// Copyright 2011 Fotios Sioutis (sfotis@gmail.com)
//
//This file is part of pythonOCC.
//
//pythonOCC is free software: you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//pythonOCC is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with pythonOCC. If not, see .
//---------------------------------------------------------------------------
#include "Tesselator.h"
#include
#include
#include
#include
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//---------------------------------------------------------------------------
Tesselator::Tesselator(TopoDS_Shape aShape,
theTextureMappingRule aTxtMapType,
Standard_Real anAutoScaleSizeOnU,
Standard_Real anAutoScaleSizeOnV,
Standard_Real aDeviation,
Standard_Real aUOrigin,
Standard_Real aVOrigin,
Standard_Real aURepeat,
Standard_Real aVRepeat,
Standard_Real aScaleU,
Standard_Real aScaleV,
Standard_Real aRotationAngle) :
//set local variables
myShape(aShape),
myTxtMapType(aTxtMapType),
myAutoScaleSizeOnU(anAutoScaleSizeOnU),
myAutoScaleSizeOnV(anAutoScaleSizeOnV),
myDeviation(aDeviation),
myUOrigin(aUOrigin),
myVOrigin(aVOrigin),
myURepeat(aURepeat),
myVRepeat(aVRepeat),
myScaleU(aScaleU),
myScaleV(aScaleV),
myRotationAngle(aRotationAngle)
{
//prepare bbox tex coords
if (myTxtMapType == atCube) {
//create a compound for bbox
//prepare bbox tex coords
PrepareBoxTextureCoordinates(myShape);
}
locVertexcoord = NULL;
locNormalcoord = NULL;
locTexcoord = NULL;
ComputeDefaultDeviation();
}
Tesselator::Tesselator(TopoDS_Shape aShape) :
//set local variables
myDeviation(1.0),
myUOrigin(0.),
myVOrigin(0.),
myURepeat(1.),
myVRepeat(1.),
myScaleU(1.),
myScaleV(1.),
myAutoScaleSizeOnU(1.),
myAutoScaleSizeOnV(1.),
myTxtMapType(atNormal),
myShape(aShape),
myRotationAngle(0.)
{
locVertexcoord = NULL;
locNormalcoord = NULL;
locTexcoord = NULL;
ComputeDefaultDeviation();
}
void Tesselator::Compute(bool uv_coords, bool compute_edges, float mesh_quality, bool parallel)
{
if (uv_coords) {
TesselateWithUVCoords(compute_edges, mesh_quality, parallel);
}
else {
Tesselate(compute_edges, mesh_quality, parallel);
}
}
//---------------------------------------------------------------------------
Tesselator::~Tesselator()
{
if (locVertexcoord)
delete [] locVertexcoord;
if (locNormalcoord)
delete [] locNormalcoord;
if (locTexcoord)
delete [] locTexcoord;
for (std::vector::iterator edgeit = edgelist.begin(); edgeit != edgelist.end(); ++edgeit) {
aedge* edge = *edgeit;
if (edge) {
if (edge->vertex_coord)
delete[] edge->vertex_coord;
delete edge;
*edgeit = NULL;
}
}
edgelist.clear();
}
//---------------------------------------------------------------------------
void Tesselator::SetDeviation(Standard_Real aDeviation)
{
myDeviation = aDeviation;
}
//---------------------------------------------------------------------------
void Tesselator::Tesselate(bool compute_edges, float mesh_quality, bool parallel)
{
TopExp_Explorer ExpFace;
StdPrs_ToolShadedShape SST;
gp_Dir d;
gp_Pnt p;
gp_Vec2d theCoord_p;
gp_Pnt2d d_coord;
//Triangulate
BRepMesh_IncrementalMesh(myShape, myDeviation*mesh_quality, false, 0.5*mesh_quality, parallel);
for (ExpFace.Init(myShape, TopAbs_FACE); ExpFace.More(); ExpFace.Next()) {
const TopoDS_Face& myFace = TopoDS::Face(ExpFace.Current());
TopLoc_Location aLocation;
Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, aLocation);
if (!myT.IsNull()) {
Poly_Connect pc(myT);
aface *this_face = new aface;
//write vertex buffer
const TColgp_Array1OfPnt& Nodes = myT->Nodes();
this_face->vertex_coord = new float[Nodes.Length() * 3];
this_face->number_of_coords = Nodes.Length();
for (int i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
p = Nodes(i).Transformed(aLocation.Transformation());
this_face->vertex_coord[((i-1) * 3)+ 0] = static_cast(p.X());
this_face->vertex_coord[((i-1) * 3)+ 1] = static_cast(p.Y());
this_face->vertex_coord[((i-1) * 3)+ 2] = static_cast(p.Z());
}
//write normal buffer
TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper());
SST.Normal(myFace, pc, myNormal);
this_face->normal_coord = new float[myNormal.Length() * 3];
this_face->number_of_normals = myNormal.Length();
for (int i = myNormal.Lower(); i <= myNormal.Upper(); i++) {
d = myNormal(i).Transformed(aLocation.Transformation());
this_face->normal_coord[((i-1) * 3)+ 0] = static_cast(d.X());
this_face->normal_coord[((i-1) * 3)+ 1] = static_cast(d.Y());
this_face->normal_coord[((i-1) * 3)+ 2] = static_cast(d.Z());
}
// set uvcoords buffers to NULL
// necessary for JoinPrimitive to be performed
this_face->tex_coord = NULL;
this_face->number_of_texcoords = 0;
//write triangle buffer
Standard_Integer validFaceTriCount = 0;
Standard_Integer n1 , n2 , n3;
TopAbs_Orientation orient = myFace.Orientation();
const Poly_Array1OfTriangle& triangles = myT->Triangles();
this_face->tri_indexes = new int [triangles.Length()* 3];
for (int nt = 1; nt <= myT->NbTriangles(); nt++) {
triangles(nt).Get(n1,n2,n3);
if (orient != TopAbs_FORWARD) {
Standard_Integer tmp=n1;
n1 = n2;
n2 = tmp;
}
if (TriangleIsValid(Nodes(n1),Nodes(n2),Nodes(n3))) {
this_face->tri_indexes[(validFaceTriCount * 3)+ 0] = n1;
this_face->tri_indexes[(validFaceTriCount * 3)+ 1] = n2;
this_face->tri_indexes[(validFaceTriCount * 3)+ 2] = n3;
validFaceTriCount++;
}
}
this_face->number_of_triangles = validFaceTriCount;
facelist.push_back(this_face);
}
}
JoinPrimitives();
if (compute_edges) {
ComputeEdges();
}
}
//---------------------------------------------------------------------------
void Tesselator::TesselateWithUVCoords(bool compute_edges, float mesh_quality, bool parallel)
{
Standard_Real Umin;
Standard_Real Umax;
Standard_Real Vmin;
Standard_Real Vmax;
Standard_Real dUmax;
Standard_Real dVmax;
TopExp_Explorer ExpFace;
StdPrs_ToolShadedShape SST;
gp_Dir d;
gp_Pnt p;
gp_Vec2d theCoord_p;
gp_Pnt2d d_coord;
//Triangulate
BRepMesh_IncrementalMesh(myShape, myDeviation*mesh_quality, false, 0.5*mesh_quality, parallel);
for (ExpFace.Init(myShape, TopAbs_FACE); ExpFace.More(); ExpFace.Next()) {
const TopoDS_Face& myFace = TopoDS::Face(ExpFace.Current());
TopLoc_Location aLocation;
Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, aLocation);
if (!myT.IsNull()) {
Poly_Connect pc(myT);
aface *this_face = new aface;
//write vertex buffer
const TColgp_Array1OfPnt& Nodes = myT->Nodes();
this_face->vertex_coord = new float[Nodes.Length() * 3];
this_face->number_of_coords = Nodes.Length();
for (int i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
p = Nodes(i).Transformed(aLocation.Transformation());
this_face->vertex_coord[((i-1) * 3)+ 0] = static_cast(p.X());
this_face->vertex_coord[((i-1) * 3)+ 1] = static_cast(p.Y());
this_face->vertex_coord[((i-1) * 3)+ 2] = static_cast(p.Z());
}
//write normal buffer
TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper());
SST.Normal(myFace, pc, myNormal);
this_face->normal_coord = new float[myNormal.Length() * 3];
this_face->number_of_normals = myNormal.Length();
for (int i = myNormal.Lower(); i <= myNormal.Upper(); i++) {
d = myNormal(i).Transformed(aLocation.Transformation());
this_face->normal_coord[((i-1) * 3)+ 0] = static_cast(d.X());
this_face->normal_coord[((i-1) * 3)+ 1] = static_cast(d.Y());
this_face->normal_coord[((i-1) * 3)+ 2] = static_cast(d.Z());
}
//write uvcoord buffer
int id1 = 0, id2 = 2, idNull = 1;
if (myTxtMapType == atNormal || myTxtMapType == atNormalAutoScale) {
BRepTools::UVBounds(myFace,Umin, Umax, Vmin, Vmax);
dUmax = (Umax - Umin);
dVmax = (Vmax - Vmin);
if (myTxtMapType == atNormalAutoScale) {
myScaleU = myAutoScaleSizeOnU/dUmax;
myScaleV = myAutoScaleSizeOnV/dVmax;
}
}
const TColgp_Array1OfPnt2d& UVNodes = myT->UVNodes();
this_face->tex_coord = new float[UVNodes.Length() * 3];
this_face->number_of_texcoords = UVNodes.Length();
for (int i = UVNodes.Lower(); i <= UVNodes.Upper();i++) {
if (myTxtMapType == atCube) {
GetBoxTextureCoordinate( Nodes(i).Transformed(aLocation.Transformation()),
myNormal(i).Transformed(aLocation.Transformation()),
theCoord_p);
d_coord.SetX((-myUOrigin+(myURepeat*theCoord_p.X())/aBndBoxSz)/myScaleU);
d_coord.SetY((-myVOrigin+(myVRepeat*theCoord_p.Y())/aBndBoxSz)/myScaleV);
}
else {
d_coord = UVNodes(i);
d_coord.SetX((-myUOrigin+(myURepeat*(d_coord.X()-Umin))/dUmax)/myScaleU);
d_coord.SetY((-myVOrigin+(myVRepeat*(d_coord.Y()-Vmin))/dVmax)/myScaleV);
}
d_coord.Rotate(gp::Origin2d(), myRotationAngle);
this_face->tex_coord[((i-1) * 3)+ id1] = static_cast(d_coord.X());
this_face->tex_coord[((i-1) * 3)+ id2] = static_cast(d_coord.Y());
this_face->tex_coord[((i-1) * 3)+ idNull] = 0.;
}
//write triangle buffer
Standard_Integer validFaceTriCount = 0;
Standard_Integer n1 , n2 , n3;
TopAbs_Orientation orient = myFace.Orientation();
const Poly_Array1OfTriangle& triangles = myT->Triangles();
this_face->tri_indexes = new int [triangles.Length()* 3];
for (int nt = 1; nt <= myT->NbTriangles(); nt++) {
triangles(nt).Get(n1,n2,n3);
if (orient != TopAbs_FORWARD) {
Standard_Integer tmp=n1;
n1 = n2;
n2 = tmp;
}
if (TriangleIsValid(Nodes(n1),Nodes(n2),Nodes(n3))) {
this_face->tri_indexes[(validFaceTriCount * 3)+ 0] = n1;
this_face->tri_indexes[(validFaceTriCount * 3)+ 1] = n2;
this_face->tri_indexes[(validFaceTriCount * 3)+ 2] = n3;
validFaceTriCount++;
}
}
this_face->number_of_triangles = validFaceTriCount;
facelist.push_back(this_face);
}
}
JoinPrimitivesWithUVCoords();
if (compute_edges) {
ComputeEdges();
}
}
//---------------------------INTERFACE---------------------------------------
void Tesselator::ComputeDefaultDeviation()
{
// This method automatically computes precision from the bounding box of the shape
Bnd_Box aBox;
Standard_Real aXmin,aYmin ,aZmin ,aXmax ,aYmax ,aZmax;
//calculate the bounding box
BRepBndLib::Add(myShape, aBox);
aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
Standard_Real xDim = std::abs((long)aXmax - (long)aXmin);
Standard_Real yDim = std::abs((long)aYmax - (long)aYmin);
Standard_Real zDim = std::abs((long)aZmax - (long)aZmin);
Standard_Real adeviation = std::max(xDim, std::max(yDim, zDim)) * 2e-2 ;
myDeviation = adeviation;
}
void Tesselator::ComputeEdges()
{
TopLoc_Location aTrsf;
// clear current data
std::vector::iterator it;
for (it = edgelist.begin(); it != edgelist.end(); ++it) {
if (*it) {
if ((*it)->vertex_coord)
delete[] (*it)->vertex_coord;
delete *it;
*it = NULL;
}
}
edgelist.clear();
// explore all boundary edges
TopTools_IndexedDataMapOfShapeListOfShape edgeMap;
TopExp::MapShapesAndAncestors (myShape, TopAbs_EDGE, TopAbs_FACE, edgeMap);
for (int iEdge = 1 ; iEdge <= edgeMap.Extent (); iEdge++) {
// reject free edges
const TopTools_ListOfShape& faceList = edgeMap.FindFromIndex (iEdge);
if (faceList.Extent() == 0) {
continue;
}
// take one of the shared edges and get edge triangulation
const TopoDS_Face& aFace = TopoDS::Face (faceList.First ());
const TopoDS_Edge& anEdge = TopoDS::Edge (edgeMap.FindKey (iEdge));
Handle(Poly_Triangulation) trian = BRep_Tool::Triangulation (aFace, aTrsf);
if (trian.IsNull ())
continue;
Handle(Poly_PolygonOnTriangulation) anEdgePoly =
BRep_Tool::PolygonOnTriangulation (anEdge, trian, aTrsf);
if (anEdgePoly.IsNull ()) {
continue;
}
// get edge vertex indexes from face triangulation
const TColgp_Array1OfPnt& trainVerts = trian->Nodes ();
const TColStd_Array1OfInteger& edgeVerts = anEdgePoly->Nodes ();
if (edgeVerts.Length () < 2) {
continue;
}
aedge* theEdge = new aedge;
theEdge->number_of_coords = edgeVerts.Upper () - edgeVerts.Lower() + 1;
theEdge->vertex_coord = new float[theEdge->number_of_coords * 3 * sizeof(float)];
for (int aNodeIdx = edgeVerts.Lower (); aNodeIdx <= edgeVerts.Upper (); aNodeIdx++) {
// node index in face triangulation
int aTriIndex = edgeVerts.Value (aNodeIdx);
// get node and apply location transformation to the node
gp_Pnt aTriNode = trainVerts.Value (aTriIndex);
if (!aTrsf.IsIdentity ()) {
aTriNode.Transform (aTrsf);
}
int locIndex = aNodeIdx - edgeVerts.Lower ();
theEdge->vertex_coord[locIndex*3 + 0] = static_cast(aTriNode.X());
theEdge->vertex_coord[locIndex*3 + 1] = static_cast(aTriNode.Y());
theEdge->vertex_coord[locIndex*3 + 2] = static_cast(aTriNode.Z());
}
edgelist.push_back(theEdge);
}
}
std::string formatFloatNumber(float f)
{
// returns string representation of the float number f.
// set epsilon to 1e-3
float epsilon = 1e-3f;
std::stringstream formatted_float;
if (std::abs(f) < epsilon) {
f = 0.;
}
formatted_float << f;
return formatted_float.str();
}
std::vector Tesselator::GetVerticesPositionAsTuple()
{
// create the vector and allocate memory
std::vector vertices_position;
vertices_position.reserve(tot_triangle_count);
// loop over tertices
int pID = 0;
int qID = 0;
int rID = 0;
for (int i=0;i Tesselator::GetNormalsAsTuple()
{
// create the vector and allocate memory
std::vector normals;
normals.reserve(tot_triangle_count);
// loop over normals
int pID = 0;
int qID = 0;
int rID = 0;
for (int i=0;i\n";
// write points coordinates
str_ifs << "\n";
// write normals
str_ifs << "\n";
// close all markups
str_ifs << "\n";
delete [] vertices_idx;
delete [] texcoords_idx;
delete [] normals_idx;
return str_ifs.str();
}
void Tesselator::ExportShapeToX3D(char * filename, int diffR, int diffG, int diffB)
{
ofstream X3Dfile;
X3Dfile.open (filename);
// write header
X3Dfile << "" ;
X3Dfile << "";
X3Dfile << "";
X3Dfile << "";
X3Dfile << "";
X3Dfile << "";
X3Dfile << "";
// write tesselation
X3Dfile << ExportShapeToX3DIndexedFaceSet();
X3Dfile << "\n";
X3Dfile.close();
}
std::string Tesselator::ExportShapeToThreejsJSONString(char *shape_function_name, bool export_uv)
{
// a method that export a shape to a JSON BufferGeometry object
std::stringstream str_3js, str_vertices, str_normals, str_uvs;
int *vertices_idx = new int[3];
int *texcoords_idx = new int[3];
int *normals_idx = new int[3];
// loop over triangles and write vertices, normals and uvs if enabled
for (int i=0;inumber_of_coords;
}
//---------------------------------------------------------------------------
void Tesselator::GetVertex(int ivert, float& x, float& y, float& z)
{
x = locVertexcoord[ivert*3 + 0];
y = locVertexcoord[ivert*3 + 1];
z = locVertexcoord[ivert*3 + 2];
}
//---------------------------------------------------------------------------
void Tesselator::GetNormal(int ivert, float& x, float& y, float& z)
{
x = locNormalcoord[ivert*3 + 0];
y = locNormalcoord[ivert*3 + 1];
z = locNormalcoord[ivert*3 + 2];
}
//---------------------------------------------------------------------------
void Tesselator::GetTriangleIndex(int triangleIdx, int &v1, int &v2, int &v3)
{
v1 = loc_tri_indexes[3*triangleIdx + 0];
v2 = loc_tri_indexes[3*triangleIdx + 1];
v3 = loc_tri_indexes[3*triangleIdx + 2];
}
//---------------------------------------------------------------------------
void Tesselator::GetEdgeVertex(int iEdge, int ivert, float &x, float &y, float &z)
{
aedge* e = edgelist.at(iEdge);
if (!e) {
return;
}
x = e->vertex_coord[3*ivert + 0];
y = e->vertex_coord[3*ivert + 1];
z = e->vertex_coord[3*ivert + 2];
}
//---------------------------------------------------------------------------
void Tesselator::ObjGetTriangle(int trianglenum, int *vertices, int *texcoords, int *normals)
{
int pID = loc_tri_indexes[(trianglenum * 3) + 0] * 3;
int qID = loc_tri_indexes[(trianglenum * 3) + 1] * 3;
int rID = loc_tri_indexes[(trianglenum * 3) + 2] * 3;
vertices[0] = pID;
vertices[1] = qID;
vertices[2] = rID;
normals[0] = pID;
normals[1] = qID;
normals[2] = rID;
texcoords[0] = pID;
texcoords[1] = qID;
texcoords[2] = rID;
}
//---------------------------------------------------------------------------
//---------------------------------HELPERS-----------------------------------
//---------------------------------------------------------------------------
void Tesselator::JoinPrimitives()
{
int obP = 0;
int obN = 0;
int obT = 0;
int obTR = 0;
int advance = 0;
int total_poly_count = 0;
int total_vertex_count = 0;
int total_normal_count = 0;
std::vector::iterator anIterator = facelist.begin();
while (anIterator != facelist.end()) {
aface* myface = *anIterator;
total_poly_count = total_poly_count + myface->number_of_triangles;
total_vertex_count = total_vertex_count + myface->number_of_coords;
total_normal_count = total_normal_count + myface->number_of_normals;
anIterator++;
}
loc_tri_indexes= new int[total_poly_count * 3 ];
locVertexcoord = new float[total_vertex_count * 3 ];
locNormalcoord = new float[total_normal_count * 3 ];
tot_triangle_count = total_poly_count;
tot_vertex_count = total_vertex_count;
tot_normal_count = total_normal_count;
anIterator = facelist.begin();
while (anIterator != facelist.end()) {
aface* myface = *anIterator;
for (int x = 0; x < myface->number_of_coords; x++) {
locVertexcoord[(obP * 3) + 0] = myface->vertex_coord[(x * 3) + 0];
locVertexcoord[(obP * 3) + 1] = myface->vertex_coord[(x * 3) + 1];
locVertexcoord[(obP * 3) + 2] = myface->vertex_coord[(x * 3) + 2];
obP++;
}
for (int x = 0; x < myface->number_of_normals; x++) {
locNormalcoord[(obN * 3) + 0] = myface->normal_coord[(x * 3) + 0];
locNormalcoord[(obN * 3) + 1] = myface->normal_coord[(x * 3) + 1];
locNormalcoord[(obN * 3) + 2] = myface->normal_coord[(x * 3) + 2];
obN++;
}
for (int x = 0; x < myface->number_of_triangles; x++) {
loc_tri_indexes[(obTR * 3) + 0] = myface->tri_indexes[(x * 3) + 0] + advance - 1;
loc_tri_indexes[(obTR * 3) + 1] = myface->tri_indexes[(x * 3) + 1] + advance - 1;
loc_tri_indexes[(obTR * 3) + 2] = myface->tri_indexes[(x * 3) + 2] + advance - 1;
obTR++;
}
advance = obP;
delete [] myface->vertex_coord;
myface->vertex_coord = NULL;
delete [] myface->normal_coord;
myface->normal_coord = NULL;
delete [] myface->tri_indexes;
myface->tri_indexes = NULL;
delete myface;
myface = NULL;
anIterator++;
}
}
void Tesselator::JoinPrimitivesWithUVCoords()
{
int obP = 0;
int obN = 0;
int obT = 0;
int obTR = 0;
int advance = 0;
int total_poly_count = 0;
int total_vertex_count = 0;
int total_normal_count = 0;
int total_texcoord_count = 0;
std::vector::iterator anIterator = facelist.begin();
while (anIterator != facelist.end()) {
aface* myface = *anIterator;
total_poly_count = total_poly_count + myface->number_of_triangles;
total_vertex_count = total_vertex_count + myface->number_of_coords;
total_normal_count = total_normal_count + myface->number_of_normals;
total_texcoord_count = total_texcoord_count + myface->number_of_texcoords;
anIterator++;
}
loc_tri_indexes= new int[total_poly_count * 3 ];
locVertexcoord = new float[total_vertex_count * 3 ];
locNormalcoord = new float[total_normal_count * 3 ];
locTexcoord = new float[total_texcoord_count * 3 ];
tot_triangle_count = total_poly_count;
tot_vertex_count = total_vertex_count;
tot_normal_count = total_normal_count;
tot_texcoord_count = total_texcoord_count;
anIterator = facelist.begin();
while (anIterator != facelist.end()) {
aface* myface = *anIterator;
for (int x = 0; x < myface->number_of_coords; x++) {
locVertexcoord[(obP * 3) + 0] = myface->vertex_coord[(x * 3) + 0];
locVertexcoord[(obP * 3) + 1] = myface->vertex_coord[(x * 3) + 1];
locVertexcoord[(obP * 3) + 2] = myface->vertex_coord[(x * 3) + 2];
obP++;
}
for (int x = 0; x < myface->number_of_normals; x++) {
locNormalcoord[(obN * 3) + 0] = myface->normal_coord[(x * 3) + 0];
locNormalcoord[(obN * 3) + 1] = myface->normal_coord[(x * 3) + 1];
locNormalcoord[(obN * 3) + 2] = myface->normal_coord[(x * 3) + 2];
obN++;
}
for (int x = 0; x < myface->number_of_texcoords; x++) {
locTexcoord[(obT * 3) + 0] = myface->tex_coord[(x * 3) + 0];
locTexcoord[(obT * 3) + 1] = myface->tex_coord[(x * 3) + 1];
locTexcoord[(obT * 3) + 2] = myface->tex_coord[(x * 3) + 2];
obT++;
}
for (int x = 0; x < myface->number_of_triangles; x++) {
loc_tri_indexes[(obTR * 3) + 0] = myface->tri_indexes[(x * 3) + 0] + advance - 1;
loc_tri_indexes[(obTR * 3) + 1] = myface->tri_indexes[(x * 3) + 1] + advance - 1;
loc_tri_indexes[(obTR * 3) + 2] = myface->tri_indexes[(x * 3) + 2] + advance - 1;
obTR++;
}
advance = obP;
delete [] myface->vertex_coord;
myface->vertex_coord = NULL;
delete [] myface->normal_coord;
myface->normal_coord = NULL;
delete [] myface->tex_coord;
myface->tex_coord = NULL;
delete [] myface->tri_indexes;
myface->tri_indexes = NULL;
delete myface;
myface = NULL;
anIterator++;
}
}
//---------------------------------------------------------------------------
Standard_Boolean Tesselator::TriangleIsValid(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) const
{
gp_Vec V1(P1,P2);
gp_Vec V2(P2,P3);
gp_Vec V3(P3,P1);
if ((V1.SquareMagnitude() > 1.e-10) && (V2.SquareMagnitude() > 1.e-10) && (V3.SquareMagnitude() > 1.e-10)) {
V1.Cross(V2);
if (V1.SquareMagnitude() > 1.e-10)
return Standard_True;
else
return Standard_False;
}
else
return Standard_False;
}
//---------------------------------------------------------------------------
void Tesselator::PrepareBoxTextureCoordinates(const TopoDS_Shape& aShape)
{
//declare local variables
Bnd_Box aBox;
Standard_Real aXmin,aYmin ,aZmin ,aXmax ,aYmax ,aZmax;
//calculate the bounding box
BRepBndLib::Add(aShape, aBox);
aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
//enlarge the bb so all edges have the size of the biggest one
Standard_Real xDim = std::abs((long)aXmax - (long)aXmin);
Standard_Real yDim = std::abs((long)aYmax - (long)aYmin);
Standard_Real zDim = std::abs((long)aZmax - (long)aZmin);
if ((xDim > yDim) && (xDim > zDim)) {
aYmin -= (xDim - yDim) / 2;
aYmax += (xDim - yDim) / 2;
aZmin -= (xDim - zDim) / 2;
aZmax += (xDim - zDim) / 2;
}
else if ((yDim > xDim) && (yDim > zDim)) {
aXmin -= (yDim - xDim) / 2;
aXmax += (yDim - xDim) / 2;
aZmin -= (yDim - zDim) / 2;
aZmax += (yDim - zDim) / 2;
}
else {
aXmin -= (zDim - xDim) / 2;
aXmax += (zDim - xDim) / 2;
aYmin -= (zDim - yDim) / 2;
aYmax += (zDim - yDim) / 2;
}
aBndBoxSz = aXmax-aXmin;
}
//---------------------------------------------------------------------------
void Tesselator::GetBoxTextureCoordinate(const gp_Pnt& p, const gp_Dir& N1, gp_Vec2d& theCoord_p)
{
Standard_Real x = std::abs(N1.X());
Standard_Real y = std::abs(N1.Y());
Standard_Real z = std::abs(N1.Z());
if (x >= y && x >= z) {
if (N1.X() > 0) { //right
theCoord_p.SetX(p.Y() - aYmin);
theCoord_p.SetY(p.Z() - aZmin);
theCoord_p.Rotate(M_PI/2.);
}
else { //left
theCoord_p.SetX(p.Z() - aZmin);
theCoord_p.SetY(p.Y() - aYmin);
}
}
else if ((y >= z) && (y >= x)) {
if (N1.Y() > 0) { //top
theCoord_p.SetX(p.X() - aXmin);
theCoord_p.SetY(-(p.Z() - aZmin));
}
else { //bottom
theCoord_p.SetY(p.Z() - aZmin);
theCoord_p.SetX(p.X() - aXmin);
theCoord_p.Rotate( M_PI);
}
}
else {
if (N1.Z() > 0) { //front
theCoord_p.SetX(p.X() - aXmin);
theCoord_p.SetY(p.Y() - aYmin);
}
else { //back
theCoord_p.SetX(p.Y() - aYmin);
theCoord_p.SetY(p.X() - aXmin);
theCoord_p.Rotate(M_PI/2.);
}
}
}