0026570: Crash on attempt to rotate a shape.
[occt.git] / src / BRepTools / BRepTools_TrsfModification.cxx
1 // Created on: 1994-08-25
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1994-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_TrsfModification.hxx>
20 #include <Geom2d_Curve.hxx>
21 #include <Geom2d_TrimmedCurve.hxx>
22 #include <Geom_Curve.hxx>
23 #include <Geom_Line.hxx>
24 #include <Geom_Surface.hxx>
25 #include <Geom_TrimmedCurve.hxx>
26 #include <GeomAdaptor_Surface.hxx>
27 #include <GeomLib.hxx>
28 #include <gp.hxx>
29 #include <gp_GTrsf2d.hxx>
30 #include <gp_Pnt.hxx>
31 #include <gp_Trsf.hxx>
32 #include <gp_TrsfForm.hxx>
33 #include <Precision.hxx>
34 #include <Standard_Type.hxx>
35 #include <TopAbs.hxx>
36 #include <TopExp.hxx>
37 #include <TopLoc_Location.hxx>
38 #include <TopoDS.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopoDS_Vertex.hxx>
42
43 IMPLEMENT_STANDARD_RTTIEXT(BRepTools_TrsfModification,BRepTools_Modification)
44
45 //=======================================================================
46 //function : BRepTools_TrsfModification
47 //purpose  : 
48 //=======================================================================
49 BRepTools_TrsfModification::BRepTools_TrsfModification(const gp_Trsf& T) :
50 myTrsf(T)
51 {
52 }
53
54
55 //=======================================================================
56 //function : Trsf
57 //purpose  : 
58 //=======================================================================
59
60 gp_Trsf& BRepTools_TrsfModification::Trsf ()
61 {
62   return myTrsf;
63 }
64
65 //=======================================================================
66 //function : NewSurface
67 //purpose  : 
68 //=======================================================================
69
70 Standard_Boolean BRepTools_TrsfModification::NewSurface
71       (const TopoDS_Face& F,
72        Handle(Geom_Surface)& S,
73        TopLoc_Location& L,
74        Standard_Real& Tol,
75        Standard_Boolean& RevWires,
76        Standard_Boolean& RevFace)
77 {
78   S = BRep_Tool::Surface(F,L);
79   Tol = BRep_Tool::Tolerance(F);
80   Tol *= Abs(myTrsf.ScaleFactor());
81   RevWires = Standard_False;
82   RevFace = myTrsf.IsNegative();
83
84   gp_Trsf LT = L.Transformation();
85   LT.Invert();
86   LT.Multiply(myTrsf);
87   LT.Multiply(L.Transformation());
88
89   S = Handle(Geom_Surface)::DownCast(S->Transformed(LT));
90   
91   return Standard_True;
92 }
93
94
95 //=======================================================================
96 //function : NewCurve
97 //purpose  : 
98 //=======================================================================
99
100 Standard_Boolean BRepTools_TrsfModification::NewCurve
101     (const TopoDS_Edge& E, 
102      Handle(Geom_Curve)& C,
103      TopLoc_Location& L, 
104      Standard_Real& Tol)
105 {
106   Standard_Real f,l;
107   C = BRep_Tool::Curve(E,L,f,l);
108
109   Tol = BRep_Tool::Tolerance(E);
110   Tol *= Abs(myTrsf.ScaleFactor());
111
112   gp_Trsf LT = L.Transformation();
113   LT.Invert();
114   LT.Multiply(myTrsf);
115   LT.Multiply(L.Transformation());
116
117   if (!C.IsNull()) {
118     C = Handle(Geom_Curve)::DownCast(C->Transformed(LT));
119   }
120
121   return Standard_True;
122 }
123
124 //=======================================================================
125 //function : NewPoint
126 //purpose  : 
127 //=======================================================================
128
129 Standard_Boolean BRepTools_TrsfModification::NewPoint
130     (const TopoDS_Vertex& V, 
131      gp_Pnt& P, 
132      Standard_Real& Tol)
133 {
134   P = BRep_Tool::Pnt(V);
135   Tol = BRep_Tool::Tolerance(V);
136   Tol *= Abs(myTrsf.ScaleFactor());
137   P.Transform(myTrsf);
138
139   return Standard_True;
140 }
141
142 //=======================================================================
143 //function : NewCurve2d
144 //purpose  : 
145 //=======================================================================
146
147 Standard_Boolean BRepTools_TrsfModification::NewCurve2d
148     (const TopoDS_Edge& E, 
149      const TopoDS_Face& F, 
150      const TopoDS_Edge&, 
151      const TopoDS_Face&, 
152      Handle(Geom2d_Curve)& C,
153      Standard_Real& Tol)
154 {
155   TopLoc_Location loc;
156   Tol = BRep_Tool::Tolerance(E);
157   Standard_Real scale = myTrsf.ScaleFactor();
158   Tol *= Abs(scale);
159   const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,loc);
160   GeomAdaptor_Surface GAsurf(S);
161   if (GAsurf.GetType() == GeomAbs_Plane)
162     return Standard_False;
163
164   Standard_Real f,l;
165   Handle(Geom2d_Curve) NewC = BRep_Tool::CurveOnSurface(E,F,f,l);
166   if (NewC.IsNull())
167     return Standard_False;
168   
169   Standard_Real newf,newl;
170
171   Handle(Standard_Type) TheType = NewC->DynamicType();
172     
173   if ( TheType == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
174     Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(NewC);
175     NewC = TC->BasisCurve();
176   }
177
178   Standard_Real fc = NewC->FirstParameter(), lc = NewC->LastParameter();
179
180   if(!NewC->IsPeriodic()) {
181     if(fc - f > Precision::PConfusion()) f = fc;
182     if(l - lc > Precision::PConfusion()) l = lc;
183     if(Abs(l - f) < Precision::PConfusion())
184     {
185       if(Abs(f - fc) < Precision::PConfusion())
186       {
187         l = lc;
188       }
189       else
190       {
191         f = fc;
192       }
193     }
194   }
195
196   newf = f;
197   newl = l;
198   if (Abs(scale) != 1.) {
199     
200     NewC = new Geom2d_TrimmedCurve(NewC,f,l);
201     gp_GTrsf2d gtrsf = S->ParametricTransformation(myTrsf);
202     
203     if ( gtrsf.Form() != gp_Identity) {
204       NewC = GeomLib::GTransform(NewC,gtrsf);
205       if (NewC.IsNull()) {
206         throw Standard_DomainError("TrsfModification:Error in NewCurve2d");
207         }
208       newf = NewC->FirstParameter();
209       newl = NewC->LastParameter();
210     }
211   }
212   // il faut parfois recadrer les ranges 3d / 2d
213   TopoDS_Vertex V1, V2;
214   TopExp::Vertices(E,V1,V2);
215   TopoDS_Shape initEFOR = E.Oriented(TopAbs_FORWARD); // skl
216   TopoDS_Edge EFOR = TopoDS::Edge(initEFOR/*E.Oriented(TopAbs_FORWARD)*/); //skl
217   Standard_Real aTolV;
218   NewParameter(V1, EFOR, f, aTolV);
219   NewParameter(V2, EFOR, l, aTolV);
220   GeomLib::SameRange(Precision::PConfusion(), NewC, newf, newl, f, l, C);
221   
222   return Standard_True;
223 }
224
225 //=======================================================================
226 //function : NewParameter
227 //purpose  : 
228 //=======================================================================
229
230 Standard_Boolean BRepTools_TrsfModification::NewParameter
231    (const TopoDS_Vertex& V, 
232     const TopoDS_Edge& E, 
233     Standard_Real& P, 
234     Standard_Real& Tol)
235 {
236   if (V.IsNull()) return Standard_False; // infinite edge may have Null vertex
237   
238   TopLoc_Location loc;
239   Tol = BRep_Tool::Tolerance(V);
240   Tol *= Abs(myTrsf.ScaleFactor());
241   P = BRep_Tool::Parameter(V,E);
242
243   Standard_Real f,l;
244
245   Handle(Geom_Curve) C = BRep_Tool::Curve(E,loc,f,l);
246   if (!C.IsNull()) {
247     P = C->TransformedParameter(P,myTrsf);
248   }
249
250   return Standard_True;
251 }
252
253 //=======================================================================
254 //function : Continuity
255 //purpose  : 
256 //=======================================================================
257
258 GeomAbs_Shape BRepTools_TrsfModification::Continuity
259   (const TopoDS_Edge& E,
260    const TopoDS_Face& F1,
261    const TopoDS_Face& F2,
262    const TopoDS_Edge&,
263    const TopoDS_Face&,
264    const TopoDS_Face&)
265 {
266   return BRep_Tool::Continuity(E,F1,F2);
267 }
268
269