//
//	Copyright © 2008 Nemetschek North America 
//	All Rights Reserved.
//
// Created by Vladislav Stanev

#include "StdAfx.h"
//#include "VWBodyFace.h"

using namespace VWFC::Math;

VWBodyFace::VWBodyFace()
{
	fp		= NULL;
	::GS_VWQueryInterface( IID_ParasolidKernel, & fp );

	fBodyFaceID	= 0;
}

VWBodyFace::VWBodyFace(int faceID)
{
	fBodyFaceID = 0;
	fp			= NULL;
	::GS_VWQueryInterface( IID_ParasolidKernel, & fp );

	PK_LOGICAL_t isEntity = PK_LOGICAL_false;
	VERIFYN(kBiplab, !PK_ENTITY_is(faceID, &isEntity));

	if (isEntity == PK_LOGICAL_true) 
		fBodyFaceID	= faceID;
}

VWBodyFace::VWBodyFace(const VWBodyFace& src)
{
	fBodyFaceID = 0;
	fp			= NULL;
	::GS_VWQueryInterface( IID_ParasolidKernel, & fp );

	PK_LOGICAL_t isEntity = PK_LOGICAL_false;
	VERIFYN(kBiplab, !PK_ENTITY_is(src.fBodyFaceID, &isEntity));

	if (isEntity == PK_LOGICAL_true) 
		fBodyFaceID	= src.fBodyFaceID;
}

VWBodyFace::~VWBodyFace()
{
	if ( fp ) {
		fp->Release();
		fp	= NULL;
	}
}

VWBodyFace& VWBodyFace::operator=(const VWBodyFace& src)
{
	fBodyFaceID	= src.fBodyFaceID;
	return *this;
}

bool VWBodyFace::GetPlanarSurface(VWPoint3D& outPlaneLocation, VWPoint3D& outPlaneNormal)
{
	if (fp) {
		if (fBodyFaceID != PK_ENTITY_null) {
			PK_SURF_t surface = PK_ENTITY_null;
			PK_LOGICAL_t faceSense = PK_LOGICAL_false;
			VERIFYN(kBiplab, !PK_FACE_ask_oriented_surf(fBodyFaceID, &surface, &faceSense));

			if (surface == PK_ENTITY_null)
				return false; // rubber face

			// check if the surface is a planar surface
			PK_ENTITY_t actualClass = PK_ENTITY_null;
			VERIFYN(kBiplab, !PK_ENTITY_ask_class(surface, &actualClass));
			if (actualClass != PK_CLASS_plane) {
				PK_LOGICAL_t verdict = PK_LOGICAL_false;
				VERIFYN(kBiplab, !PK_CLASS_is_subclass(actualClass, PK_CLASS_plane, &verdict));
				if (verdict == PK_LOGICAL_false)
					return false;  // not planar
			}

			// get data from plane
			PK_PLANE_sf_t planeSF;
			VERIFYN(kBiplab, !PK_PLANE_ask(surface, &planeSF));

			PK_VECTOR_t location = planeSF.basis_set.location;
			outPlaneLocation = VWPoint3D(location.coord[0]*10000, location.coord[1]*10000, location.coord[2]*10000);

			PK_VECTOR_t normal = planeSF.basis_set.axis;
			if (faceSense == PK_LOGICAL_false) {
				normal.coord[0] *= -1;
				normal.coord[1] *= -1;
				normal.coord[2] *= -1;
			}
			
			outPlaneNormal = VWPoint3D(normal.coord[0], normal.coord[1], normal.coord[2]);
		}
	}

	return false;
}

bool VWBodyFace::GetPlanarSurface(VWPlane& out)
{
	if (fp) {
		if (fBodyFaceID != PK_ENTITY_null) {
			PK_SURF_t surface = PK_ENTITY_null;
			PK_LOGICAL_t faceSense = PK_LOGICAL_false;
			VERIFYN(kBiplab, !PK_FACE_ask_oriented_surf(fBodyFaceID, &surface, &faceSense));

			if (surface == PK_ENTITY_null)
				return false; // rubber face

			// check if the surface is a planar surface
			PK_ENTITY_t actualClass = PK_ENTITY_null;
			VERIFYN(kBiplab, !PK_ENTITY_ask_class(surface, &actualClass));
			if (actualClass != PK_CLASS_plane) {
				PK_LOGICAL_t verdict = PK_LOGICAL_false;
				VERIFYN(kBiplab, !PK_CLASS_is_subclass(actualClass, PK_CLASS_plane, &verdict));
				if (verdict == PK_LOGICAL_false)
					return false;  // not planar
			}

			// get data from plane
			PK_PLANE_sf_t planeSF;
			VERIFYN(kBiplab, !PK_PLANE_ask(surface, &planeSF));

			PK_VECTOR_t location = planeSF.basis_set.location;
			WorldPt3 planeLocation = VWPoint3D(location.coord[0]*10000, location.coord[1]*10000, location.coord[2]*10000);

			PK_VECTOR_t normal = planeSF.basis_set.axis;
			if (faceSense == PK_LOGICAL_false) {
				normal.coord[0] *= -1;
				normal.coord[1] *= -1;
				normal.coord[2] *= -1;
			}
			
			WorldPt3 planeNormal = VWPoint3D(normal.coord[0], normal.coord[1], normal.coord[2]);

			out.SetPlane(planeLocation, planeNormal);
		}
	}

	return false;
}
