1 // Created on: 2000-06-23
2 // Created by: Sergey MOZOKHIN
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 //=======================================================================
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Surface.hxx>
20 #include <BRepMesh_IncrementalMesh.hxx>
22 #include <Geom_Surface.hxx>
27 #include <Poly_Connect.hxx>
28 #include <Poly_Triangulation.hxx>
29 #include <Precision.hxx>
30 #include <Standard_ErrorHandler.hxx>
31 #include <Standard_Failure.hxx>
32 #include <StlMesh_Mesh.hxx>
33 #include <StlTransfer.hxx>
34 #include <TColgp_Array1OfDir.hxx>
35 #include <TColgp_Array1OfPnt2d.hxx>
36 #include <TColgp_SequenceOfXYZ.hxx>
38 #include <TopExp_Explorer.hxx>
39 #include <TopLoc_Location.hxx>
41 #include <TopoDS_Face.hxx>
42 #include <TopoDS_Shape.hxx>
44 //function computes normals for surface
45 static void Normal(const TopoDS_Face& aFace,
47 TColgp_Array1OfDir& Nor)
49 const Handle(Poly_Triangulation)& T = pc.Triangulation();
50 BRepAdaptor_Surface S;
51 Standard_Boolean hasUV = T->HasUVNodes();
54 Handle(Geom_Surface) GS = BRep_Tool::Surface(aFace, l);
56 if (hasUV && !GS.IsNull()) {
57 Standard_Boolean OK = Standard_True;
62 CSLib_DerivativeStatus Status;
63 CSLib_NormalStatus NStat;
64 S.Initialize(aFace, Standard_False);
65 const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
66 if (S.GetType() != GeomAbs_Plane) {
67 for (i = UVNodes.Lower(); i <= UVNodes.Upper(); i++) {
71 CSLib::Normal(D1U,D1V,Precision::Angular(),Status,Nor(i));
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,Nor(i));
76 if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
81 U = UVNodes(UVNodes.Lower()).X();
82 V = UVNodes(UVNodes.Lower()).Y();
84 CSLib::Normal(D1U,D1V,Precision::Angular(),Status,NPlane);
85 if (Status != CSLib_Done) {
86 S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
87 CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,NPlane);
89 if (aFace.Orientation() == TopAbs_REVERSED) NPlane.Reverse();
95 const TColgp_Array1OfPnt& Nodes = T->Nodes();
96 Standard_Integer n[3];
97 const Poly_Array1OfTriangle& triangles = T->Triangles();
99 for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
100 gp_XYZ eqPlan(0, 0, 0);
101 for (pc.Initialize(i); pc.More(); pc.Next()) {
102 triangles(pc.Value()).Get(n[0], n[1], n[2]);
103 gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord());
104 gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord());
105 eqPlan += (v1^v2).Normalized();
107 Nor(i) = gp_Dir(eqPlan);
108 if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
113 void StlTransfer::RetrieveMesh (const TopoDS_Shape& Shape,
114 const Handle(StlMesh_Mesh)& Mesh)
116 for (TopExp_Explorer itf(Shape,TopAbs_FACE); itf.More(); itf.Next()) {
117 TopoDS_Face face = TopoDS::Face(itf.Current());
118 TopLoc_Location Loc, loc;
119 Handle(Poly_Triangulation) theTriangulation = BRep_Tool::Triangulation(face, Loc);
120 if (theTriangulation.IsNull()) continue; //Meshing was not done for this face!
121 Poly_Array1OfTriangle theTriangles(1,theTriangulation->NbTriangles());
122 theTriangles.Assign(theTriangulation->Triangles());
123 Mesh->AddDomain (theTriangulation->Deflection());
125 TColgp_Array1OfPnt thePoints(1, theTriangulation->NbNodes());
126 thePoints.Assign(theTriangulation->Nodes());
127 //compute normal of face
128 const TColgp_Array1OfPnt& Nodes = theTriangulation->Nodes();
129 TColgp_Array1OfDir NORMAL(Nodes.Lower(), Nodes.Upper());
130 Poly_Connect pc(theTriangulation);
131 Normal(face, pc, NORMAL);
133 for(i=1;i<=thePoints.Length();i++) {
134 Standard_Real X1, Y1, Z1;
135 gp_Pnt p = thePoints.Value(i);
136 p.Transform(Loc.Transformation());
137 p.Coord (X1, Y1, Z1);
138 Mesh->AddVertex (X1, Y1, Z1);
142 for (i=1;i<=theTriangles.Length();i++) {
143 Standard_Integer V1, V2, V3;
144 Poly_Triangle triangle = theTriangles.Value(i);
145 triangle.Get(V1, V2, V3);
147 P1 = Mesh->Vertices(Mesh->NbDomains()).Value(V1);
148 P2 = Mesh->Vertices(Mesh->NbDomains()).Value(V2);
149 P3 = Mesh->Vertices(Mesh->NbDomains()).Value(V3);
150 gp_Vec average = NORMAL(V1);;
152 //check angle between vectors
153 gp_Vec V1V2(P1, P2), V2V3(P2, P3);
154 Standard_Integer A,B,C;
155 gp_Vec vec = V1V2^V2V3;
156 Standard_Real modul1, modul2;
157 modul1 = average.XYZ().Modulus();
158 modul2 = vec.XYZ().Modulus();
159 if (modul2>Precision::Confusion ()) vec.Divide(modul2);
161 // vec.Transform(loc);
162 if (modul1>Precision::Confusion () && modul2>Precision::Confusion ()) {
163 Standard_Real an = vec.Angle(average);
171 Mesh->AddTriangle (A, B, C, average.X(), average.Y(), average.Z());
174 catch(Standard_Failure)
177 cout << "Fail in StlTransfer::BuildIncrementalMesh" << endl;