0065bb73e9ecd9e69874442a9349e79c1dc1b69f
[occt.git] / src / Draft / Draft_Modification.cxx
1 // Created on: 1994-08-30
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_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepTools.hxx>
21 #include <Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx>
22 #include <Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx>
23 #include <Draft_EdgeInfo.hxx>
24 #include <Draft_FaceInfo.hxx>
25 #include <Draft_Modification.hxx>
26 #include <Draft_VertexInfo.hxx>
27 #include <Geom2d_Curve.hxx>
28 #include <Geom_Circle.hxx>
29 #include <Geom_ConicalSurface.hxx>
30 #include <Geom_Curve.hxx>
31 #include <Geom_CylindricalSurface.hxx>
32 #include <Geom_Ellipse.hxx>
33 #include <Geom_RectangularTrimmedSurface.hxx>
34 #include <Geom_SphericalSurface.hxx>
35 #include <Geom_Surface.hxx>
36 #include <Geom_SurfaceOfLinearExtrusion.hxx>
37 #include <Geom_TrimmedCurve.hxx>
38 #include <GeomProjLib.hxx>
39 #include <gp_Dir.hxx>
40 #include <gp_Pln.hxx>
41 #include <gp_Pnt.hxx>
42 #include <gp_Pnt2d.hxx>
43 #include <gp_Vec2d.hxx>
44 #include <Precision.hxx>
45 #include <Standard_ConstructionError.hxx>
46 #include <Standard_DomainError.hxx>
47 #include <Standard_NoSuchObject.hxx>
48 #include <Standard_Type.hxx>
49 #include <StdFail_NotDone.hxx>
50 #include <TopExp.hxx>
51 #include <TopExp_Explorer.hxx>
52 #include <TopLoc_Location.hxx>
53 #include <TopoDS.hxx>
54 #include <TopoDS_Edge.hxx>
55 #include <TopoDS_Face.hxx>
56 #include <TopoDS_Shape.hxx>
57 #include <TopoDS_Vertex.hxx>
58 #include <TopTools_ListIteratorOfListOfShape.hxx>
59
60 //=======================================================================
61 //function : Draft_Modification
62 //purpose  : 
63 //=======================================================================
64 Draft_Modification::Draft_Modification (const TopoDS_Shape& S) :
65        myComp(Standard_False),myShape(S)
66 {
67   TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myEFMap);
68 }
69
70
71
72 //=======================================================================
73 //function : Clear
74 //purpose  : 
75 //=======================================================================
76
77 void Draft_Modification::Clear ()
78 {
79   myComp = Standard_False;
80   myFMap.Clear();
81   myEMap.Clear();
82   myVMap.Clear();
83   myEFMap.Clear();
84   badShape.Nullify();
85   errStat = Draft_NoError;
86 }
87
88
89
90 //=======================================================================
91 //function : Init
92 //purpose  : 
93 //=======================================================================
94
95 void Draft_Modification::Init(const TopoDS_Shape& S)
96 {
97   myShape = S;
98   Clear();
99   TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myEFMap);
100 }
101
102 //=======================================================================
103 //function : Add
104 //purpose  : 
105 //=======================================================================
106
107 Standard_Boolean Draft_Modification::Add(const TopoDS_Face& F,
108                                          const gp_Dir& Direction,
109                                          const Standard_Real Angle,
110                                          const gp_Pln& NeutralPlane,
111                                          const Standard_Boolean Flag)
112 {
113   if (!badShape.IsNull()) {
114     Standard_ConstructionError::Raise();
115   }
116
117   if (myComp) {
118     Clear();
119   }
120   curFace = F;
121   return InternalAdd(F,Direction,Angle,NeutralPlane, Flag);
122 }
123
124
125 //=======================================================================
126 //function : Remove
127 //purpose  : 
128 //=======================================================================
129
130 void Draft_Modification::Remove(const TopoDS_Face& F)
131 {
132   if (!myFMap.IsBound(F) || myComp) {
133     Standard_NoSuchObject::Raise();
134   }
135
136   conneF.Clear();
137   TopTools_ListIteratorOfListOfShape ltod;
138
139   curFace = myFMap(F).RootFace();
140   Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
141   while (itf.More()) {
142     const TopoDS_Face& theF = itf.Key();
143     if (myFMap(theF).RootFace().IsSame(curFace)) {
144       conneF.Append(theF);
145       if (theF.IsSame(badShape)) {
146         badShape.Nullify();
147       }
148     }
149     itf.Next();
150   }
151
152   ltod.Initialize(conneF);
153   while (ltod.More()) {
154     myFMap.UnBind(TopoDS::Face(ltod.Value()));
155     ltod.Next();
156   }
157
158   conneF.Clear();
159   Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
160   while (ite.More()) {
161     const TopoDS_Edge& theE = ite.Key();
162     if (myEMap(theE).RootFace().IsSame(curFace)) {
163       conneF.Append(theE);
164     }
165     ite.Next();
166   }
167   ltod.Initialize(conneF);
168   while (ltod.More()) {
169     myEMap.UnBind(TopoDS::Edge(ltod.Value()));
170     ltod.Next();
171   }
172 }
173
174
175 //=======================================================================
176 //function : IsDone
177 //purpose  : 
178 //=======================================================================
179
180 Standard_Boolean Draft_Modification::IsDone() const
181 {
182   return myComp && badShape.IsNull();
183
184
185
186 //=======================================================================
187 //function : Error
188 //purpose  : 
189 //=======================================================================
190
191 Draft_ErrorStatus Draft_Modification::Error() const
192 {
193   return errStat;
194
195
196
197 //=======================================================================
198 //function : ProblematicShape
199 //purpose  : 
200 //=======================================================================
201
202 const TopoDS_Shape& Draft_Modification::ProblematicShape() const
203 {
204   return badShape;
205
206
207
208 //=======================================================================
209 //function : ConnectedFaces
210 //purpose  : 
211 //=======================================================================
212
213 const TopTools_ListOfShape & Draft_Modification::ConnectedFaces(const TopoDS_Face& F)
214 {
215   if (!myFMap.IsBound(F)) {
216     Standard_NoSuchObject::Raise();
217   }
218   if (!IsDone()) {
219     StdFail_NotDone::Raise();
220   }
221   conneF.Clear();
222   curFace = myFMap(F).RootFace();
223
224   Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
225   while (itf.More()) {
226     const TopoDS_Face& theF = itf.Key();
227     if (myFMap(theF).RootFace().IsSame(curFace)) {
228       conneF.Append(theF);
229     }
230     itf.Next();
231   }
232
233   return conneF;
234   
235
236 }
237
238
239 //=======================================================================
240 //function : ModifiedFaces
241 //purpose  : 
242 //=======================================================================
243
244 const TopTools_ListOfShape & Draft_Modification::ModifiedFaces()
245 {
246   if (!badShape.IsNull()) {
247     StdFail_NotDone::Raise();
248   }
249   conneF.Clear();
250
251   Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
252   while (itf.More()) {
253     const TopoDS_Face& theF = itf.Key();
254     if (!myFMap(theF).RootFace().IsNull()) {
255       conneF.Append(theF);
256     }
257     itf.Next();
258   }
259
260   return conneF;
261   
262
263 }
264
265
266 //=======================================================================
267 //function : NewSurface
268 //purpose  : 
269 //=======================================================================
270
271 Standard_Boolean Draft_Modification::NewSurface(const TopoDS_Face& F,
272                                                 Handle(Geom_Surface)& S,
273                                                 TopLoc_Location& L,
274                                                 Standard_Real& Tol,
275                                                 Standard_Boolean& RevWires,
276                                                 Standard_Boolean& RevFace)
277 {
278   if (!IsDone()) {Standard_DomainError::Raise();}
279
280   if (!myFMap.IsBound(F) || !myFMap(F).NewGeometry()) {
281     return Standard_False;
282   }
283
284   RevWires = Standard_False;
285   RevFace = Standard_False;
286   Tol = BRep_Tool::Tolerance(F);
287
288   S = BRep_Tool::Surface(F,L);
289
290   L.Identity();
291
292   S = myFMap(F).Geometry();
293
294   return Standard_True;
295 }
296                                                 
297
298 //=======================================================================
299 //function : NewCurve
300 //purpose  : 
301 //=======================================================================
302
303 Standard_Boolean Draft_Modification::NewCurve(const TopoDS_Edge& E,
304                                               Handle(Geom_Curve)& C,
305                                               TopLoc_Location& L, 
306                                               Standard_Real& Tol)
307 {
308   if (!IsDone()) {Standard_DomainError::Raise();}
309
310   if (!myEMap.IsBound(E)) 
311     return Standard_False;
312   
313   const Draft_EdgeInfo& Einf= myEMap(E);
314   if (!myEMap(E).NewGeometry())
315     return Standard_False;
316   
317   Tol = Einf.Tolerance();
318   Tol = Max(Tol, BRep_Tool::Tolerance(E));
319   L.Identity();
320   C = myEMap(E).Geometry();
321
322   return Standard_True;
323
324 }
325
326
327 //=======================================================================
328 //function : NewPoint
329 //purpose  : 
330 //=======================================================================
331
332 Standard_Boolean Draft_Modification::NewPoint(const TopoDS_Vertex& V,
333                                               gp_Pnt& P, 
334                                               Standard_Real& Tol)
335 {
336   if (!IsDone()) {Standard_DomainError::Raise();};
337
338   if (!myVMap.IsBound(V)) {
339     return Standard_False;
340   }
341
342   Tol = BRep_Tool::Tolerance(V);
343   P = myVMap(V).Geometry();
344   return Standard_True;
345 }
346
347
348 //=======================================================================
349 //function : NewCurve2d
350 //purpose  : 
351 //=======================================================================
352
353 Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E, 
354                                                 const TopoDS_Face& F, 
355                                                 const TopoDS_Edge& NewE, 
356                                                 const TopoDS_Face&, 
357                                                 Handle(Geom2d_Curve)& C,
358                                                 Standard_Real& Tol)
359 {
360   
361   if (!IsDone()) {Standard_DomainError::Raise();};
362
363   if (!myEMap.IsBound(E)) {
364     return Standard_False;
365   }
366   
367   Standard_Real Fp,Lp;
368   BRep_Tool::Range(NewE,Fp,Lp);
369   
370   Handle(Geom_Surface) SB = myFMap(F).Geometry();
371
372   const Draft_EdgeInfo& Einf = myEMap(E);
373   if ( Einf.FirstFace().IsSame(F) && !Einf.FirstPC().IsNull()) {
374     C = Einf.FirstPC();
375   }
376   else if ( Einf.SecondFace().IsSame(F) && !Einf.SecondPC().IsNull()) {
377     C = Einf.SecondPC();
378   }
379   else {
380     
381     if (!myEMap(E).NewGeometry()) {
382       Standard_Real Fpi,Lpi;
383       BRep_Tool::Range(E,Fpi,Lpi);
384       if (Fpi <= Fp && Fp <= Lpi && Fpi <= Lp && Lp <= Lpi) {
385         return Standard_False;
386       }
387     }
388     
389     Tol = BRep_Tool::Tolerance(E);
390     
391     //  if (!BRep_Tool::IsClosed(E,F)) {
392     BRep_Tool::Range(NewE,Fp,Lp);
393     Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(myEMap(E).Geometry(),
394                                                          Fp,Lp);
395     Fp = TC->FirstParameter();
396     Lp = TC->LastParameter();
397     BRep_Builder B;
398     B.Range( NewE, Fp, Lp );
399     C = GeomProjLib::Curve2d(TC,Fp, Lp, SB, Tol);
400   }
401
402   Handle(Standard_Type) typs = SB->DynamicType();
403   if (typs == STANDARD_TYPE(Geom_RectangularTrimmedSurface) ) {
404     SB = Handle(Geom_RectangularTrimmedSurface)::DownCast(SB)->BasisSurface();
405     typs = SB->DynamicType();
406   }
407
408   Standard_Boolean JeRecadre = Standard_False;
409   if (typs == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
410     Handle(Geom_Curve) aC = 
411       Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(SB)->BasisCurve();
412     Handle(Standard_Type) typc = aC->DynamicType();
413     if (typc == STANDARD_TYPE(Geom_Circle)) JeRecadre = Standard_True;
414   }
415
416   JeRecadre = JeRecadre || 
417               (typs == STANDARD_TYPE(Geom_CylindricalSurface)) || 
418               (typs == STANDARD_TYPE(Geom_SphericalSurface)) || 
419               (typs == STANDARD_TYPE(Geom_ConicalSurface));
420
421   if ( JeRecadre) {
422     Standard_Boolean bTranslate;
423     Standard_Real aD2, aT1, aT2;
424     gp_Pnt2d  PF, NewPF, aP2DT;
425     gp_Vec2d aV2DT, vectra(2.*M_PI,0.);
426     Handle(Geom2d_Curve) aC2DE;
427     //
428     aC2DE=BRep_Tool::CurveOnSurface(E, F, aT1, aT2);
429     //
430     PF=aC2DE->Value(0.5*(aT1+aT2));
431     //
432     NewPF=C->Value(0.5*(Fp+Lp));
433     //
434     aD2=NewPF.SquareDistance(PF);
435     //
436     bTranslate=Standard_False;
437     if (NewPF.Translated(vectra).SquareDistance(PF) < aD2) {
438       aV2DT=vectra;
439       bTranslate=!bTranslate; //True
440     }
441     else if (NewPF.Translated(-vectra).SquareDistance(PF) < aD2) {
442       aV2DT=-vectra;
443       bTranslate=!bTranslate; //True
444     }
445     //
446     if (bTranslate) {
447       C->Translate(aV2DT);
448     }
449   }
450   return Standard_True;
451 }
452
453
454 //=======================================================================
455 //function : NewParameter
456 //purpose  : 
457 //=======================================================================
458
459 Standard_Boolean Draft_Modification::NewParameter(const TopoDS_Vertex& V,
460                                                   const TopoDS_Edge& E,
461                                                   Standard_Real& P,
462                                                   Standard_Real& Tol)
463 {
464
465   if (!IsDone()) {Standard_DomainError::Raise();};
466
467   if (!myVMap.IsBound(V)) {
468     return Standard_False;
469   }
470
471   P = myVMap(V).Parameter(E);
472   Handle(Geom_Curve) GC = myEMap(E).Geometry();
473   Handle(Standard_Type) typc = GC->DynamicType();
474   if (typc == STANDARD_TYPE(Geom_TrimmedCurve)) {
475     GC = Handle(Geom_TrimmedCurve)::DownCast(GC);
476     typc = GC->DynamicType();
477   }
478
479   if (GC->IsClosed()) {
480     TopoDS_Vertex FV = TopExp::FirstVertex(E);
481     Standard_Real paramf;
482     if (myVMap.IsBound(FV)) {
483       paramf = myVMap(FV).Parameter(E);
484     }
485     else {
486       paramf = BRep_Tool::Parameter(FV,E);
487     }
488
489     //Patch
490     Standard_Real FirstPar = GC->FirstParameter(), LastPar = GC->LastParameter();
491     Standard_Real pconf = Precision::PConfusion();
492     if (Abs( paramf - LastPar ) <= pconf)
493       {
494         paramf = FirstPar;
495         FV.Orientation(E.Orientation());
496         if (V.IsEqual( FV ))
497           P = paramf;
498       }
499
500     FV.Orientation(E.Orientation());
501     if (!V.IsEqual(FV) && P <= paramf) {
502       if (GC->IsPeriodic()) {
503         P += GC->Period();
504       }
505       else {
506         P = GC->LastParameter();
507       }
508     }
509   }
510   
511   Tol = Max (BRep_Tool::Tolerance(V), BRep_Tool::Tolerance(E));
512   return Standard_True;
513 }
514
515
516
517 //=======================================================================
518 //function : Continuity
519 //purpose  : 
520 //=======================================================================
521
522 GeomAbs_Shape Draft_Modification::Continuity(const TopoDS_Edge& E,
523                                              const TopoDS_Face& F1,
524                                              const TopoDS_Face& F2,
525                                              const TopoDS_Edge&,
526                                              const TopoDS_Face&,
527                                              const TopoDS_Face&)
528 {
529   return BRep_Tool::Continuity(E,F1,F2);
530 }
531                                              
532