1 // Created on: 1999-04-27
2 // Created by: Pavel DURANDIN
3 // Copyright (c) 1999-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.
17 // abv 16.06.99 returning ReShape context; processing shared subshapes in compounds
18 // sln 29.11.01 Bug21: in method Perform(..) nullify location of compound's faces only if mode myConsiderLocation is on
20 #include <ShapeUpgrade_ShapeDivide.ixx>
21 #include <Precision.hxx>
22 #include <ShapeExtend.hxx>
23 #include <ShapeBuild_ReShape.hxx>
24 #include <TopExp_Explorer.hxx>
27 #include <TopoDS_Edge.hxx>
28 #include <TopoDS_Wire.hxx>
29 #include <TopoDS_Compound.hxx>
30 #include <TopoDS_Iterator.hxx>
31 #include <TopoDS_Vertex.hxx>
32 #include <BRep_Builder.hxx>
33 #include <ShapeUpgrade_WireDivide.hxx>
34 #include <Standard_ErrorHandler.hxx>
35 #include <Standard_Failure.hxx>
37 //=======================================================================
38 //function : ShapeUpgrade_ShapeDivide
40 //=======================================================================
42 ShapeUpgrade_ShapeDivide::ShapeUpgrade_ShapeDivide() : myStatus(0)
44 myPrecision = myMinTol = Precision::Confusion();
45 myMaxTol = 1; //Precision::Infinite() ?? pdn
46 mySplitFaceTool = new ShapeUpgrade_FaceDivide;
47 myContext = new ShapeBuild_ReShape;
48 mySegmentMode = Standard_True;
52 //=======================================================================
53 //function : ShapeUpgrade_ShapeDivide
55 //=======================================================================
57 ShapeUpgrade_ShapeDivide::ShapeUpgrade_ShapeDivide(const TopoDS_Shape &S) : myStatus(0)
59 myPrecision = myMinTol = Precision::Confusion();
60 myMaxTol = 1; //Precision::Infinite() ?? pdn
61 mySplitFaceTool = new ShapeUpgrade_FaceDivide;
62 myContext = new ShapeBuild_ReShape;
63 mySegmentMode = Standard_True;
68 //=======================================================================
71 //=======================================================================
73 void ShapeUpgrade_ShapeDivide::Init(const TopoDS_Shape &S)
78 //=======================================================================
81 //=======================================================================
83 void ShapeUpgrade_ShapeDivide::Delete()
87 //=======================================================================
88 //function : SetPrecision
90 //=======================================================================
92 void ShapeUpgrade_ShapeDivide::SetPrecision (const Standard_Real Prec)
97 //=======================================================================
98 //function : SetMaxTolerance
100 //=======================================================================
102 void ShapeUpgrade_ShapeDivide::SetMaxTolerance (const Standard_Real maxtol)
108 //=======================================================================
109 //function : SetMinTolerance
111 //=======================================================================
113 void ShapeUpgrade_ShapeDivide::SetMinTolerance (const Standard_Real mintol)
119 //=======================================================================
120 //function : SetSurfaceSegmentMode
122 //=======================================================================
124 void ShapeUpgrade_ShapeDivide::SetSurfaceSegmentMode(const Standard_Boolean Segment)
126 mySegmentMode = Segment;
128 //=======================================================================
131 //=======================================================================
133 Standard_Boolean ShapeUpgrade_ShapeDivide::Perform(const Standard_Boolean newContext)
135 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
136 if(myShape.IsNull()) {
137 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
138 return Standard_False;
141 if ( newContext || myContext.IsNull() )
142 myContext = new ShapeBuild_ReShape;
144 // Process COMPOUNDs separately in order to handle sharing in assemblies
145 // NOTE: not optimized: subshape can be processed twice (second time - no modif)
146 if ( myShape.ShapeType() == TopAbs_COMPOUND ) {
147 Standard_Integer locStatus = myStatus;
150 B.MakeCompound ( C );
151 TopoDS_Shape savShape = myShape;
152 for ( TopoDS_Iterator it(savShape,Standard_False); it.More(); it.Next() ) {
153 TopoDS_Shape shape = it.Value();
154 TopLoc_Location L = shape.Location();
155 if(myContext->ModeConsiderLocation()) {
156 TopLoc_Location nullLoc;
157 shape.Location ( nullLoc );
159 myShape = myContext->Apply ( shape );
160 Perform ( Standard_False );
161 if(myContext->ModeConsiderLocation())
162 myResult.Location ( L );
163 myResult.Orientation(TopAbs::Compose(myResult.Orientation(),savShape.Orientation()));
164 B.Add ( C, myResult );
165 locStatus |= myStatus;
169 myStatus = locStatus;
170 if ( Status ( ShapeExtend_DONE ) ) {
171 myResult = myContext->Apply ( C, TopAbs_SHAPE );
172 myContext->Replace ( myShape, myResult );
173 return Standard_True;
176 return Standard_False;
180 Handle(ShapeUpgrade_FaceDivide) SplitFace = GetSplitFaceTool();
181 if ( ! SplitFace.IsNull() ) {
182 SplitFace->SetPrecision( myPrecision );
183 SplitFace->SetMaxTolerance(myMaxTol);
184 SplitFace->SetSurfaceSegmentMode(mySegmentMode);
185 Handle(ShapeUpgrade_WireDivide) SplitWire = SplitFace->GetWireDivideTool();
186 if ( ! SplitWire.IsNull() ) {
187 SplitWire->SetMinTolerance(myMinTol);
188 SplitWire->SetEdgeMode(myEdgeMode);
190 for(TopExp_Explorer exp(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
192 TopoDS_Shape tmpF = exp.Current().Oriented ( TopAbs_FORWARD );
193 TopoDS_Face F = TopoDS::Face (tmpF); // protection against INTERNAL shapes: cts20105a.rle
194 TopoDS_Shape sh = myContext->Apply ( F, TopAbs_SHAPE );
195 for (TopExp_Explorer exp2(sh,TopAbs_FACE); exp2.More(); exp2.Next()) {
196 //szv: try-catch added
199 for (; exp2.More(); exp2.Next()) {
200 TopoDS_Face face = TopoDS::Face ( exp2.Current() );
201 SplitFace->Init(face);
202 SplitFace->SetContext(myContext);
203 SplitFace->Perform();
204 if(SplitFace->Status(ShapeExtend_FAIL)) {
205 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
207 if(SplitFace->Status(ShapeExtend_DONE)) {
208 myContext->Replace(face,SplitFace->Result());
209 if(SplitFace->Status(ShapeExtend_DONE1))
210 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
211 if(SplitFace->Status(ShapeExtend_DONE2))
212 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
216 catch (Standard_Failure) {
217 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
219 cout << "\nError: Exception in ShapeUpgrade_FaceDivide::Perform(): ";
220 Standard_Failure::Caught()->Print(cout); cout << endl;
227 // Process free WIREs
228 Handle(ShapeUpgrade_WireDivide) SplitWire = SplitFace->GetWireDivideTool();
229 if ( ! SplitWire.IsNull() ) {
230 SplitWire->SetFace (TopoDS_Face());
231 SplitWire->SetPrecision( myPrecision );
232 SplitWire->SetMaxTolerance(myMaxTol);
233 SplitWire->SetMinTolerance(myMinTol);
234 SplitWire->SetEdgeMode(myEdgeMode);
235 TopExp_Explorer exp;//svv Jan 10 2000 : porting on DEC
236 for (exp.Init (myShape, TopAbs_WIRE, TopAbs_FACE); exp.More(); exp.Next()) {
238 TopoDS_Shape tmpW = exp.Current().Oriented ( TopAbs_FORWARD );
239 TopoDS_Wire W = TopoDS::Wire (tmpW ); // protection against INTERNAL shapes
240 TopoDS_Shape sh = myContext->Apply ( W, TopAbs_SHAPE );
241 for (TopExp_Explorer exp2 (sh,TopAbs_WIRE); exp2.More(); exp2.Next()) {
242 TopoDS_Wire wire = TopoDS::Wire ( exp2.Current() );
243 SplitWire->Load (wire);
244 SplitWire->SetContext(myContext);
245 SplitWire->Perform();
246 if(SplitWire->Status(ShapeExtend_FAIL)) {
247 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 );
249 if(SplitWire->Status(ShapeExtend_DONE)) {
250 myContext->Replace(wire,SplitWire->Wire());
251 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
256 // Process free EDGEs
257 for (exp.Init (myShape, TopAbs_EDGE, TopAbs_WIRE); exp.More(); exp.Next()) {
259 TopoDS_Shape tmpE = exp.Current().Oriented ( TopAbs_FORWARD );
260 TopoDS_Edge E = TopoDS::Edge (tmpE ); // protection against INTERNAL shapes
262 TopExp::Vertices(E,V2,V1);
263 if( V1.IsNull() && V2.IsNull() ) continue; // skl 27.10.2004 for OCC5624
264 TopoDS_Shape sh = myContext->Apply ( E, TopAbs_SHAPE );
265 for (TopExp_Explorer exp2 (sh,TopAbs_EDGE); exp2.More(); exp2.Next()) {
266 TopoDS_Edge edge = TopoDS::Edge ( exp2.Current() );
267 SplitWire->Load (edge);
268 SplitWire->SetContext(myContext);
269 SplitWire->Perform();
270 if(SplitWire->Status(ShapeExtend_FAIL)) {
271 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 );
273 if(SplitWire->Status(ShapeExtend_DONE)) {
274 myContext->Replace(edge,SplitWire->Wire());
275 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
280 myResult = myContext->Apply ( myShape, TopAbs_SHAPE );
281 return ! myResult.IsSame ( myShape );
284 //=======================================================================
287 //=======================================================================
289 TopoDS_Shape ShapeUpgrade_ShapeDivide::Result() const
294 //=======================================================================
295 //function : GetContext
297 //=======================================================================
299 Handle(ShapeBuild_ReShape) ShapeUpgrade_ShapeDivide::GetContext() const
301 //if ( myContext.IsNull() ) myContext = new ShapeBuild_ReShape;
305 //=======================================================================
306 //function : SetContext
308 //=======================================================================
310 void ShapeUpgrade_ShapeDivide::SetContext (const Handle(ShapeBuild_ReShape) &context)
315 //=======================================================================
316 //function : SetSplitFaceTool
318 //=======================================================================
320 void ShapeUpgrade_ShapeDivide::SetSplitFaceTool(const Handle(ShapeUpgrade_FaceDivide)& splitFaceTool)
322 mySplitFaceTool = splitFaceTool;
325 //=======================================================================
326 //function : GetSplitFaceTool
328 //=======================================================================
330 Handle(ShapeUpgrade_FaceDivide) ShapeUpgrade_ShapeDivide::GetSplitFaceTool () const
332 return mySplitFaceTool;
335 //=======================================================================
338 //=======================================================================
340 Standard_Boolean ShapeUpgrade_ShapeDivide::Status (const ShapeExtend_Status status) const
342 return ShapeExtend::DecodeStatus ( myStatus, status );
345 //=======================================================================
346 //function : SetEdgeMode
348 //=======================================================================
350 void ShapeUpgrade_ShapeDivide::SetEdgeMode(const Standard_Integer aEdgeMode)
352 myEdgeMode = aEdgeMode;