0022867: Avoid performing mesh of a singled face model in parallel mode when flag...
[occt.git] / src / StlTransfer / StlTransfer.cxx
CommitLineData
b311480e 1// Created on: 2000-06-23
2// Created by: Sergey MOZOKHIN
3// Copyright (c) 2000-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20//=======================================================================
7fd59977 21#include <StlTransfer.ixx>
22#include <Standard_ErrorHandler.hxx>
23#include <Standard_Failure.hxx>
24#include <TopoDS_Face.hxx>
25#include <Poly_Connect.hxx>
26#include <TColgp_Array1OfDir.hxx>
27#include <Poly_Triangulation.hxx>
28#include <BRepAdaptor_Surface.hxx>
29#include <TopLoc_Location.hxx>
30#include <Geom_Surface.hxx>
31#include <BRep_Tool.hxx>
32#include <gp_Vec.hxx>
33#include <gp_Pnt.hxx>
34#include <CSLib.hxx>
35#include <TColgp_Array1OfPnt2d.hxx>
36#include <CSLib.hxx>
37#include <gp_Dir.hxx>
38#include <gp_XYZ.hxx>
416d4426 39#include <BRepMesh_IncrementalMesh.hxx>
7fd59977 40#include <TopAbs.hxx>
41#include <Precision.hxx>
42#include <TopExp_Explorer.hxx>
43#include <TopoDS.hxx>
44#include <TColgp_SequenceOfXYZ.hxx>
45//function computes normals for surface
46
47static void Normal(const TopoDS_Face& aFace,
48 Poly_Connect& pc,
49 TColgp_Array1OfDir& Nor)
50{
51 const Handle(Poly_Triangulation)& T = pc.Triangulation();
52 BRepAdaptor_Surface S;
53 Standard_Boolean hasUV = T->HasUVNodes();
54 Standard_Integer i;
55 TopLoc_Location l;
56 Handle(Geom_Surface) GS = BRep_Tool::Surface(aFace, l);
57
58 if (hasUV && !GS.IsNull()) {
59 Standard_Boolean OK = Standard_True;
60 gp_Vec D1U,D1V;
61 gp_Vec D2U,D2V,D2UV;
62 gp_Pnt P;
63 Standard_Real U, V;
64 CSLib_DerivativeStatus Status;
65 CSLib_NormalStatus NStat;
66 S.Initialize(aFace, Standard_False);
67 const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
68 if (!S.GetType() == GeomAbs_Plane) {
69 for (i = UVNodes.Lower(); i <= UVNodes.Upper(); i++) {
70 U = UVNodes(i).X();
71 V = UVNodes(i).Y();
72 S.D1(U,V,P,D1U,D1V);
73 CSLib::Normal(D1U,D1V,Precision::Angular(),Status,Nor(i));
74 if (Status != CSLib_Done) {
75 S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
76 CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,Nor(i));
77 }
78 if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
79 }
80 }
81 else {
82 gp_Dir NPlane;
83 U = UVNodes(UVNodes.Lower()).X();
84 V = UVNodes(UVNodes.Lower()).Y();
85 S.D1(U,V,P,D1U,D1V);
86 CSLib::Normal(D1U,D1V,Precision::Angular(),Status,NPlane);
87 if (Status != CSLib_Done) {
88 S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
89 CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,NPlane);
90 }
91 if (aFace.Orientation() == TopAbs_REVERSED) NPlane.Reverse();
92 Nor.Init(NPlane);
93
94 }
95 }
96 else {
97 const TColgp_Array1OfPnt& Nodes = T->Nodes();
98 Standard_Integer n[3];
99 const Poly_Array1OfTriangle& triangles = T->Triangles();
100
101 for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
102 gp_XYZ eqPlan(0, 0, 0);
103 for (pc.Initialize(i); pc.More(); pc.Next()) {
104 triangles(pc.Value()).Get(n[0], n[1], n[2]);
105 gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord());
106 gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord());
107 eqPlan += (v1^v2).Normalized();
108 }
109 Nor(i) = gp_Dir(eqPlan);
110 if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
111 }
112 }
113
114}
115void StlTransfer::BuildIncrementalMesh (const TopoDS_Shape& Shape,
416d4426 116 const Standard_Real Deflection,
117 const Standard_Boolean InParallel,
118 const Handle(StlMesh_Mesh)& Mesh)
7fd59977 119{
120 if (Deflection <= Precision::Confusion ()) {
121 Standard_ConstructionError::Raise ("StlTransfer::BuildIncrementalMesh");
122 }
123
124 Standard_Integer NbVertices, NbTriangles;
416d4426 125 BRepMesh_IncrementalMesh aMesher(Shape, Deflection, Standard_False, 0.5, InParallel);
7fd59977 126 for (TopExp_Explorer itf(Shape,TopAbs_FACE); itf.More(); itf.Next()) {
127 TopoDS_Face face = TopoDS::Face(itf.Current());
128 TopLoc_Location Loc, loc;
129 Handle(Poly_Triangulation) theTriangulation = BRep_Tool::Triangulation(face, Loc);
130 if (theTriangulation.IsNull()) continue; //Meshing was not done for this face!
131 Poly_Array1OfTriangle theTriangles(1,theTriangulation->NbTriangles());
132 theTriangles.Assign(theTriangulation->Triangles());
133 Mesh->AddDomain (Deflection);
134
7fd59977 135 TColgp_Array1OfPnt thePoints(1, theTriangulation->NbNodes());
136 thePoints.Assign(theTriangulation->Nodes());
137 //compute normal of face
138 const TColgp_Array1OfPnt& Nodes = theTriangulation->Nodes();
139 TColgp_Array1OfDir NORMAL(Nodes.Lower(), Nodes.Upper());
140 Poly_Connect pc(theTriangulation);
141 Normal(face, pc, NORMAL);
142 Standard_Integer i;
143 for(i=1;i<=thePoints.Length();i++) {
144 Standard_Real X1, Y1, Z1;
145 gp_Pnt p = thePoints.Value(i);
146 p.Transform(Loc.Transformation());
147 p.Coord (X1, Y1, Z1);
148 NbVertices = Mesh->AddVertex (X1, Y1, Z1);
149 }
150 try {
151 OCC_CATCH_SIGNALS
152 for (i=1;i<=theTriangles.Length();i++) {
153 Standard_Integer V1, V2, V3;
154 Poly_Triangle triangle = theTriangles.Value(i);
155 triangle.Get(V1, V2, V3);
156 gp_Pnt P1, P2, P3;
157 P1 = Mesh->Vertices(Mesh->NbDomains()).Value(V1);
158 P2 = Mesh->Vertices(Mesh->NbDomains()).Value(V2);
159 P3 = Mesh->Vertices(Mesh->NbDomains()).Value(V3);
160 gp_Vec average = NORMAL(V1);;
161
162 //check angle between vectors
163 gp_Vec V1V2(P1, P2), V2V3(P2, P3);
164 Standard_Integer A,B,C;
165 gp_Vec vec = V1V2^V2V3;
166 Standard_Real modul1, modul2;
167 modul1 = average.XYZ().Modulus();
168 modul2 = vec.XYZ().Modulus();
169 if (modul2>Precision::Confusion ()) vec.Divide(modul2);
170 A=V1;B=V2;C=V3;
171 // vec.Transform(loc);
172 if (modul1>Precision::Confusion () && modul2>Precision::Confusion ()) {
173 Standard_Real an = vec.Angle(average);
c6541a0c 174 if ( an > M_PI/2) {
7fd59977 175 A = V3;B=V2;C=V1;
176 }
177 else {
178 A=V1;B=V2;C=V3;
179 }
180 }
181 NbTriangles = Mesh->AddTriangle (A, B, C, average.X(), average.Y(), average.Z());
182 }
183 }
184 catch(Standard_Failure)
185 {
186#ifdef DEB
187 cout << "Fail in StlTransfer::BuildIncrementalMesh" << endl;
188#endif
189 }
190 }
191}
192
193
194
195
196
197