Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
// FaceTools.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.
#include "stdafx.h"
#include "FaceTools.h"
#include "strconv.h"
static Standard_Boolean TriangleIsValid(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3)
{
gp_Vec V1(P1,P2); // V1=(P1,P2)
gp_Vec V2(P2,P3); // V2=(P2,P3)
gp_Vec V3(P3,P1); // V3=(P3,P1)
if ((V1.SquareMagnitude() > 1.e-10) && (V2.SquareMagnitude() > 1.e-10) && (V3.SquareMagnitude() > 1.e-10))
{
V1.Cross(V2); // V1 = Normal
if (V1.SquareMagnitude() > 1.e-10)
return Standard_True;
else
return Standard_False;
}
else
return Standard_False;
}
void MeshFace(TopoDS_Face face, double pixels_per_mm)
{
BRepTools::Clean(face);
BRepMesh_IncrementalMesh(face, 1 / pixels_per_mm);
}
void command_callback(const double* x, const double* n)
{
glNormal3d(n[0],n[1],n[2]);
glVertex3d(x[0],x[1],x[2]);
glNormal3d(n[3],n[4],n[5]);
glVertex3d(x[3],x[4],x[5]);
glNormal3d(n[6],n[7],n[8]);
glVertex3d(x[6],x[7],x[8]);
}
void DrawFaceWithCommands(TopoDS_Face face)
{
glBegin(GL_TRIANGLES);
DrawFace(face,command_callback,false);
glEnd();
}
gp_Dir GetFaceNormalAtUV(const TopoDS_Face &face, double u, double v, gp_Pnt *pos){
if(face.IsNull()) return gp_Dir(0, 0, 1);
try
{
Handle(Geom_Surface) surf=BRep_Tool::Surface(face); // get surface properties
GeomLProp_SLProps props(surf, u, v, 1, 0.01); // get surface normal
if(!props.IsNormalDefined())return gp_Dir(0, 0, 1);
gp_Dir norm=props.Normal(); // check orientation
if(pos)*pos = props.Value();
if(face.Orientation()==TopAbs_REVERSED) norm.Reverse();
return norm;
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
theApp->DoMessageBox((std::wstring(L"Error in GetFaceNormalAtUV") + L": " + Ctt(e->GetMessageString())).c_str());
return gp_Dir(0, 0, 1);
}
catch (const char* str)
{
theApp->DoMessageBox((std::wstring(L"Error in GetFaceNormalAtUV") + L": " + Ctt(str)).c_str());
return gp_Dir(0, 0, 1);
}
catch (...)
{
theApp->DoMessageBox(L"Error in GetFaceNormalAtUV");
return gp_Dir(0, 0, 1);
}
}
void DrawFace(TopoDS_Face face,void(*callbackfunc)(const double* x, const double* n), bool just_one_average_normal)
{
double x[9], n[9];
// Get triangulation
TopLoc_Location L;
Handle_Poly_Triangulation facing = BRep_Tool::Triangulation(face,L);
gp_Trsf tr = L;
if(facing.IsNull()){
#if 0
BRepAdaptor_Surface surface(face, Standard_True);
double u0 = surface.FirstUParameter();
double u1 = surface.LastUParameter();
double v0 = surface.FirstVParameter();
double v1 = surface.LastVParameter();
const int numi = 10;
const int numj = 10;
for(int i = 0; i<numi; i++)
{
for(int j = 0; j<numj; j++)
{
double uA = -1.2 + 2.5 *(double)i / numi;
double uB = -1.2 + 2.5 *(double)(i+1) / numi;
double vA = 10* (double)j / numj;
double vB = 10*(double)(j+1) / numj;
gp_Pnt p0, p1, p2, p3;
gp_Dir n0 = GetFaceNormalAtUV(face, uA, vA, &p0);
gp_Dir n1 = GetFaceNormalAtUV(face, uB, vA, &p1);
gp_Dir n2 = GetFaceNormalAtUV(face, uB, vB, &p2);
gp_Dir n3 = GetFaceNormalAtUV(face, uA, vB, &p3);
x[0] = p0.X();
x[1] = p0.Y();
x[2] = p0.Z();
x[3] = p1.X();
x[4] = p1.Y();
x[5] = p1.Z();
x[6] = p2.X();
x[7] = p2.Y();
x[8] = p2.Z();
n[0] = n0.X();
n[1] = n0.Y();
n[2] = n0.Z();
n[3] = n1.X();
n[4] = n1.Y();
n[5] = n1.Z();
n[6] = n2.X();
n[7] = n2.Y();
n[8] = n2.Z();
(*callbackfunc)(x, n);
x[0] = p0.X();
x[1] = p0.Y();
x[2] = p0.Z();
x[3] = p2.X();
x[4] = p2.Y();
x[5] = p2.Z();
x[6] = p3.X();
x[7] = p3.Y();
x[8] = p3.Z();
n[0] = n0.X();
n[1] = n0.Y();
n[2] = n0.Z();
n[3] = n2.X();
n[4] = n2.Y();
n[5] = n2.Z();
n[6] = n3.X();
n[7] = n3.Y();
n[8] = n3.Z();
(*callbackfunc)(x, n);
}
}
#endif
}
else
{
Poly_Connect pc(facing);
const TColgp_Array1OfPnt& Nodes = facing->Nodes();
const Poly_Array1OfTriangle& triangles = facing->Triangles();
TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper());
StdPrs_ToolShadedShape::Normal(face, pc, myNormal);
Standard_Integer nnn = facing->NbTriangles(); // nnn : nombre de triangles
Standard_Integer nt, n1, n2, n3 = 0; // nt : triangle courant
// ni : sommet i du triangle courant
for (nt = 1; nt <= nnn; nt++)
{
if (face.Orientation() == TopAbs_REVERSED) // si la face est "reversed"
triangles(nt).Get(n1,n3,n2); // le triangle est n1,n3,n2
else
triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
{
gp_Pnt v1 = Nodes(n1).Transformed(tr);
gp_Pnt v2 = Nodes(n2).Transformed(tr);
gp_Pnt v3 = Nodes(n3).Transformed(tr);
x[0] = v1.X();
x[1] = v1.Y();
x[2] = v1.Z();
x[3] = v2.X();
x[4] = v2.Y();
x[5] = v2.Z();
x[6] = v3.X();
x[7] = v3.Y();
x[8] = v3.Z();
if(just_one_average_normal)
{
gp_Vec V1(v1, v2);
gp_Vec V2(v1, v3);
extract((V1 ^ V2).Normalized(), n);
}
else
{
gp_Dir d1 = myNormal(n1).Transformed(tr);
gp_Dir d2 = myNormal(n2).Transformed(tr);
gp_Dir d3 = myNormal(n3).Transformed(tr);
n[0] = d1.X();
n[1] = d1.Y();
n[2] = d1.Z();
n[3] = d2.X();
n[4] = d2.Y();
n[5] = d2.Z();
n[6] = d3.X();
n[7] = d3.Y();
n[8] = d3.Z();
}
(*callbackfunc)(x, n);
}
}
}
}
c5721c306This file is pinned to the selected release. Download the original to open it in your design tool.