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 <BRep_Builder.hxx>
21 #include <Message_Msg.hxx>
22 #include <Precision.hxx>
23 #include <ShapeBuild_ReShape.hxx>
24 #include <ShapeExtend.hxx>
25 #include <ShapeExtend_BasicMsgRegistrator.hxx>
26 #include <ShapeUpgrade_FaceDivide.hxx>
27 #include <ShapeUpgrade_ShapeDivide.hxx>
28 #include <ShapeUpgrade_WireDivide.hxx>
29 #include <Standard_ErrorHandler.hxx>
30 #include <Standard_Failure.hxx>
32 #include <TopExp_Explorer.hxx>
34 #include <TopoDS_Compound.hxx>
35 #include <TopoDS_Edge.hxx>
36 #include <TopoDS_Iterator.hxx>
37 #include <TopoDS_Shape.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Wire.hxx>
41 //=======================================================================
42 //function : ShapeUpgrade_ShapeDivide
44 //=======================================================================
45 ShapeUpgrade_ShapeDivide::ShapeUpgrade_ShapeDivide() : myStatus(0)
47 myPrecision = myMinTol = Precision::Confusion();
48 myMaxTol = 1; //Precision::Infinite() ?? pdn
49 mySplitFaceTool = new ShapeUpgrade_FaceDivide;
50 myContext = new ShapeBuild_ReShape;
51 //myMsgReg = new ShapeExtend_BasicMsgRegistrator;
52 mySegmentMode = Standard_True;
56 //=======================================================================
57 //function : ShapeUpgrade_ShapeDivide
59 //=======================================================================
61 ShapeUpgrade_ShapeDivide::ShapeUpgrade_ShapeDivide(const TopoDS_Shape &S) : myStatus(0)
63 myPrecision = myMinTol = Precision::Confusion();
64 myMaxTol = 1; //Precision::Infinite() ?? pdn
65 mySplitFaceTool = new ShapeUpgrade_FaceDivide;
66 myContext = new ShapeBuild_ReShape;
67 mySegmentMode = Standard_True;
72 //=======================================================================
75 //=======================================================================
77 void ShapeUpgrade_ShapeDivide::Init(const TopoDS_Shape &S)
82 //=======================================================================
85 //=======================================================================
87 void ShapeUpgrade_ShapeDivide::Delete()
91 //=======================================================================
92 //function : SetPrecision
94 //=======================================================================
96 void ShapeUpgrade_ShapeDivide::SetPrecision (const Standard_Real Prec)
101 //=======================================================================
102 //function : SetMaxTolerance
104 //=======================================================================
106 void ShapeUpgrade_ShapeDivide::SetMaxTolerance (const Standard_Real maxtol)
112 //=======================================================================
113 //function : SetMinTolerance
115 //=======================================================================
117 void ShapeUpgrade_ShapeDivide::SetMinTolerance (const Standard_Real mintol)
123 //=======================================================================
124 //function : SetSurfaceSegmentMode
126 //=======================================================================
128 void ShapeUpgrade_ShapeDivide::SetSurfaceSegmentMode(const Standard_Boolean Segment)
130 mySegmentMode = Segment;
132 //=======================================================================
135 //=======================================================================
137 Standard_Boolean ShapeUpgrade_ShapeDivide::Perform(const Standard_Boolean newContext)
139 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
140 if(myShape.IsNull()) {
141 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
142 return Standard_False;
145 if ( newContext || myContext.IsNull() )
146 myContext = new ShapeBuild_ReShape;
148 // Process COMPOUNDs separately in order to handle sharing in assemblies
149 // NOTE: not optimized: subshape can be processed twice (second time - no modif)
150 if ( myShape.ShapeType() == TopAbs_COMPOUND ) {
151 Standard_Integer locStatus = myStatus;
154 B.MakeCompound ( C );
155 TopoDS_Shape savShape = myShape;
156 for ( TopoDS_Iterator it(savShape,Standard_False); it.More(); it.Next() ) {
157 TopoDS_Shape shape = it.Value();
158 TopLoc_Location L = shape.Location();
159 if(myContext->ModeConsiderLocation()) {
160 TopLoc_Location nullLoc;
161 shape.Location ( nullLoc );
163 myShape = myContext->Apply ( shape );
164 Perform ( Standard_False );
165 if(myContext->ModeConsiderLocation())
166 myResult.Location ( L );
167 myResult.Orientation(TopAbs::Compose(myResult.Orientation(),savShape.Orientation()));
168 B.Add ( C, myResult );
169 locStatus |= myStatus;
173 myStatus = locStatus;
174 if ( Status ( ShapeExtend_DONE ) ) {
175 myResult = myContext->Apply ( C, TopAbs_SHAPE );
176 myContext->Replace ( myShape, myResult );
177 return Standard_True;
180 return Standard_False;
184 Handle(ShapeUpgrade_FaceDivide) SplitFace = GetSplitFaceTool();
185 if ( ! SplitFace.IsNull() ) {
186 SplitFace->SetPrecision( myPrecision );
187 SplitFace->SetMaxTolerance(myMaxTol);
188 SplitFace->SetSurfaceSegmentMode(mySegmentMode);
189 Handle(ShapeUpgrade_WireDivide) SplitWire = SplitFace->GetWireDivideTool();
190 if ( ! SplitWire.IsNull() ) {
191 SplitWire->SetMinTolerance(myMinTol);
192 SplitWire->SetEdgeMode(myEdgeMode);
194 Message_Msg doneMsg = GetFaceMsg();
196 for(TopExp_Explorer exp(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
198 TopoDS_Shape tmpF = exp.Current().Oriented ( TopAbs_FORWARD );
199 TopoDS_Face F = TopoDS::Face (tmpF); // protection against INTERNAL shapes: cts20105a.rle
200 TopoDS_Shape sh = myContext->Apply ( F, TopAbs_SHAPE );
201 for (TopExp_Explorer exp2(sh,TopAbs_FACE); exp2.More(); exp2.Next()) {
202 //szv: try-catch added
205 for (; exp2.More(); exp2.Next()) {
206 TopoDS_Face face = TopoDS::Face ( exp2.Current() );
207 SplitFace->Init(face);
208 SplitFace->SetContext(myContext);
209 SplitFace->Perform();
210 if(SplitFace->Status(ShapeExtend_FAIL)) {
211 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
213 if(SplitFace->Status(ShapeExtend_DONE)) {
214 myContext->Replace(face,SplitFace->Result());
215 SendMsg( face, doneMsg, Message_Info );
216 if(SplitFace->Status(ShapeExtend_DONE1))
217 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
218 if(SplitFace->Status(ShapeExtend_DONE2))
219 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
223 catch (Standard_Failure) {
224 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
226 cout << "\nError: Exception in ShapeUpgrade_FaceDivide::Perform(): ";
227 Standard_Failure::Caught()->Print(cout); cout << endl;
234 // Process free WIREs
235 Handle(ShapeUpgrade_WireDivide) SplitWire = SplitFace->GetWireDivideTool();
236 if ( ! SplitWire.IsNull() ) {
237 SplitWire->SetFace (TopoDS_Face());
238 SplitWire->SetPrecision( myPrecision );
239 SplitWire->SetMaxTolerance(myMaxTol);
240 SplitWire->SetMinTolerance(myMinTol);
241 SplitWire->SetEdgeMode(myEdgeMode);
242 Message_Msg doneMsg = GetWireMsg();
244 TopExp_Explorer exp;//svv Jan 10 2000 : porting on DEC
245 for (exp.Init (myShape, TopAbs_WIRE, TopAbs_FACE); exp.More(); exp.Next()) {
247 TopoDS_Shape tmpW = exp.Current().Oriented ( TopAbs_FORWARD );
248 TopoDS_Wire W = TopoDS::Wire (tmpW ); // protection against INTERNAL shapes
249 TopoDS_Shape sh = myContext->Apply ( W, TopAbs_SHAPE );
250 for (TopExp_Explorer exp2 (sh,TopAbs_WIRE); exp2.More(); exp2.Next()) {
251 TopoDS_Wire wire = TopoDS::Wire ( exp2.Current() );
252 SplitWire->Load (wire);
253 SplitWire->SetContext(myContext);
254 SplitWire->Perform();
255 if(SplitWire->Status(ShapeExtend_FAIL)) {
256 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 );
258 if(SplitWire->Status(ShapeExtend_DONE)) {
259 myContext->Replace(wire,SplitWire->Wire());
260 SendMsg( wire, doneMsg, Message_Info );
261 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
266 // Process free EDGEs
267 Message_Msg edgeDoneMsg = GetEdgeMsg();
268 for (exp.Init (myShape, TopAbs_EDGE, TopAbs_WIRE); exp.More(); exp.Next()) {
270 TopoDS_Shape tmpE = exp.Current().Oriented ( TopAbs_FORWARD );
271 TopoDS_Edge E = TopoDS::Edge (tmpE ); // protection against INTERNAL shapes
273 TopExp::Vertices(E,V2,V1);
274 if( V1.IsNull() && V2.IsNull() ) continue; // skl 27.10.2004 for OCC5624
275 TopoDS_Shape sh = myContext->Apply ( E, TopAbs_SHAPE );
276 for (TopExp_Explorer exp2 (sh,TopAbs_EDGE); exp2.More(); exp2.Next()) {
277 TopoDS_Edge edge = TopoDS::Edge ( exp2.Current() );
278 SplitWire->Load (edge);
279 SplitWire->SetContext(myContext);
280 SplitWire->Perform();
281 if(SplitWire->Status(ShapeExtend_FAIL)) {
282 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 );
284 if(SplitWire->Status(ShapeExtend_DONE)) {
285 myContext->Replace(edge,SplitWire->Wire());
286 SendMsg( edge, edgeDoneMsg, Message_Info );
287 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
292 myResult = myContext->Apply ( myShape, TopAbs_SHAPE );
293 return ! myResult.IsSame ( myShape );
296 //=======================================================================
299 //=======================================================================
301 TopoDS_Shape ShapeUpgrade_ShapeDivide::Result() const
306 //=======================================================================
307 //function : GetContext
309 //=======================================================================
311 Handle(ShapeBuild_ReShape) ShapeUpgrade_ShapeDivide::GetContext() const
313 //if ( myContext.IsNull() ) myContext = new ShapeBuild_ReShape;
317 //=======================================================================
318 //function : SetContext
320 //=======================================================================
322 void ShapeUpgrade_ShapeDivide::SetContext (const Handle(ShapeBuild_ReShape) &context)
327 //=======================================================================
328 //function : SetSplitFaceTool
330 //=======================================================================
332 void ShapeUpgrade_ShapeDivide::SetSplitFaceTool(const Handle(ShapeUpgrade_FaceDivide)& splitFaceTool)
334 mySplitFaceTool = splitFaceTool;
337 //=======================================================================
338 //function : GetSplitFaceTool
340 //=======================================================================
342 Handle(ShapeUpgrade_FaceDivide) ShapeUpgrade_ShapeDivide::GetSplitFaceTool () const
344 return mySplitFaceTool;
347 //=======================================================================
350 //=======================================================================
352 Standard_Boolean ShapeUpgrade_ShapeDivide::Status (const ShapeExtend_Status status) const
354 return ShapeExtend::DecodeStatus ( myStatus, status );
357 //=======================================================================
358 //function : SetEdgeMode
360 //=======================================================================
362 void ShapeUpgrade_ShapeDivide::SetEdgeMode(const Standard_Integer aEdgeMode)
364 myEdgeMode = aEdgeMode;
367 //=======================================================================
368 //function : SetMsgRegistrator
370 //=======================================================================
372 void ShapeUpgrade_ShapeDivide::SetMsgRegistrator(const Handle(ShapeExtend_BasicMsgRegistrator)& msgreg)
377 //=======================================================================
378 //function : MsgRegistrator
380 //=======================================================================
382 Handle(ShapeExtend_BasicMsgRegistrator) ShapeUpgrade_ShapeDivide::MsgRegistrator() const
387 //=======================================================================
390 //=======================================================================
392 void ShapeUpgrade_ShapeDivide::SendMsg(const TopoDS_Shape& shape,
393 const Message_Msg& message,
394 const Message_Gravity gravity) const
396 if ( !myMsgReg.IsNull() )
397 myMsgReg->Send (shape, message, gravity);
400 Message_Msg ShapeUpgrade_ShapeDivide::GetFaceMsg() const
402 return "ShapeDivide.FaceDivide.MSG0";
404 Message_Msg ShapeUpgrade_ShapeDivide::GetWireMsg() const
406 return "ShapeDivide.WireDivide.MSG0";
408 Message_Msg ShapeUpgrade_ShapeDivide::GetEdgeMsg() const
410 return "ShapeDivide.EdgeDivide.MSG0";