1 //=======================================================================
2 // File: StlTransfer.cxx
3 // Created: Fri Jun 23 14:36:58 2000
4 // Author: Sergey MOZOKHIN
5 // <smh@russox.nnov.matra-dtv.fr>
6 #include <StlTransfer.ixx>
7 #include <Standard_ErrorHandler.hxx>
8 #include <Standard_Failure.hxx>
9 #include <TopoDS_Face.hxx>
10 #include <Poly_Connect.hxx>
11 #include <TColgp_Array1OfDir.hxx>
12 #include <Poly_Triangulation.hxx>
13 #include <BRepAdaptor_Surface.hxx>
14 #include <TopLoc_Location.hxx>
15 #include <Geom_Surface.hxx>
16 #include <BRep_Tool.hxx>
20 #include <TColgp_Array1OfPnt2d.hxx>
24 #include <BRepMesh.hxx>
26 #include <Precision.hxx>
27 #include <TopExp_Explorer.hxx>
29 #include <TColgp_SequenceOfXYZ.hxx>
30 //function computes normals for surface
32 static void Normal(const TopoDS_Face& aFace,
34 TColgp_Array1OfDir& Nor)
36 const Handle(Poly_Triangulation)& T = pc.Triangulation();
37 BRepAdaptor_Surface S;
38 Standard_Boolean hasUV = T->HasUVNodes();
41 Handle(Geom_Surface) GS = BRep_Tool::Surface(aFace, l);
43 if (hasUV && !GS.IsNull()) {
44 Standard_Boolean OK = Standard_True;
49 CSLib_DerivativeStatus Status;
50 CSLib_NormalStatus NStat;
51 S.Initialize(aFace, Standard_False);
52 const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
53 if (!S.GetType() == GeomAbs_Plane) {
54 for (i = UVNodes.Lower(); i <= UVNodes.Upper(); i++) {
58 CSLib::Normal(D1U,D1V,Precision::Angular(),Status,Nor(i));
59 if (Status != CSLib_Done) {
60 S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
61 CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,Nor(i));
63 if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
68 U = UVNodes(UVNodes.Lower()).X();
69 V = UVNodes(UVNodes.Lower()).Y();
71 CSLib::Normal(D1U,D1V,Precision::Angular(),Status,NPlane);
72 if (Status != CSLib_Done) {
73 S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
74 CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,NPlane);
76 if (aFace.Orientation() == TopAbs_REVERSED) NPlane.Reverse();
82 const TColgp_Array1OfPnt& Nodes = T->Nodes();
83 Standard_Integer n[3];
84 const Poly_Array1OfTriangle& triangles = T->Triangles();
86 for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
87 gp_XYZ eqPlan(0, 0, 0);
88 for (pc.Initialize(i); pc.More(); pc.Next()) {
89 triangles(pc.Value()).Get(n[0], n[1], n[2]);
90 gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord());
91 gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord());
92 eqPlan += (v1^v2).Normalized();
94 Nor(i) = gp_Dir(eqPlan);
95 if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
100 void StlTransfer::BuildIncrementalMesh (const TopoDS_Shape& Shape,
101 const Standard_Real Deflection,
102 const Handle(StlMesh_Mesh)& Mesh)
104 if (Deflection <= Precision::Confusion ()) {
105 Standard_ConstructionError::Raise ("StlTransfer::BuildIncrementalMesh");
108 Standard_Integer NbVertices, NbTriangles;
109 BRepMesh::Mesh (Shape, Deflection);
110 for (TopExp_Explorer itf(Shape,TopAbs_FACE); itf.More(); itf.Next()) {
111 TopoDS_Face face = TopoDS::Face(itf.Current());
112 TopLoc_Location Loc, loc;
113 Handle(Poly_Triangulation) theTriangulation = BRep_Tool::Triangulation(face, Loc);
114 if (theTriangulation.IsNull()) continue; //Meshing was not done for this face!
115 Poly_Array1OfTriangle theTriangles(1,theTriangulation->NbTriangles());
116 theTriangles.Assign(theTriangulation->Triangles());
117 Mesh->AddDomain (Deflection);
120 TopAbs_Orientation orientation =
124 TColgp_Array1OfPnt thePoints(1, theTriangulation->NbNodes());
125 thePoints.Assign(theTriangulation->Nodes());
126 //compute normal of face
127 const TColgp_Array1OfPnt& Nodes = theTriangulation->Nodes();
128 TColgp_Array1OfDir NORMAL(Nodes.Lower(), Nodes.Upper());
129 Poly_Connect pc(theTriangulation);
130 Normal(face, pc, NORMAL);
132 for(i=1;i<=thePoints.Length();i++) {
133 Standard_Real X1, Y1, Z1;
134 gp_Pnt p = thePoints.Value(i);
135 p.Transform(Loc.Transformation());
136 p.Coord (X1, Y1, Z1);
137 NbVertices = Mesh->AddVertex (X1, Y1, Z1);
141 for (i=1;i<=theTriangles.Length();i++) {
142 Standard_Integer V1, V2, V3;
143 Poly_Triangle triangle = theTriangles.Value(i);
144 triangle.Get(V1, V2, V3);
146 P1 = Mesh->Vertices(Mesh->NbDomains()).Value(V1);
147 P2 = Mesh->Vertices(Mesh->NbDomains()).Value(V2);
148 P3 = Mesh->Vertices(Mesh->NbDomains()).Value(V3);
149 gp_Vec average = NORMAL(V1);;
151 //check angle between vectors
152 gp_Vec V1V2(P1, P2), V2V3(P2, P3);
153 Standard_Integer A,B,C;
154 gp_Vec vec = V1V2^V2V3;
155 Standard_Real modul1, modul2;
156 modul1 = average.XYZ().Modulus();
157 modul2 = vec.XYZ().Modulus();
158 if (modul2>Precision::Confusion ()) vec.Divide(modul2);
160 // vec.Transform(loc);
161 if (modul1>Precision::Confusion () && modul2>Precision::Confusion ()) {
162 Standard_Real an = vec.Angle(average);
170 NbTriangles = Mesh->AddTriangle (A, B, C, average.X(), average.Y(), average.Z());
173 catch(Standard_Failure)
176 cout << "Fail in StlTransfer::BuildIncrementalMesh" << endl;