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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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>
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>
51 #include <TopExp_Explorer.hxx>
52 #include <TopLoc_Location.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>
60 //=======================================================================
61 //function : Draft_Modification
63 //=======================================================================
64 Draft_Modification::Draft_Modification (const TopoDS_Shape& S) :
65 myComp(Standard_False),myShape(S)
67 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myEFMap);
72 //=======================================================================
75 //=======================================================================
77 void Draft_Modification::Clear ()
79 myComp = Standard_False;
85 errStat = Draft_NoError;
90 //=======================================================================
93 //=======================================================================
95 void Draft_Modification::Init(const TopoDS_Shape& S)
99 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myEFMap);
102 //=======================================================================
105 //=======================================================================
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)
113 if (!badShape.IsNull()) {
114 Standard_ConstructionError::Raise();
121 return InternalAdd(F,Direction,Angle,NeutralPlane, Flag);
125 //=======================================================================
128 //=======================================================================
130 void Draft_Modification::Remove(const TopoDS_Face& F)
132 if (!myFMap.IsBound(F) || myComp) {
133 Standard_NoSuchObject::Raise();
137 TopTools_ListIteratorOfListOfShape ltod;
139 curFace = myFMap(F).RootFace();
140 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
142 const TopoDS_Face& theF = itf.Key();
143 if (myFMap(theF).RootFace().IsSame(curFace)) {
145 if (theF.IsSame(badShape)) {
152 ltod.Initialize(conneF);
153 while (ltod.More()) {
154 myFMap.UnBind(TopoDS::Face(ltod.Value()));
159 Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
161 const TopoDS_Edge& theE = ite.Key();
162 if (myEMap(theE).RootFace().IsSame(curFace)) {
167 ltod.Initialize(conneF);
168 while (ltod.More()) {
169 myEMap.UnBind(TopoDS::Edge(ltod.Value()));
175 //=======================================================================
178 //=======================================================================
180 Standard_Boolean Draft_Modification::IsDone() const
182 return myComp && badShape.IsNull();
186 //=======================================================================
189 //=======================================================================
191 Draft_ErrorStatus Draft_Modification::Error() const
197 //=======================================================================
198 //function : ProblematicShape
200 //=======================================================================
202 const TopoDS_Shape& Draft_Modification::ProblematicShape() const
208 //=======================================================================
209 //function : ConnectedFaces
211 //=======================================================================
213 const TopTools_ListOfShape & Draft_Modification::ConnectedFaces(const TopoDS_Face& F)
215 if (!myFMap.IsBound(F)) {
216 Standard_NoSuchObject::Raise();
219 StdFail_NotDone::Raise();
222 curFace = myFMap(F).RootFace();
224 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
226 const TopoDS_Face& theF = itf.Key();
227 if (myFMap(theF).RootFace().IsSame(curFace)) {
239 //=======================================================================
240 //function : ModifiedFaces
242 //=======================================================================
244 const TopTools_ListOfShape & Draft_Modification::ModifiedFaces()
246 if (!badShape.IsNull()) {
247 StdFail_NotDone::Raise();
251 Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
253 const TopoDS_Face& theF = itf.Key();
254 if (!myFMap(theF).RootFace().IsNull()) {
266 //=======================================================================
267 //function : NewSurface
269 //=======================================================================
271 Standard_Boolean Draft_Modification::NewSurface(const TopoDS_Face& F,
272 Handle(Geom_Surface)& S,
275 Standard_Boolean& RevWires,
276 Standard_Boolean& RevFace)
278 if (!IsDone()) {Standard_DomainError::Raise();}
280 if (!myFMap.IsBound(F) || !myFMap(F).NewGeometry()) {
281 return Standard_False;
284 RevWires = Standard_False;
285 RevFace = Standard_False;
286 Tol = BRep_Tool::Tolerance(F);
288 S = BRep_Tool::Surface(F,L);
292 S = myFMap(F).Geometry();
294 return Standard_True;
298 //=======================================================================
299 //function : NewCurve
301 //=======================================================================
303 Standard_Boolean Draft_Modification::NewCurve(const TopoDS_Edge& E,
304 Handle(Geom_Curve)& C,
308 if (!IsDone()) {Standard_DomainError::Raise();}
310 if (!myEMap.IsBound(E))
311 return Standard_False;
313 const Draft_EdgeInfo& Einf= myEMap(E);
314 if (!myEMap(E).NewGeometry())
315 return Standard_False;
317 Tol = Einf.Tolerance();
318 Tol = Max(Tol, BRep_Tool::Tolerance(E));
320 C = myEMap(E).Geometry();
322 return Standard_True;
327 //=======================================================================
328 //function : NewPoint
330 //=======================================================================
332 Standard_Boolean Draft_Modification::NewPoint(const TopoDS_Vertex& V,
336 if (!IsDone()) {Standard_DomainError::Raise();};
338 if (!myVMap.IsBound(V)) {
339 return Standard_False;
342 Tol = BRep_Tool::Tolerance(V);
343 P = myVMap(V).Geometry();
344 return Standard_True;
348 //=======================================================================
349 //function : NewCurve2d
351 //=======================================================================
353 Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
354 const TopoDS_Face& F,
355 const TopoDS_Edge& NewE,
357 Handle(Geom2d_Curve)& C,
361 if (!IsDone()) {Standard_DomainError::Raise();};
363 if (!myEMap.IsBound(E)) {
364 return Standard_False;
368 BRep_Tool::Range(NewE,Fp,Lp);
370 Handle(Geom_Surface) SB = myFMap(F).Geometry();
372 const Draft_EdgeInfo& Einf = myEMap(E);
373 if ( Einf.FirstFace().IsSame(F) && !Einf.FirstPC().IsNull()) {
376 else if ( Einf.SecondFace().IsSame(F) && !Einf.SecondPC().IsNull()) {
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;
389 Tol = BRep_Tool::Tolerance(E);
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(),
395 Fp = TC->FirstParameter();
396 Lp = TC->LastParameter();
398 B.Range( NewE, Fp, Lp );
399 C = GeomProjLib::Curve2d(TC,Fp, Lp, SB, Tol);
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();
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;
416 JeRecadre = JeRecadre ||
417 (typs == STANDARD_TYPE(Geom_CylindricalSurface)) ||
418 (typs == STANDARD_TYPE(Geom_SphericalSurface)) ||
419 (typs == STANDARD_TYPE(Geom_ConicalSurface));
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;
428 aC2DE=BRep_Tool::CurveOnSurface(E, F, aT1, aT2);
430 PF=aC2DE->Value(0.5*(aT1+aT2));
432 NewPF=C->Value(0.5*(Fp+Lp));
434 aD2=NewPF.SquareDistance(PF);
436 bTranslate=Standard_False;
437 if (NewPF.Translated(vectra).SquareDistance(PF) < aD2) {
439 bTranslate=!bTranslate; //True
441 else if (NewPF.Translated(-vectra).SquareDistance(PF) < aD2) {
443 bTranslate=!bTranslate; //True
450 return Standard_True;
454 //=======================================================================
455 //function : NewParameter
457 //=======================================================================
459 Standard_Boolean Draft_Modification::NewParameter(const TopoDS_Vertex& V,
460 const TopoDS_Edge& E,
465 if (!IsDone()) {Standard_DomainError::Raise();};
467 if (!myVMap.IsBound(V)) {
468 return Standard_False;
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();
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);
486 paramf = BRep_Tool::Parameter(FV,E);
490 Standard_Real FirstPar = GC->FirstParameter(), LastPar = GC->LastParameter();
491 Standard_Real pconf = Precision::PConfusion();
492 if (Abs( paramf - LastPar ) <= pconf)
495 FV.Orientation(E.Orientation());
500 FV.Orientation(E.Orientation());
501 if (!V.IsEqual(FV) && P <= paramf) {
502 if (GC->IsPeriodic()) {
506 P = GC->LastParameter();
511 Tol = Max (BRep_Tool::Tolerance(V), BRep_Tool::Tolerance(E));
512 return Standard_True;
517 //=======================================================================
518 //function : Continuity
520 //=======================================================================
522 GeomAbs_Shape Draft_Modification::Continuity(const TopoDS_Edge& E,
523 const TopoDS_Face& F1,
524 const TopoDS_Face& F2,
529 return BRep_Tool::Continuity(E,F1,F2);