0025039: Improvement of code structure of general and supporting tools implemented...
[occt.git] / src / StlTransfer / StlTransfer.cxx
CommitLineData
b311480e 1// Created on: 2000-06-23
2// Created by: Sergey MOZOKHIN
973c2be1 3// Copyright (c) 2000-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
7fd59977 16//=======================================================================
7fd59977 17#include <StlTransfer.ixx>
18#include <Standard_ErrorHandler.hxx>
19#include <Standard_Failure.hxx>
20#include <TopoDS_Face.hxx>
21#include <Poly_Connect.hxx>
22#include <TColgp_Array1OfDir.hxx>
23#include <Poly_Triangulation.hxx>
24#include <BRepAdaptor_Surface.hxx>
25#include <TopLoc_Location.hxx>
26#include <Geom_Surface.hxx>
27#include <BRep_Tool.hxx>
28#include <gp_Vec.hxx>
29#include <gp_Pnt.hxx>
30#include <CSLib.hxx>
31#include <TColgp_Array1OfPnt2d.hxx>
32#include <CSLib.hxx>
33#include <gp_Dir.hxx>
34#include <gp_XYZ.hxx>
416d4426 35#include <BRepMesh_IncrementalMesh.hxx>
7fd59977 36#include <TopAbs.hxx>
37#include <Precision.hxx>
38#include <TopExp_Explorer.hxx>
39#include <TopoDS.hxx>
40#include <TColgp_SequenceOfXYZ.hxx>
41//function computes normals for surface
42
43static void Normal(const TopoDS_Face& aFace,
44 Poly_Connect& pc,
45 TColgp_Array1OfDir& Nor)
46{
47 const Handle(Poly_Triangulation)& T = pc.Triangulation();
48 BRepAdaptor_Surface S;
49 Standard_Boolean hasUV = T->HasUVNodes();
50 Standard_Integer i;
51 TopLoc_Location l;
52 Handle(Geom_Surface) GS = BRep_Tool::Surface(aFace, l);
53
54 if (hasUV && !GS.IsNull()) {
55 Standard_Boolean OK = Standard_True;
56 gp_Vec D1U,D1V;
57 gp_Vec D2U,D2V,D2UV;
58 gp_Pnt P;
59 Standard_Real U, V;
60 CSLib_DerivativeStatus Status;
61 CSLib_NormalStatus NStat;
62 S.Initialize(aFace, Standard_False);
63 const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
c29a9290 64 if (S.GetType() != GeomAbs_Plane) {
7fd59977 65 for (i = UVNodes.Lower(); i <= UVNodes.Upper(); i++) {
66 U = UVNodes(i).X();
67 V = UVNodes(i).Y();
68 S.D1(U,V,P,D1U,D1V);
69 CSLib::Normal(D1U,D1V,Precision::Angular(),Status,Nor(i));
70 if (Status != CSLib_Done) {
71 S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
72 CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,Nor(i));
73 }
74 if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
75 }
76 }
77 else {
78 gp_Dir NPlane;
79 U = UVNodes(UVNodes.Lower()).X();
80 V = UVNodes(UVNodes.Lower()).Y();
81 S.D1(U,V,P,D1U,D1V);
82 CSLib::Normal(D1U,D1V,Precision::Angular(),Status,NPlane);
83 if (Status != CSLib_Done) {
84 S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
85 CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,NPlane);
86 }
87 if (aFace.Orientation() == TopAbs_REVERSED) NPlane.Reverse();
88 Nor.Init(NPlane);
89
90 }
91 }
92 else {
93 const TColgp_Array1OfPnt& Nodes = T->Nodes();
94 Standard_Integer n[3];
95 const Poly_Array1OfTriangle& triangles = T->Triangles();
96
97 for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
98 gp_XYZ eqPlan(0, 0, 0);
99 for (pc.Initialize(i); pc.More(); pc.Next()) {
100 triangles(pc.Value()).Get(n[0], n[1], n[2]);
101 gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord());
102 gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord());
103 eqPlan += (v1^v2).Normalized();
104 }
105 Nor(i) = gp_Dir(eqPlan);
106 if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
107 }
108 }
109
110}
111void StlTransfer::BuildIncrementalMesh (const TopoDS_Shape& Shape,
416d4426 112 const Standard_Real Deflection,
113 const Standard_Boolean InParallel,
114 const Handle(StlMesh_Mesh)& Mesh)
7fd59977 115{
116 if (Deflection <= Precision::Confusion ()) {
117 Standard_ConstructionError::Raise ("StlTransfer::BuildIncrementalMesh");
118 }
119
fc9b36d6 120 BRepMesh_IncrementalMesh aMesher(Shape, Deflection, 0.5, Standard_False, InParallel);
7fd59977 121 for (TopExp_Explorer itf(Shape,TopAbs_FACE); itf.More(); itf.Next()) {
122 TopoDS_Face face = TopoDS::Face(itf.Current());
123 TopLoc_Location Loc, loc;
124 Handle(Poly_Triangulation) theTriangulation = BRep_Tool::Triangulation(face, Loc);
125 if (theTriangulation.IsNull()) continue; //Meshing was not done for this face!
126 Poly_Array1OfTriangle theTriangles(1,theTriangulation->NbTriangles());
127 theTriangles.Assign(theTriangulation->Triangles());
128 Mesh->AddDomain (Deflection);
129
7fd59977 130 TColgp_Array1OfPnt thePoints(1, theTriangulation->NbNodes());
131 thePoints.Assign(theTriangulation->Nodes());
132 //compute normal of face
133 const TColgp_Array1OfPnt& Nodes = theTriangulation->Nodes();
134 TColgp_Array1OfDir NORMAL(Nodes.Lower(), Nodes.Upper());
135 Poly_Connect pc(theTriangulation);
136 Normal(face, pc, NORMAL);
137 Standard_Integer i;
138 for(i=1;i<=thePoints.Length();i++) {
139 Standard_Real X1, Y1, Z1;
140 gp_Pnt p = thePoints.Value(i);
141 p.Transform(Loc.Transformation());
142 p.Coord (X1, Y1, Z1);
96a95605 143 Mesh->AddVertex (X1, Y1, Z1);
7fd59977 144 }
145 try {
146 OCC_CATCH_SIGNALS
147 for (i=1;i<=theTriangles.Length();i++) {
148 Standard_Integer V1, V2, V3;
149 Poly_Triangle triangle = theTriangles.Value(i);
150 triangle.Get(V1, V2, V3);
151 gp_Pnt P1, P2, P3;
152 P1 = Mesh->Vertices(Mesh->NbDomains()).Value(V1);
153 P2 = Mesh->Vertices(Mesh->NbDomains()).Value(V2);
154 P3 = Mesh->Vertices(Mesh->NbDomains()).Value(V3);
155 gp_Vec average = NORMAL(V1);;
156
157 //check angle between vectors
158 gp_Vec V1V2(P1, P2), V2V3(P2, P3);
159 Standard_Integer A,B,C;
160 gp_Vec vec = V1V2^V2V3;
161 Standard_Real modul1, modul2;
162 modul1 = average.XYZ().Modulus();
163 modul2 = vec.XYZ().Modulus();
164 if (modul2>Precision::Confusion ()) vec.Divide(modul2);
165 A=V1;B=V2;C=V3;
166 // vec.Transform(loc);
167 if (modul1>Precision::Confusion () && modul2>Precision::Confusion ()) {
168 Standard_Real an = vec.Angle(average);
c6541a0c 169 if ( an > M_PI/2) {
7fd59977 170 A = V3;B=V2;C=V1;
171 }
172 else {
173 A=V1;B=V2;C=V3;
174 }
175 }
96a95605 176 Mesh->AddTriangle (A, B, C, average.X(), average.Y(), average.Z());
7fd59977 177 }
178 }
179 catch(Standard_Failure)
180 {
181#ifdef DEB
182 cout << "Fail in StlTransfer::BuildIncrementalMesh" << endl;
183#endif
184 }
185 }
186}
187
188
189
190
191
192