1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <ShapeUpgrade_RemoveLocations.ixx>
15 #include <TopAbs_ShapeEnum.hxx>
16 #include <TopLoc_Location.hxx>
17 #include <TopoDS_Face.hxx>
19 #include <Geom_Surface.hxx>
20 #include <BRep_Builder.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopoDS_Vertex.hxx>
25 #include <Geom_Curve.hxx>
26 #include <BRep_Tool.hxx>
28 #include <TopoDS_Iterator.hxx>
29 #include <TopTools_DataMapOfShapeShape.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom_Geometry.hxx>
32 #include <gp_Trsf.hxx>
34 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
35 #include <BRep_TEdge.hxx>
36 #include <BRep_GCurve.hxx>
37 #include <BRep_CurveRepresentation.hxx>
38 #include <TColStd_ListIteratorOfListOfTransient.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <TColStd_ListOfTransient.hxx>
41 //#include <ShapeUpgrade_DataMapOfShapeListOfTransient.hxx>
42 #include <ShapeBuild_Edge.hxx>
43 #include <Geom_Plane.hxx>
45 //=======================================================================
46 //function : ShapeUpgrade_RemoveLocations
48 //=======================================================================
50 ShapeUpgrade_RemoveLocations::ShapeUpgrade_RemoveLocations()
52 myLevelRemoving = TopAbs_SHAPE;
55 //=======================================================================
58 //=======================================================================
60 Standard_Boolean ShapeUpgrade_RemoveLocations::Remove(const TopoDS_Shape& theShape)
62 TopoDS_Shape aShape = theShape;
64 TopAbs_ShapeEnum shtype = theShape.ShapeType();
65 Standard_Boolean isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE) ||
66 ((Standard_Integer)myLevelRemoving <= ((Standard_Integer)shtype)));
68 Standard_Boolean isDone = MakeNewShape(theShape,S,myShape,isRemoveLoc);
74 //=======================================================================
75 //function : RebuildShape
77 //=======================================================================
78 static Standard_Boolean RebuildShape(const TopoDS_Face& theFace, TopoDS_Face& theNewFace)
82 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace,aLoc);
83 Standard_Boolean isRebuild = Standard_False;
84 if(!aLoc.IsIdentity()) {
85 Handle(Geom_Surface) anewSurf =Handle(Geom_Surface)::DownCast( aSurf->Transformed(aLoc.Transformation()));
86 aB.MakeFace(theNewFace,anewSurf,BRep_Tool::Tolerance(theFace));
87 isRebuild = Standard_True;
91 //=======================================================================
92 //function : RebuildShape
94 //=======================================================================
95 static Standard_Boolean RebuildShape(const TopoDS_Edge& theEdge, TopoDS_Edge& theNewEdge,
96 const TopoDS_Face& theFace, TopoDS_Face& theNewFace,
97 Standard_Boolean isBound)
99 Standard_Boolean isRebuild = Standard_False;
102 Handle(Geom_Curve) C3d;
103 TopLoc_Location aLoc;
104 Standard_Real First3d,Last3d;
105 C3d = BRep_Tool::Curve( theEdge,aLoc,First3d,Last3d);
106 aB.MakeEdge(theNewEdge);
108 if(!aLoc.IsIdentity()) {
109 Handle(Geom_Curve) anewC3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(aLoc.Transformation()));
113 aB.UpdateEdge(theNewEdge,C3d,BRep_Tool::Tolerance(theEdge));
114 aB.Range(theNewEdge,First3d,Last3d);
116 theNewEdge.Orientation(theEdge.Orientation());
117 if(BRep_Tool::Degenerated(theEdge))
118 aB.Degenerated(theNewEdge,Standard_True);
119 isRebuild = Standard_True;
121 if(!theFace.IsNull()) {
122 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace);
123 if(!aSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
124 Handle(Geom2d_Curve) c2d,c2d1;
125 Standard_Real First2d,Last2d;
127 c2d= BRep_Tool::CurveOnSurface( theEdge,theFace,First2d,Last2d);
128 if(BRep_Tool::IsClosed(theEdge,theFace)) {
129 if(!BRep_Tool::IsClosed(theNewEdge,theNewFace)) {
130 TopoDS_Edge tmpE = TopoDS::Edge(theEdge.Reversed());
131 c2d1= BRep_Tool::CurveOnSurface(tmpE,theFace,First2d,Last2d);
132 TopAbs_Orientation OrEdge = theNewEdge.Orientation();
134 if(theFace.Orientation() == TopAbs_REVERSED)
135 OrEdge = ( OrEdge == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD);
137 if(OrEdge == TopAbs_FORWARD)
138 aB.UpdateEdge(theNewEdge,c2d, c2d1,theNewFace,0);
139 else aB.UpdateEdge(theNewEdge,c2d1, c2d,theNewFace,0);
144 aB.UpdateEdge(theNewEdge,c2d,theNewFace,0);
146 if(!c2d.IsNull() || !c2d1.IsNull())
147 aB.Range(theNewEdge,theNewFace,First2d,Last2d);
152 //=======================================================================
153 //function : RebuildShape
155 //=======================================================================
156 static Standard_Boolean RebuildShape(const TopoDS_Vertex& theVertex, TopoDS_Vertex& theNewVertex)
159 aB.MakeVertex(theNewVertex);
160 theNewVertex.Orientation( theVertex.Orientation());
161 gp_Pnt p1 = BRep_Tool::Pnt( theVertex);
162 aB.UpdateVertex(theNewVertex,p1,BRep_Tool::Tolerance( theVertex));
163 return Standard_True;
165 //=======================================================================
166 //function : MakeNewShape
168 //=======================================================================
170 Standard_Boolean ShapeUpgrade_RemoveLocations::MakeNewShape(const TopoDS_Shape& theShape,
171 const TopoDS_Shape& theAncShape,
172 TopoDS_Shape& theNewShape,
173 const Standard_Boolean theRemoveLoc)
175 Standard_Boolean isDone = Standard_False;
176 TopoDS_Shape aNewShape;
177 TopAbs_ShapeEnum shtype = theShape.ShapeType();
179 TopoDS_Shape aShape = theShape;
180 if(!theRemoveLoc && !theShape.Location().IsIdentity()) {
181 TopLoc_Location nulLoc;
182 aShape.Location(nulLoc);
184 Standard_Boolean isBound = myMapNewShapes.IsBound(aShape);
186 aNewShape= myMapNewShapes.Find(aShape);
187 aNewShape.Orientation(theShape.Orientation());
188 if(!theRemoveLoc && !theShape.Location().IsIdentity()) {
189 TopLoc_Location aL = theShape.Location();
190 aNewShape.Location(aL);
192 if(shtype != TopAbs_EDGE) {
193 theNewShape = aNewShape;
194 return Standard_True;
199 Standard_Boolean isRemoveLoc = theRemoveLoc;
201 isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE) ||
202 ((Standard_Integer)myLevelRemoving <= ((Standard_Integer)shtype)));
205 Standard_Boolean aRebuild = Standard_False;
206 TopoDS_Shape anAncShape = theAncShape;
207 if(shtype == TopAbs_FACE)
209 if(isRemoveLoc && (!aShape.Location().IsIdentity() || shtype == TopAbs_EDGE || shtype == TopAbs_FACE )) {
211 //Rebuild geometry for shape with location.
212 if(shtype == TopAbs_FACE) {
213 TopoDS_Face anewFace;
214 TopoDS_Face oldFace = TopoDS::Face(aShape);
215 aRebuild = RebuildShape(oldFace,anewFace);
217 aNewShape = anewFace;
218 myMapNewShapes.Bind(oldFace,aNewShape);
222 else if(shtype == TopAbs_EDGE) {
223 TopoDS_Edge oldEdge = TopoDS::Edge(aShape);
224 TopoDS_Edge anewEdge;
225 TopoDS_Face F,newFace;
227 if(!anAncShape.IsNull()) {
228 F = TopoDS::Face(anAncShape);
230 if(myMapNewShapes.IsBound(F))
231 newFace = TopoDS::Face(myMapNewShapes.Find(F));
234 anewEdge = TopoDS::Edge(aNewShape);
235 aRebuild = RebuildShape(oldEdge,anewEdge,F,newFace,isBound);
236 aNewShape = anewEdge;
239 else if(shtype == TopAbs_VERTEX) {
241 TopoDS_Vertex aV = TopoDS::Vertex(aShape);
242 aRebuild = RebuildShape(aV,aVnew);
249 //Removing location from sub-shapes in dependance of LevelRemoving and re-building shape.
254 aNewShape = theShape.EmptyCopied();
255 // it is safe to simply copy Closed flag since this operation does not change topology
256 aNewShape.Closed (theShape.Closed());
258 TopLoc_Location oldLoc,nullloc;
259 oldLoc = theShape.Location();
260 if(!oldLoc.IsIdentity())
261 aNewShape.Location(nullloc);
262 TopAbs_Orientation orient = theShape.Orientation();
263 aNewShape.Orientation(TopAbs_FORWARD);
264 TopoDS_Iterator aIt(aShape,Standard_False,isRemoveLoc);
265 for( ; aIt.More(); aIt.Next()) {
266 TopoDS_Shape subshape = aIt.Value();
267 TopoDS_Shape anewsubshape;
268 Standard_Boolean isDoneSubShape = MakeNewShape(subshape,anAncShape,anewsubshape,isRemoveLoc);
269 isDone = (isDone || isDoneSubShape);
270 aB.Add(aNewShape,anewsubshape);
273 aNewShape.Orientation(orient);
276 myMapNewShapes.Bind(aShape,aNewShape);
277 if(!theRemoveLoc && !oldLoc.IsIdentity())
278 aNewShape.Location(oldLoc);
281 theNewShape = aNewShape;
283 return (isDone || isBound);