0031479: Modeling Algorithms - exception on geometry transformation of triangulation...
[occt.git] / src / BRepTools / BRepTools_GTrsfModification.cxx
1 // Created on: 1996-12-30
2 // Created by: Stagiaire Mary FABIEN
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Tool.hxx>
19 #include <BRepTools_GTrsfModification.hxx>
20 #include <Geom2d_Curve.hxx>
21 #include <Geom2d_TrimmedCurve.hxx>
22 #include <Geom_BezierCurve.hxx>
23 #include <Geom_BezierSurface.hxx>
24 #include <Geom_BSplineCurve.hxx>
25 #include <Geom_BSplineSurface.hxx>
26 #include <Geom_Curve.hxx>
27 #include <Geom_Surface.hxx>
28 #include <Geom_TrimmedCurve.hxx>
29 #include <GeomLib.hxx>
30 #include <gp_GTrsf.hxx>
31 #include <gp_Pnt.hxx>
32 #include <gp_Quaternion.hxx>
33 #include <gp_XYZ.hxx>
34 #include <Standard_NoSuchObject.hxx>
35 #include <Standard_Type.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TopoDS_Face.hxx>
38 #include <TopoDS_Vertex.hxx>
39
40 IMPLEMENT_STANDARD_RTTIEXT(BRepTools_GTrsfModification,BRepTools_Modification)
41
42 //=======================================================================
43 //function : BRepTools_GTrsfModification
44 //purpose  : 
45 //=======================================================================
46 BRepTools_GTrsfModification::BRepTools_GTrsfModification(const gp_GTrsf& T) :
47 myGTrsf(T)
48 {
49   // on prend comme dilatation maximale pour la tolerance la norme sup
50   Standard_Real loc1, loc2, loc3, loc4;
51
52   loc1 = Max(Abs(T.Value(1,1)), Abs(T.Value(1,2)));
53   loc2 = Max(Abs(T.Value(2,1)), Abs(T.Value(2,2)));
54   loc3 = Max(Abs(T.Value(3,1)), Abs(T.Value(3,2)));
55   loc4 = Max(Abs(T.Value(1,3)), Abs(T.Value(2,3)));
56
57   loc1 = Max(loc1, loc2);
58   loc2 = Max(loc3, loc4);
59
60   loc1 = Max(loc1, loc2);
61
62   myGScale = Max(loc1, Abs(T.Value(3,3)));
63 }
64
65
66 //=======================================================================
67 //function : GTrsf
68 //purpose  : 
69 //=======================================================================
70
71 gp_GTrsf& BRepTools_GTrsfModification::GTrsf ()
72 {
73   return myGTrsf;
74 }
75
76 //=======================================================================
77 //function : NewSurface
78 //purpose  : 
79 //=======================================================================
80
81 Standard_Boolean BRepTools_GTrsfModification::NewSurface
82       (const TopoDS_Face& F,
83        Handle(Geom_Surface)& S,
84        TopLoc_Location& L,
85        Standard_Real& Tol,
86        Standard_Boolean& RevWires,
87        Standard_Boolean& RevFace)
88 {
89   gp_GTrsf gtrsf;
90   gtrsf.SetVectorialPart(myGTrsf.VectorialPart());
91   gtrsf.SetTranslationPart(myGTrsf.TranslationPart());
92   S = BRep_Tool::Surface(F, L);
93   if (S.IsNull())
94   {
95     //processing the case when there is no geometry
96     return Standard_False;
97   }
98   S = Handle(Geom_Surface)::DownCast(S->Copy());
99
100   Tol = BRep_Tool::Tolerance(F);
101   Tol *= myGScale;
102   RevWires = Standard_False;
103   RevFace = myGTrsf.IsNegative();
104   S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
105   
106   Handle(Standard_Type) TheTypeS = S->DynamicType();
107   if (TheTypeS == STANDARD_TYPE(Geom_BSplineSurface)) {
108     Handle(Geom_BSplineSurface) S2 = Handle(Geom_BSplineSurface)::DownCast(S);
109     for(Standard_Integer i = 1; i <= S2->NbUPoles(); i++) 
110       for(Standard_Integer j = 1; j <= S2->NbVPoles(); j++) {
111         gp_XYZ coor(S2->Pole(i, j).Coord());
112         gtrsf.Transforms(coor);
113         gp_Pnt P(coor);
114         S2->SetPole(i, j, P);
115       }
116   }
117   else
118     if (TheTypeS == STANDARD_TYPE(Geom_BezierSurface)) {
119       Handle(Geom_BezierSurface) S2 = Handle(Geom_BezierSurface)::DownCast(S);
120       for(Standard_Integer i = 1; i <= S2->NbUPoles(); i++) 
121         for(Standard_Integer j = 1; j <= S2->NbVPoles(); j++) {
122           gp_XYZ coor(S2->Pole(i, j).Coord());
123           gtrsf.Transforms(coor);
124           gp_Pnt P(coor);
125           S2->SetPole(i, j, P);
126         }
127     }
128     else{
129       throw Standard_NoSuchObject("BRepTools_GTrsfModification : Pb no BSpline/Bezier Type Surface");
130     }
131
132   L.Identity();
133   return Standard_True;
134 }
135
136
137 //=======================================================================
138 //function : NewCurve
139 //purpose  : 
140 //=======================================================================
141
142 Standard_Boolean BRepTools_GTrsfModification::NewCurve
143 (const TopoDS_Edge& E, 
144  Handle(Geom_Curve)& C,
145  TopLoc_Location& L, 
146  Standard_Real& Tol)
147 {
148   Standard_Real f,l;
149   gp_GTrsf gtrsf;
150   gtrsf.SetVectorialPart(myGTrsf.VectorialPart());
151   gtrsf.SetTranslationPart(myGTrsf.TranslationPart());
152   Tol = BRep_Tool::Tolerance(E)*myGScale;
153   C = BRep_Tool::Curve(E, L, f, l);
154   
155   if (!C.IsNull()) {
156     C = Handle(Geom_Curve)::DownCast(C->Copy()->Transformed(L.Transformation()));
157     Handle(Standard_Type) TheTypeC = C->DynamicType();
158     if (TheTypeC == STANDARD_TYPE(Geom_BSplineCurve)) {
159       Handle(Geom_BSplineCurve) C2 = Handle(Geom_BSplineCurve)::DownCast(C);
160       for(Standard_Integer i = 1; i <= C2->NbPoles(); i++) {
161         gp_XYZ coor(C2->Pole(i).Coord());
162         gtrsf.Transforms(coor);
163         gp_Pnt P(coor);
164         C2->SetPole(i, P);
165       }
166     }
167     else
168       if(TheTypeC == STANDARD_TYPE(Geom_BezierCurve)) {
169         Handle(Geom_BezierCurve) C2 = Handle(Geom_BezierCurve)::DownCast(C);
170         for(Standard_Integer i = 1; i <= C2->NbPoles(); i++) {
171           gp_XYZ coor(C2->Pole(i).Coord());
172           gtrsf.Transforms(coor);
173           gp_Pnt P(coor);
174           C2->SetPole(i, P);
175         }
176       }
177       else {
178         throw Standard_NoSuchObject("BRepTools_GTrsfModification : Pb no BSpline/Bezier Type Curve");
179       }
180     C = new Geom_TrimmedCurve(C, f, l);
181   }
182   L.Identity() ;  
183   return !C.IsNull();
184 }
185
186 //=======================================================================
187 //function : NewPoint
188 //purpose  : 
189 //=======================================================================
190
191 Standard_Boolean BRepTools_GTrsfModification::NewPoint
192 (const TopoDS_Vertex& V, 
193  gp_Pnt& P, 
194  Standard_Real& Tol)
195 {
196   gp_Pnt Pnt = BRep_Tool::Pnt(V);
197   Tol = BRep_Tool::Tolerance(V);
198   Tol *= myGScale;
199   gp_XYZ coor(Pnt.Coord());
200   myGTrsf.Transforms(coor);
201   P.SetXYZ(coor);
202
203   return Standard_True;
204 }
205
206 //=======================================================================
207 //function : NewCurve2d
208 //purpose  : 
209 //=======================================================================
210
211 Standard_Boolean BRepTools_GTrsfModification::NewCurve2d
212     (const TopoDS_Edge& E, 
213      const TopoDS_Face& F, 
214      const TopoDS_Edge&, 
215      const TopoDS_Face&, 
216      Handle(Geom2d_Curve)& C,
217      Standard_Real& Tol)
218 {
219   TopLoc_Location loc;
220   Tol = BRep_Tool::Tolerance(E);
221   Tol *= myGScale;
222   Standard_Real f,l;
223   C = BRep_Tool::CurveOnSurface(E,F,f,l);
224   if (C.IsNull())
225   {
226     //processing the case when there is no geometry
227     return Standard_False;
228   }
229   C = new Geom2d_TrimmedCurve(C, f, l);
230   return Standard_True;
231 }
232
233 //=======================================================================
234 //function : NewParameter
235 //purpose  : 
236 //=======================================================================
237
238 Standard_Boolean BRepTools_GTrsfModification::NewParameter
239    (const TopoDS_Vertex& V, 
240     const TopoDS_Edge& E, 
241     Standard_Real& P, 
242     Standard_Real& Tol)
243 {
244   Tol = BRep_Tool::Tolerance(V);
245   Tol *= myGScale;
246   P = BRep_Tool::Parameter(V,E);
247   return Standard_True;
248 }
249
250 //=======================================================================
251 //function : Continuity
252 //purpose  : 
253 //=======================================================================
254
255 GeomAbs_Shape BRepTools_GTrsfModification::Continuity
256   (const TopoDS_Edge& E,
257    const TopoDS_Face& F1,
258    const TopoDS_Face& F2,
259    const TopoDS_Edge&,
260    const TopoDS_Face&,
261    const TopoDS_Face&)
262 {
263   return BRep_Tool::Continuity(E,F1,F2);
264 }
265
266 //=======================================================================
267 //function : NewTriangulation
268 //purpose  : 
269 //=======================================================================
270
271 Standard_Boolean BRepTools_GTrsfModification::NewTriangulation(const TopoDS_Face&          theFace,
272                                                                Handle(Poly_Triangulation)& theTriangulation)
273 {
274   TopLoc_Location aLoc;
275   theTriangulation = BRep_Tool::Triangulation(theFace, aLoc);
276   if (theTriangulation.IsNull())
277   {
278     return Standard_False;
279   }
280
281   gp_GTrsf aGTrsf;
282   aGTrsf.SetVectorialPart(myGTrsf.VectorialPart());
283   aGTrsf.SetTranslationPart(myGTrsf.TranslationPart());
284   aGTrsf.Multiply(aLoc.Transformation());
285
286   theTriangulation = theTriangulation->Copy();
287   theTriangulation->SetCachedMinMax(Bnd_Box()); // clear bounding box
288   theTriangulation->Deflection(theTriangulation->Deflection() * Abs(myGScale));
289   // apply transformation to 3D nodes
290   for (Standard_Integer anInd = 1; anInd <= theTriangulation->NbNodes(); ++anInd)
291   {
292     gp_Pnt aP = theTriangulation->Node(anInd);
293     aGTrsf.Transforms(aP.ChangeCoord());
294     theTriangulation->SetNode(anInd, aP);
295   }
296   // modify triangles orientation in case of mirror transformation
297   if (myGScale < 0.0)
298   {
299     for (Standard_Integer anInd = 1; anInd <= theTriangulation->NbTriangles(); ++anInd)
300     {
301       Poly_Triangle aTria = theTriangulation->Triangle(anInd);
302       Standard_Integer aN1, aN2, aN3;
303       aTria.Get(aN1, aN2, aN3);
304       aTria.Set(aN1, aN3, aN2);
305       theTriangulation->SetTriangle(anInd, aTria);
306     }
307   }
308   // modify normals
309   if (theTriangulation->HasNormals())
310   {
311     for (Standard_Integer anInd = 1; anInd <= theTriangulation->NbTriangles(); ++anInd)
312     {
313       gp_Dir aNormal = theTriangulation->Normal(anInd);
314       aNormal.Transform(aGTrsf.Trsf());
315       theTriangulation->SetNormal(anInd, aNormal);
316     }
317   }
318
319   return Standard_True;
320 }
321
322 //=======================================================================
323 //function : NewPolygon
324 //purpose  : 
325 //=======================================================================
326
327 Standard_Boolean BRepTools_GTrsfModification::NewPolygon(const TopoDS_Edge&      theEdge,
328                                                          Handle(Poly_Polygon3D)& thePoly)
329 {
330   TopLoc_Location aLoc;
331   thePoly = BRep_Tool::Polygon3D(theEdge, aLoc);
332   if (thePoly.IsNull())
333   {
334     return Standard_False;
335   }
336
337   gp_GTrsf aGTrsf;
338   aGTrsf.SetVectorialPart(myGTrsf.VectorialPart());
339   aGTrsf.SetTranslationPart(myGTrsf.TranslationPart());
340   aGTrsf.Multiply(aLoc.Transformation());
341
342   thePoly = thePoly->Copy();
343   thePoly->Deflection(thePoly->Deflection() * Abs(myGScale));
344   // transform nodes
345   TColgp_Array1OfPnt& aNodesArray = thePoly->ChangeNodes();
346   for (Standard_Integer anId = aNodesArray.Lower(); anId <= aNodesArray.Upper(); ++anId)
347   {
348     gp_Pnt& aP = aNodesArray.ChangeValue(anId);
349     aGTrsf.Transforms(aP.ChangeCoord());
350   }
351   return Standard_True;
352 }
353
354 //=======================================================================
355 //function : NewPolygonOnTriangulation
356 //purpose  : 
357 //=======================================================================
358
359 Standard_Boolean BRepTools_GTrsfModification::NewPolygonOnTriangulation
360  (const TopoDS_Edge& theEdge,
361   const TopoDS_Face& theFace,
362   Handle(Poly_PolygonOnTriangulation)& thePoly)
363 {
364   TopLoc_Location aLoc;
365   Handle(Poly_Triangulation) aT = BRep_Tool::Triangulation(theFace, aLoc);
366   if (aT.IsNull())
367   {
368     return Standard_False;
369   }
370
371   thePoly = BRep_Tool::PolygonOnTriangulation(theEdge, aT, aLoc);
372   if (!thePoly.IsNull())
373     thePoly = thePoly->Copy();
374   return Standard_True;
375 }