0026489: The class ShapeUpgrade_UnifySameDomain provides the results that are wrong...
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_RemoveLocations.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 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
973c2be1 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.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
42cf5bc1 14
7fd59977 15#include <BRep_Builder.hxx>
42cf5bc1 16#include <BRep_CurveRepresentation.hxx>
17#include <BRep_GCurve.hxx>
18#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
19#include <BRep_TEdge.hxx>
7fd59977 20#include <BRep_Tool.hxx>
7fd59977 21#include <Geom2d_Curve.hxx>
42cf5bc1 22#include <Geom_Curve.hxx>
7fd59977 23#include <Geom_Geometry.hxx>
42cf5bc1 24#include <Geom_Plane.hxx>
25#include <Geom_Surface.hxx>
26#include <gp_Pnt.hxx>
7fd59977 27#include <gp_Trsf.hxx>
42cf5bc1 28#include <ShapeBuild_Edge.hxx>
29#include <ShapeUpgrade_RemoveLocations.hxx>
30#include <Standard_Type.hxx>
7fd59977 31#include <TColStd_ListIteratorOfListOfTransient.hxx>
7fd59977 32#include <TColStd_ListOfTransient.hxx>
42cf5bc1 33#include <TopAbs_ShapeEnum.hxx>
34#include <TopExp.hxx>
35#include <TopExp_Explorer.hxx>
36#include <TopLoc_Location.hxx>
37#include <TopoDS.hxx>
38#include <TopoDS_Edge.hxx>
39#include <TopoDS_Face.hxx>
40#include <TopoDS_Iterator.hxx>
41#include <TopoDS_Shape.hxx>
42#include <TopoDS_Vertex.hxx>
43#include <TopTools_DataMapOfShapeShape.hxx>
b311480e 44
42cf5bc1 45//#include <ShapeUpgrade_DataMapOfShapeListOfTransient.hxx>
7fd59977 46//=======================================================================
47//function : ShapeUpgrade_RemoveLocations
48//purpose :
49//=======================================================================
7fd59977 50ShapeUpgrade_RemoveLocations::ShapeUpgrade_RemoveLocations()
51{
52 myLevelRemoving = TopAbs_SHAPE;
53}
54
55//=======================================================================
56//function : Remove
57//purpose :
58//=======================================================================
59
60 Standard_Boolean ShapeUpgrade_RemoveLocations::Remove(const TopoDS_Shape& theShape)
61{
62 TopoDS_Shape aShape = theShape;
63 myShape = aShape;
64 TopAbs_ShapeEnum shtype = theShape.ShapeType();
65 Standard_Boolean isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE) ||
66 ((Standard_Integer)myLevelRemoving <= ((Standard_Integer)shtype)));
67 TopoDS_Shape S;
68 Standard_Boolean isDone = MakeNewShape(theShape,S,myShape,isRemoveLoc);
69
70 return isDone;
71
72}
73
74//=======================================================================
75//function : RebuildShape
76//purpose :
77//=======================================================================
78static Standard_Boolean RebuildShape(const TopoDS_Face& theFace, TopoDS_Face& theNewFace)
79{
80 BRep_Builder aB;
81 TopLoc_Location aLoc;
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;
88 }
89 return isRebuild;
90}
91//=======================================================================
92//function : RebuildShape
93//purpose :
94//=======================================================================
95static Standard_Boolean RebuildShape(const TopoDS_Edge& theEdge, TopoDS_Edge& theNewEdge,
96 const TopoDS_Face& theFace, TopoDS_Face& theNewFace,
97 Standard_Boolean isBound)
98{
99 Standard_Boolean isRebuild = Standard_False;
100 BRep_Builder aB;
101 if(!isBound) {
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);
107 if(!C3d.IsNull()) {
108 if(!aLoc.IsIdentity()) {
109 Handle(Geom_Curve) anewC3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(aLoc.Transformation()));
110 C3d = anewC3d;
111 }
112
113 aB.UpdateEdge(theNewEdge,C3d,BRep_Tool::Tolerance(theEdge));
114 aB.Range(theNewEdge,First3d,Last3d);
115 }
116 theNewEdge.Orientation(theEdge.Orientation());
117 if(BRep_Tool::Degenerated(theEdge))
118 aB.Degenerated(theNewEdge,Standard_True);
119 isRebuild = Standard_True;
120 }
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;
126
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();
133
982a90fc 134 if(theFace.Orientation() == TopAbs_REVERSED)
7fd59977 135 OrEdge = ( OrEdge == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD);
136
137 if(OrEdge == TopAbs_FORWARD)
138 aB.UpdateEdge(theNewEdge,c2d, c2d1,theNewFace,0);
139 else aB.UpdateEdge(theNewEdge,c2d1, c2d,theNewFace,0);
140
141 }
142 }
143 else
144 aB.UpdateEdge(theNewEdge,c2d,theNewFace,0);
145
146 if(!c2d.IsNull() || !c2d1.IsNull())
147 aB.Range(theNewEdge,theNewFace,First2d,Last2d);
148 }
149 }
150 return isRebuild;
151}
152//=======================================================================
153//function : RebuildShape
154//purpose :
155//=======================================================================
156static Standard_Boolean RebuildShape(const TopoDS_Vertex& theVertex, TopoDS_Vertex& theNewVertex)
157{
158 BRep_Builder aB;
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;
164}
165//=======================================================================
166//function : MakeNewShape
167//purpose :
168//=======================================================================
169
170Standard_Boolean ShapeUpgrade_RemoveLocations::MakeNewShape(const TopoDS_Shape& theShape,
171 const TopoDS_Shape& theAncShape,
172 TopoDS_Shape& theNewShape,
173 const Standard_Boolean theRemoveLoc)
174{
175 Standard_Boolean isDone = Standard_False;
176 TopoDS_Shape aNewShape;
177 TopAbs_ShapeEnum shtype = theShape.ShapeType();
178 BRep_Builder aB;
179 TopoDS_Shape aShape = theShape;
180 if(!theRemoveLoc && !theShape.Location().IsIdentity()) {
181 TopLoc_Location nulLoc;
182 aShape.Location(nulLoc);
183 }
184 Standard_Boolean isBound = myMapNewShapes.IsBound(aShape);
185 if(isBound) {
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);
191 }
192 if(shtype != TopAbs_EDGE) {
7fd59977 193 theNewShape = aNewShape;
ab860031 194 return Standard_True;
195 }
7fd59977 196 }
197
198
199 Standard_Boolean isRemoveLoc = theRemoveLoc;
200 if(!theRemoveLoc) {
201 isRemoveLoc = ((shtype != TopAbs_COMPOUND && myLevelRemoving == TopAbs_SHAPE) ||
202 ((Standard_Integer)myLevelRemoving <= ((Standard_Integer)shtype)));
203 }
204
205 Standard_Boolean aRebuild = Standard_False;
206 TopoDS_Shape anAncShape = theAncShape;
207 if(shtype == TopAbs_FACE)
208 anAncShape = aShape;
209 if(isRemoveLoc && (!aShape.Location().IsIdentity() || shtype == TopAbs_EDGE || shtype == TopAbs_FACE )) {
210
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);
216 if(aRebuild) {
217 aNewShape = anewFace;
218 myMapNewShapes.Bind(oldFace,aNewShape);
219 }
220
221 }
222 else if(shtype == TopAbs_EDGE) {
223 TopoDS_Edge oldEdge = TopoDS::Edge(aShape);
224 TopoDS_Edge anewEdge;
225 TopoDS_Face F,newFace;
226
227 if(!anAncShape.IsNull()) {
228 F = TopoDS::Face(anAncShape);
229 newFace = F;
230 if(myMapNewShapes.IsBound(F))
231 newFace = TopoDS::Face(myMapNewShapes.Find(F));
232 }
233 if(isBound)
234 anewEdge = TopoDS::Edge(aNewShape);
235 aRebuild = RebuildShape(oldEdge,anewEdge,F,newFace,isBound);
236 aNewShape = anewEdge;
237
238 }
239 else if(shtype == TopAbs_VERTEX) {
240 TopoDS_Vertex aVnew;
241 TopoDS_Vertex aV = TopoDS::Vertex(aShape);
242 aRebuild = RebuildShape(aV,aVnew);
243 if(aRebuild)
244 aNewShape = aVnew;
245 }
246 }
247 isDone = aRebuild;
248
249 //Removing location from sub-shapes in dependance of LevelRemoving and re-building shape.
250
251 if(!isBound) {
ab860031 252 if(!aRebuild)
253 {
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());
257 }
7fd59977 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);
7fd59977 271 }
272 if(isDone)
273 aNewShape.Orientation(orient);
ab860031 274 else
275 aNewShape = aShape;
7fd59977 276 myMapNewShapes.Bind(aShape,aNewShape);
277 if(!theRemoveLoc && !oldLoc.IsIdentity())
278 aNewShape.Location(oldLoc);
279
280 }
281 theNewShape = aNewShape;
ab860031 282
7fd59977 283 return (isDone || isBound);
284}
285