1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : AdvancedEngine_IOperations.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 #include "AdvancedEngine_IOperations.hxx"
23 #include "AdvancedEngine_PipeTShapeDriver.hxx"
24 #include "AdvancedEngine_IPipeTShape.hxx"
25 #include "AdvancedEngine_DividedDiskDriver.hxx"
26 #include "AdvancedEngine_IDividedDisk.hxx"
27 #include "AdvancedEngine_SmoothingSurfaceDriver.hxx"
28 #include "AdvancedEngine_ISmoothingSurface.hxx"
30 #include <Basics_OCCTVersion.hxx>
32 #include <utilities.h>
34 #include <Utils_ExceptHandlers.hxx>
36 #include "GEOM_Function.hxx"
37 #include "GEOM_PythonDump.hxx"
38 #include "GEOMUtils.hxx"
39 #include "GEOMAlgo_ClsfSurf.hxx"
40 #include "GEOMAlgo_FinderShapeOn2.hxx"
41 #include "GEOMAlgo_Splitter.hxx"
43 #include "GEOMImpl_Gen.hxx"
44 #include "GEOMImpl_Types.hxx"
46 #include "GEOMImpl_IBasicOperations.hxx"
47 #include "GEOMImpl_IBooleanOperations.hxx"
48 #include "GEOMImpl_IShapesOperations.hxx"
49 #include "GEOMImpl_ITransformOperations.hxx"
50 #include "GEOMImpl_IBlocksOperations.hxx"
51 #include "GEOMImpl_I3DPrimOperations.hxx"
52 #include "GEOMImpl_ILocalOperations.hxx"
53 #include "GEOMImpl_IHealingOperations.hxx"
54 #include "GEOMImpl_IGroupOperations.hxx"
55 #include "GEOMImpl_GlueDriver.hxx"
57 #include <TDF_Tool.hxx>
58 #include <TFunction_DriverTable.hxx>
59 #include <TFunction_Driver.hxx>
60 #include <TFunction_Logbook.hxx>
61 #include <TNaming_CopyShape.hxx>
64 #include <TopExp_Explorer.hxx>
66 #include <TopoDS_Vertex.hxx>
67 #include <TopTools_IndexedMapOfShape.hxx>
68 #include <TopTools_ListIteratorOfListOfShape.hxx>
69 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
71 #include <BRep_Builder.hxx>
72 #include <BRep_Tool.hxx>
74 #include <BRepAdaptor_Surface.hxx>
75 #include <BRepAlgoAPI_Cut.hxx>
76 #include <BRepAlgoAPI_Fuse.hxx>
77 #include <BRepBuilderAPI_MakeFace.hxx>
78 #include <BRepBuilderAPI_MakeVertex.hxx>
79 #include <BRepBuilderAPI_Transform.hxx>
80 #include <BRepPrimAPI_MakeCone.hxx>
81 #include <BRepPrimAPI_MakeCylinder.hxx>
87 #include <GC_MakeConicalSurface.hxx>
88 #include <Geom_CylindricalSurface.hxx>
90 #include <ShapeAnalysis_Edge.hxx>
94 #include "AdvancedEngine_Types.hxx"
96 #include <Standard_Stream.hxx>
97 #include <Standard_Failure.hxx>
98 #include <StdFail_NotDone.hxx>
99 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
101 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
102 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
103 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
104 #define THICKNESS "Thickness" //"Epaisseur"
105 #define FLANGE "Flange" // "Collerette"
106 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
107 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
108 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
109 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
111 #define FIND_GROUPS_BY_POINTS 1
113 // Undefine below macro to enable workaround about fillet problem in MakePipeTShapeFillet
114 // VSR 30/12/2014: macro enabled
115 #define FILLET_FIX_TOLERANCE
117 //=============================================================================
121 //=============================================================================
122 AdvancedEngine_IOperations::AdvancedEngine_IOperations(GEOM_Engine* theEngine, int theDocID) :
123 GEOM_IOperations(theEngine, theDocID)
125 MESSAGE("AdvancedEngine_IOperations::AdvancedEngine_IOperations");
126 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
127 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
128 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
129 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
130 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
131 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
132 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
133 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
134 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
137 //=============================================================================
141 //=============================================================================
142 AdvancedEngine_IOperations::~AdvancedEngine_IOperations()
144 MESSAGE("AdvancedEngine_IOperations::~AdvancedEngine_IOperations");
145 delete myBasicOperations;
146 delete myBooleanOperations;
147 delete myShapesOperations;
148 delete myTransformOperations;
149 delete myBlocksOperations;
150 delete my3DPrimOperations;
151 delete myLocalOperations;
152 delete myHealingOperations;
153 delete myGroupOperations;
156 //=============================================================================
160 //=============================================================================
161 gp_Trsf AdvancedEngine_IOperations::GetPositionTrsf(double theL1, double theL2,
162 Handle(GEOM_Object) theP1,
163 Handle(GEOM_Object) theP2,
164 Handle(GEOM_Object) theP3)
166 // Old Local Coordinates System oldLCS
168 gp_Pnt P1(-theL1, 0, 0);
169 gp_Pnt P2(theL1, 0, 0);
170 gp_Pnt P3(0, 0, theL2);
172 gp_Dir oldX(gp_Vec(P1, P2));
173 gp_Dir oldZ(gp_Vec(P0, P3));
174 gp_Ax3 oldLCS(P0, oldZ, oldX);
176 // New Local Coordinates System newLCS
177 double LocX, LocY, LocZ;
178 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
179 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
180 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
181 LocX = (newP1.X() + newP2.X()) / 2.;
182 LocY = (newP1.Y() + newP2.Y()) / 2.;
183 LocZ = (newP1.Z() + newP2.Z()) / 2.;
184 gp_Pnt newO(LocX, LocY, LocZ);
186 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
187 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
188 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
191 aTrsf.SetDisplacement(oldLCS, newLCS);
196 //=============================================================================
198 * CheckCompatiblePosition
201 //=============================================================================
202 bool AdvancedEngine_IOperations::CheckCompatiblePosition(double& theL1, double& theL2,
203 Handle(GEOM_Object) theP1,
204 Handle(GEOM_Object) theP2,
205 Handle(GEOM_Object) theP3,
209 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
210 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
211 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
213 double d12 = P1.Distance(P2);
214 double d13 = P1.Distance(P3);
215 double d23 = P2.Distance(P3);
216 // double d2 = newO.Distance(P3);
218 if (Abs(d12) <= Precision::Confusion()) {
219 SetErrorCode("Junctions points P1 and P2 are identical");
222 if (Abs(d13) <= Precision::Confusion()) {
223 SetErrorCode("Junctions points P1 and P3 are identical");
226 if (Abs(d23) <= Precision::Confusion()) {
227 SetErrorCode("Junctions points P2 and P3 are identical");
232 double newL1 = 0.5 * d12;
233 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
235 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
237 if (fabs(newL1 - theL1) > Precision::Approximation()) {
238 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
239 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
240 // std::cerr << "theL1 = newL1" << std::endl;
244 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
250 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
252 if (fabs(newL2 - theL2) > Precision::Approximation()) {
253 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
254 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
258 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
268 //=============================================================================
270 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
272 //=============================================================================
273 bool AdvancedEngine_IOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
274 double theR1, double theW1, double theL1,
275 double theR2, double theW2, double theL2,
276 double theH, double theW, double theRF,
277 Handle(TColStd_HSequenceOfTransient) theSeq,
282 if (theShape.IsNull()) return false;
284 TopoDS_Shape aShape = theShape->GetValue();
285 if (aShape.IsNull()) {
286 SetErrorCode("Shape is not defined");
290 gp_Trsf aTrsfInv = aTrsf.Inverted();
292 // int expectedGroups = 0;
293 // if (shapeType == TSHAPE_BASIC)
294 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
295 // expectedGroups = 10;
297 // expectedGroups = 11;
298 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
299 // expectedGroups = 12;
301 double aR1Ext = theR1 + theW1;
302 double aR2Ext = theR2 + theW2;
304 /////////////////////////
305 //// Groups of Faces ////
306 /////////////////////////
309 // Comment the following lines when GetInPlace bug is solved
311 // Workaround of GetInPlace bug
312 // Create a bounding box that fits the shape
313 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
314 aBox->GetLastFunction()->SetDescription("");
315 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
316 aBox->GetLastFunction()->SetDescription("");
317 // Apply transformation to box
318 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
319 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
320 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
322 // Get the shell of the box
323 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
324 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
325 aBox->GetLastFunction()->SetDescription("");
326 aShell->GetLastFunction()->SetDescription("");
327 // Get the common shapes between shell and shape
328 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean
329 (theShape, aShell, 1, Standard_False); // MakeCommon
330 if (aCommonCompound.IsNull()) {
331 SetErrorCode(myBooleanOperations->GetErrorCode());
334 aCommonCompound->GetLastFunction()->SetDescription("");
335 // Explode the faces of common shapes => 3 faces
336 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
337 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
338 aCommonCompound->GetLastFunction()->SetDescription("");
339 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
341 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
342 std::list<Handle(GEOM_Object)> aFacesList;
343 for (int j = 1 ; j <= 4 ; j++) {
344 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
345 if (!aFace.IsNull()) {
346 aFace->GetLastFunction()->SetDescription("");
347 aFacesList.push_back(aFace);
350 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
351 if (!aCompoundOfFaces.IsNull()) {
352 aCompoundOfFaces->GetLastFunction()->SetDescription("");
353 aCompoundOfFacesList.push_back(aCompoundOfFaces);
357 if (aCompoundOfFacesList.size() == 3) {
358 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
359 aCompoundOfFacesList.pop_front();
360 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
361 aCompoundOfFacesList.pop_front();
362 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
363 aCompoundOfFacesList.pop_front();
368 // Uncomment the following lines when GetInPlace bug is solved
370 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
371 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
372 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
373 // aP1->GetLastFunction()->SetDescription("");
374 // aP2->GetLastFunction()->SetDescription("");
375 // aP3->GetLastFunction()->SetDescription("");
376 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
377 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
378 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
379 // aV1->GetLastFunction()->SetDescription("");
380 // aV2->GetLastFunction()->SetDescription("");
381 // aV3->GetLastFunction()->SetDescription("");
382 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
383 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
384 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
385 // aPln1->GetLastFunction()->SetDescription("");
386 // aPln2->GetLastFunction()->SetDescription("");
387 // aPln3->GetLastFunction()->SetDescription("");
389 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
390 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
391 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
392 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
393 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
394 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
395 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
396 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
397 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
401 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
402 if (junctionFaces1.IsNull())
403 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
404 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
405 if (!junctionFaces1.IsNull()) {
406 junctionFaces1->GetLastFunction()->SetDescription("");
407 junctionFaces1->SetName("JUNCTION_FACE_1");
408 theSeq->Append(junctionFaces1);
411 SetErrorCode("Junction face 1 not found");
412 // theSeq->Append(aPln1);
415 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
416 if (junctionFaces2.IsNull())
417 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
418 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
419 if (!junctionFaces2.IsNull()) {
420 junctionFaces2->GetLastFunction()->SetDescription("");
421 junctionFaces2->SetName("JUNCTION_FACE_2");
422 theSeq->Append(junctionFaces2);
425 SetErrorCode("Junction face 2 not found");
426 // theSeq->Append(aPln2);
429 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
430 if (junctionFaces3.IsNull())
431 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
432 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
433 if (!junctionFaces3.IsNull()) {
434 junctionFaces3->GetLastFunction()->SetDescription("");
435 junctionFaces3->SetName("JUNCTION_FACE_3");
436 theSeq->Append(junctionFaces3);
439 SetErrorCode("Junction face 3 not found");
440 // theSeq->Append(aPln3);
443 // Comment the following lines when GetInPlace bug is solved
448 /////////////////////////
449 //// Groups of Edges ////
450 /////////////////////////
451 // Result of propagate
453 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
455 TCollection_AsciiString theDesc = aFunction->GetDescription();
456 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
457 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
458 SetErrorCode("Propagation groups not found");
461 Standard_Integer aNbGroups = aSeqPropagate->Length();
462 // Recover previous description to get rid of Propagate dump
463 aFunction->SetDescription(theDesc);
465 #ifdef FIND_GROUPS_BY_POINTS
466 // BEGIN: new groups search
473 // g / ''..| | |..'' \
475 // .---.--'.. | | | ..'--.---.
476 // |a \ '''...........''' / |
477 // |-------\------' | '------/-------.
482 // ._________________|_________________.
488 // |-----------------|-----------------|
490 // '-----------------'-----------------'
493 // "Thickness" group (a)
494 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
495 aPntA.Transform(aTrsf);
496 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
497 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
498 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
500 // "Circular quarter of pipe" group (b)
501 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
502 aPntB.Transform(aTrsf);
503 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
504 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
505 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
507 // "Circular quarter of pipe" group (c)
508 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
509 aPntC.Transform(aTrsf);
510 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
511 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
512 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
514 // "Main pipe half length" group (d)
515 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
516 aPntD.Transform(aTrsf);
517 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
518 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
519 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
521 // "Incident pipe half length" group (e)
522 double aTol10 = Precision::Confusion() * 10.;
523 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
524 aPntE.Transform(aTrsf);
525 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
526 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
527 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
529 // "Flange" group (f)
530 double aFx = - aR2Ext - aTol10;
531 if (shapeType == TSHAPE_CHAMFER)
533 else if (shapeType == TSHAPE_FILLET)
535 gp_Pnt aPntF (aFx, 0, aR1Ext);
536 aPntF.Transform(aTrsf);
537 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
538 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
539 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
541 // "Chamfer or Fillet" group (g)
542 TopoDS_Shape anEdgeG;
543 if (shapeType == TSHAPE_CHAMFER) {
544 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
545 aPntG.Transform(aTrsf);
546 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
547 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
548 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
550 else if (shapeType == TSHAPE_FILLET) {
551 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
552 aPntG.Transform(aTrsf);
553 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
554 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
555 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
558 for (int i = 1 ; i <= aNbGroups; i++) {
559 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
563 TopoDS_Shape aGroupShape = aGroup->GetValue();
564 TopTools_IndexedMapOfShape anEdgesMap;
565 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
567 if (anEdgesMap.Contains(anEdgeA)) { // a
568 aGroup->SetName("THICKNESS");
569 theSeq->Append(aGroup);
571 else if (anEdgesMap.Contains(anEdgeB)) { // b
572 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
573 theSeq->Append(aGroup);
575 else if (anEdgesMap.Contains(anEdgeC)) { // c
576 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
577 theSeq->Append(aGroup);
579 else if (anEdgesMap.Contains(anEdgeD)) { // d
580 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
581 theSeq->Append(aGroup);
583 else if (anEdgesMap.Contains(anEdgeE)) { // e
584 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
585 theSeq->Append(aGroup);
587 else if (anEdgesMap.Contains(anEdgeF)) { // f
588 aGroup->SetName("FLANGE");
589 theSeq->Append(aGroup);
591 else if (shapeType == TSHAPE_CHAMFER) { // g
592 if (anEdgesMap.Contains(anEdgeG)) {
593 aGroup->SetName("CHAMFER");
594 theSeq->Append(aGroup);
597 else if (shapeType == TSHAPE_FILLET) { // g
598 if (anEdgesMap.Contains(anEdgeG)) {
599 aGroup->SetName("FILLET");
600 theSeq->Append(aGroup);
606 // END: new groups search
609 bool circularFoundAndAdded = false;
610 bool circularFound10 = false;
611 bool incidentPipeFound = false;
612 bool mainPipeFound = false;
613 bool mainPipeFoundAndAdded = false;
614 bool radialFound =false;
615 bool flangeFound = false;
616 bool flangeFoundAndAdded = false;
617 bool chamferOrFilletFound = false;
619 for (int i = 1 ; i <= aNbGroups; i++) {
622 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
626 TopoDS_Shape aGroupShape = aGroup->GetValue();
627 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
628 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
630 TopTools_IndexedMapOfShape anEdgesMap;
631 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
632 Standard_Integer nbEdges = anEdgesMap.Extent();
634 if (shapeType == TSHAPE_BASIC) {
635 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
637 aGroup->SetName("THICKNESS");
639 else if (nbEdges == 6) {
640 if (!circularFoundAndAdded) {
641 circularFoundAndAdded = true;
643 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
646 else if (nbEdges == 8) {
647 incidentPipeFound = true;
648 mainPipeFound = false;
652 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
654 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
655 double x=aP.X(), y=aP.Y(), z=aP.Z();
658 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
659 (Abs(y) > aR2Ext + Precision::Confusion())) {
660 incidentPipeFound = false;
663 if ( z < -Precision::Confusion()) {
664 // length of main pipe
665 mainPipeFound = true;
666 if (!mainPipeFoundAndAdded) {
667 mainPipeFoundAndAdded = true;
669 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
673 else if (Abs(x) > (theL1-Precision::Confusion())) {
674 // discretisation circulaire
676 if (!circularFoundAndAdded) {
677 circularFoundAndAdded = true;
679 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
684 if (incidentPipeFound) {
686 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
688 if (!addGroup && (!incidentPipeFound &&
692 // Flange (collerette)
695 aGroup->SetName("FLANGE");
701 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
702 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
704 aGroup->SetName("THICKNESS");
706 else if ((nbEdges == 10) || (nbEdges == 6)) {
707 if (!circularFoundAndAdded) {
709 circularFoundAndAdded = true;
710 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
712 circularFound10 = true;
715 else if (!circularFound10 && nbEdges == 10) {
716 circularFound10 = true;
718 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
721 else if (nbEdges == 8) {
722 incidentPipeFound = true;
723 mainPipeFound = true;
726 bool isNearZ0 = false;
727 bool isBelowZ0 = false;
729 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
731 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
732 double x=aP.X(), y=aP.Y(), z=aP.Z();
734 // tuy_princ_long_avant & tuy_princ_long_apres
735 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
736 // ((y <= aR1Ext + Precision::Confusion()) ||
737 // (y <= -(aR1Ext + Precision::Confusion())) ||
738 // (y <= theR1 + Precision::Confusion()) ||
739 // (y == -(theR1 + Precision::Confusion()))));
740 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
741 (fabs(y) > theR1 - Precision::Confusion() ||
742 fabs(y) < Precision::Confusion()));
745 mainPipeFound = false;
749 //if (z < Precision::Confusion() && !isMain) {
750 // flangeFound = true;
751 // if (!flangeFoundAndAdded) {
752 // flangeFoundAndAdded = true;
754 // aGroup->SetName("FLANGE");
757 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
758 if (z < - Precision::Confusion()) isBelowZ0 = true;
761 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
762 (Abs(y) > aR2Ext + Precision::Confusion())) {
763 incidentPipeFound = false;
769 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
771 if (incidentPipeFound) {
773 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
775 if (isNearZ0 && !isBelowZ0) {
777 if (!flangeFoundAndAdded) {
778 flangeFoundAndAdded = true;
780 aGroup->SetName("FLANGE");
783 if (!addGroup && (!incidentPipeFound &&
786 !chamferOrFilletFound)) {
788 chamferOrFilletFound = true;
789 if (shapeType == TSHAPE_CHAMFER)
790 aGroup->SetName("CHAMFER");
792 aGroup->SetName("FILLET");
798 // Add group to the list
800 theSeq->Append(aGroup);
808 //=============================================================================
810 * Return faces that are laying on surface.
812 //=============================================================================
813 bool AdvancedEngine_IOperations::GetFacesOnSurf
814 (const TopoDS_Shape &theShape,
815 const Handle_Geom_Surface& theSurface,
816 const Standard_Real theTolerance,
817 TopTools_ListOfShape &theFaces)
819 GEOMAlgo_FinderShapeOn2 aFinder;
820 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
822 aClsfSurf->SetSurface(theSurface);
823 aFinder.SetShape(theShape);
824 aFinder.SetTolerance(theTolerance);
825 aFinder.SetClsf(aClsfSurf);
826 aFinder.SetShapeType(TopAbs_FACE);
827 aFinder.SetState(GEOMAlgo_ST_ON);
829 // Sets the minimal number of inner points for the faces that do not have own
830 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
832 aFinder.SetNbPntsMin(3);
833 // Sets the maximal number of inner points for edges or faces.
834 // It is usefull for the cases when this number is very big (e.g =2000) to improve
835 // the performance. If this value =0, all inner points will be taken into account.
837 aFinder.SetNbPntsMax(100);
840 // Interprete results
841 Standard_Integer iErr = aFinder.ErrorStatus();
842 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
844 MESSAGE(" iErr : " << iErr);
845 TCollection_AsciiString aMsg (" iErr : ");
846 aMsg += TCollection_AsciiString(iErr);
850 Standard_Integer iWrn = aFinder.WarningStatus();
851 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
853 MESSAGE(" *** iWrn : " << iWrn);
856 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
857 TopTools_ListIteratorOfListOfShape anIter (aListRes);
859 for (; anIter.More(); anIter.Next()) {
860 theFaces.Append(anIter.Value());
866 //=============================================================================
868 * Creates and returns conical face.
870 //=============================================================================
871 TopoDS_Shape AdvancedEngine_IOperations::MakeConicalFace
872 (const gp_Ax2 &theAxis,
873 const double theRadius,
874 const double theRadiusThin,
875 const double theHeight,
876 const gp_Trsf &theTrsf)
878 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
879 TopoDS_Shape aResult;
882 if (aMkCone.IsDone()) {
883 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
885 for (; anExp.More(); anExp.Next()) {
886 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
888 if (aFace.IsNull() == Standard_False) {
889 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
891 if (anAdaptor.GetType() == GeomAbs_Cone) {
892 // This is a conical face. Transform and return it.
893 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
895 aResult = aTransf.Shape();
905 //=============================================================================
907 * Generate the internal group of a Pipe T-Shape
909 //=============================================================================
910 bool AdvancedEngine_IOperations::MakeInternalGroup
911 (const Handle(GEOM_Object) &theShape,
912 const double theR1, const double theLen1,
913 const double theR2, const double theLen2,
914 const double theRL, double theTransLenL,
915 const double theRR, double theTransLenR,
916 const double theRI, double theTransLenI,
917 const Handle(TColStd_HSequenceOfTransient) &theSeq,
918 const gp_Trsf &theTrsf)
922 if (theShape.IsNull()) {
926 TopoDS_Shape aShape = theShape->GetValue();
928 if (aShape.IsNull()) {
929 SetErrorCode("Shape is not defined");
934 Standard_Real aMaxTol = -RealLast();
935 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
937 for (; anExp.More(); anExp.Next()) {
938 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
940 if (aVertex.IsNull() == Standard_False) {
941 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
943 if (aTol > aMaxTol) {
949 // Construct internal surfaces.
950 Standard_Integer i = 0;
951 const Standard_Integer aMaxNbSurf = 5;
952 Handle(Geom_Surface) aSurface[aMaxNbSurf];
953 TopTools_ListOfShape aConicalFaces;
954 Standard_Real aTolConf = Precision::Confusion();
956 // 1. Construct the internal surface of main pipe.
957 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
958 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
960 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
962 // 2. Construct the internal surface of incident pipe.
963 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
965 // 3. Construct the internal surface of left reduction pipe.
966 if (theRL > aTolConf) {
967 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
969 if (theTransLenL > aTolConf) {
970 // 3.1. Construct the internal surface of left transition pipe.
971 gp_Pnt aPLeft (-theLen1, 0., 0.);
972 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
973 TopoDS_Shape aConeLeft =
974 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
976 if (aConeLeft.IsNull() == Standard_False) {
977 aConicalFaces.Append(aConeLeft);
982 // 4. Construct the internal surface of right reduction pipe.
983 if (theRR > aTolConf) {
984 // There is no need to construct another cylinder of the same radius. Skip it.
985 if (Abs(theRR - theRL) > aTolConf) {
986 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
989 if (theTransLenL > aTolConf) {
990 // 4.1. Construct the internal surface of right transition pipe.
991 gp_Pnt aPRight (theLen1, 0., 0.);
992 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
993 TopoDS_Shape aConeRight =
994 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
996 if (aConeRight.IsNull() == Standard_False) {
997 aConicalFaces.Append(aConeRight);
1002 // 5. Construct the internal surface of incident reduction pipe.
1003 if (theRI > aTolConf) {
1004 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
1006 if (theTransLenI > aTolConf) {
1007 // 5.1. Construct the internal surface of incident transition pipe.
1008 gp_Pnt aPInci (0., 0., theLen2);
1009 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1010 TopoDS_Shape aConeInci =
1011 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1013 if (aConeInci.IsNull() == Standard_False) {
1014 aConicalFaces.Append(aConeInci);
1019 // Get faces that are laying on cylindrical surfaces.
1020 TopTools_ListOfShape aFaces;
1021 gp_Trsf anInvTrsf = theTrsf.Inverted();
1023 for (i = 0; i < aMaxNbSurf; i++) {
1024 if (aSurface[i].IsNull()) {
1028 aSurface[i]->Transform(theTrsf);
1030 TopTools_ListOfShape aLocalFaces;
1032 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1037 // Check if the result contains outer cylinders.
1038 // It is required for main and incident pipes.
1039 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1041 while (anIter.More()) {
1042 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1043 Standard_Boolean isInside = Standard_False;
1045 // Get a vertex from this shape
1047 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1049 if (aVtx.IsNull() == Standard_False) {
1050 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1052 aPnt.Transform(anInvTrsf);
1055 // Check if the point is inside the main pipe.
1056 isInside = (Abs(aPnt.X()) <= theLen1);
1058 // Check if the point is inside the incident pipe.
1059 isInside = (aPnt.Z() <= theLen2);
1068 // Remove this face.
1069 aLocalFaces.Remove(anIter);
1074 aFaces.Append(aLocalFaces);
1077 // Get faces that are laying on conical faces.
1078 if (aConicalFaces.IsEmpty() == Standard_False) {
1079 Handle(GEOM_Object) aCone =
1080 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1081 Handle(GEOM_Function) aFunction =
1082 aCone->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1083 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1084 Handle(GEOM_Object) aConeFromShape;
1086 for (; aFIter.More(); aFIter.Next()) {
1087 aFunction->SetValue(aFIter.Value());
1088 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1090 if (aConeFromShape.IsNull() == Standard_False) {
1091 aConeFromShape->GetLastFunction()->SetDescription("");
1092 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1093 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1095 for (; anExp.More(); anExp.Next()) {
1096 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1098 if (aConeFace.IsNull() == Standard_False) {
1099 aFaces.Append(aConeFace);
1106 // Create a group of internal faces.
1107 if (aFaces.IsEmpty() == Standard_False) {
1108 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1110 if (aGroup.IsNull() == Standard_False) {
1111 aGroup->GetLastFunction()->SetDescription("");
1112 aGroup->SetName("INTERNAL_FACES");
1114 TopTools_IndexedMapOfShape anIndices;
1115 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1117 TopExp::MapShapes(aShape, anIndices);
1119 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1121 for (; anIter.More(); anIter.Next()) {
1122 const TopoDS_Shape &aFace = anIter.Value();
1123 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1126 aSeqIDs->Append(anIndex);
1130 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1131 aGroup->GetLastFunction()->SetDescription("");
1132 theSeq->Append(aGroup);
1141 bool AdvancedEngine_IOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1142 double theR1, double theW1, double theL1,
1143 double theR2, double theW2, double theL2,
1144 double theH, double theW,
1145 double theRF, bool isNormal)
1149 // Build tools for partition operation:
1150 // 1 face and 2 planes
1152 Handle(GEOM_Object) arete_intersect_int, arete_intersect_ext;
1153 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1154 Handle(GEOM_Object) chan_racc;
1155 Handle(GEOM_Object) vi1, vi2;
1156 Handle(GEOM_Object) Te3;
1160 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1161 Vector_Z->GetLastFunction()->SetDescription("");
1164 double aSize = 2*(theL1 + theL2);
1165 double aR1Ext = theR1 + theW1;
1166 double aR2Ext = theR2 + theW2;
1167 double theVertCylinderRadius = aR2Ext + theW + theRF;
1168 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1170 // Common edges on internal cylinder
1171 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1172 box_i->GetLastFunction()->SetDescription("");
1173 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1174 box_i->GetLastFunction()->SetDescription("");
1176 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1177 TCollection_AsciiString theDesc = aFunction->GetDescription();
1178 Handle(TColStd_HSequenceOfTransient) edges_i =
1179 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1180 // Recover previous description to get rid of Propagate dump
1181 aFunction->SetDescription(theDesc);
1182 if (edges_i.IsNull() || edges_i->Length() == 0) {
1183 SetErrorCode("Internal edges not found");
1186 for (int i=1; i<=edges_i->Length();i++) {
1187 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1188 anObj->GetLastFunction()->SetDescription("");
1190 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1192 // search for vertices located on both internal pipes
1193 aFunction = theShape->GetLastFunction();
1194 theDesc = aFunction->GetDescription();
1195 Handle(TColStd_HSequenceOfTransient) vertices_i =
1196 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1197 // Recover previous description to get rid of Propagate dump
1198 aFunction->SetDescription(theDesc);
1199 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1200 SetErrorCode("Internal vertices not found");
1204 double d1min = theR2+theW2, d2min=theR2+theW2;
1205 for (int i = 1; i <= vertices_i->Length(); i++) {
1206 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1207 v->GetLastFunction()->SetDescription("");
1208 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1209 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1210 if (Abs(aP.X()) <= Precision::Confusion()) {
1211 if (Abs(aP.Y()) < d1min) {
1213 d1min = Abs(aP.Y());
1215 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1216 if (Abs(aP.X()) < d2min) {
1218 d2min = Abs(aP.X());
1222 if (vi1.IsNull() || vi2.IsNull()) {
1223 SetErrorCode("Cannot find internal intersection vertices");
1227 std::list<Handle(GEOM_Object)> theShapes;
1230 Handle(GEOM_Object) ve1, ve2;
1231 TopoDS_Vertex vertex1, vertex2;
1233 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1234 box_e->GetLastFunction()->SetDescription("");
1235 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1236 box_e->GetLastFunction()->SetDescription("");
1238 // search for vertices located on both external pipes
1239 aFunction = theShape->GetLastFunction();
1240 theDesc = aFunction->GetDescription();
1241 Handle(TColStd_HSequenceOfTransient) vertices_e =
1242 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1243 // Recover previous description to get rid of Propagate dump
1244 aFunction->SetDescription(theDesc);
1245 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1246 SetErrorCode("External vertices not found");
1250 double d1max = 0, d2max = 0;
1251 for (int i = 1; i <= vertices_e->Length(); i++) {
1252 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1253 v->GetLastFunction()->SetDescription("");
1254 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1255 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1256 if (Abs(aP.X()) <= Precision::Confusion()) {
1257 if (Abs(aP.Y()) > d1max) {
1260 d1max = Abs(aP.Y());
1262 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1263 if (Abs(aP.X()) > d2max) {
1266 d2max = Abs(aP.X());
1270 if (ve1.IsNull() || ve2.IsNull()) {
1271 SetErrorCode("Cannot find external intersection vertices");
1274 Handle(GEOM_Object) edge_e1, edge_e2;
1276 // Common edges on external cylinder
1277 aFunction = theShape->GetLastFunction();
1278 theDesc = aFunction->GetDescription();
1279 Handle(TColStd_HSequenceOfTransient) edges_e =
1280 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1281 // Recover previous description to get rid of Propagate dump
1282 aFunction->SetDescription(theDesc);
1283 if (edges_e.IsNull() || edges_e->Length() == 0) {
1284 SetErrorCode("External edges not found");
1287 ShapeAnalysis_Edge sae;
1288 for (int i=1; i<=edges_e->Length();i++) {
1289 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1290 anObj->GetLastFunction()->SetDescription("");
1291 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1292 if ( !anEdge.IsNull() &&
1293 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1294 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1295 arete_intersect_ext = anObj;
1299 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1300 if (edge_e1.IsNull()) {
1301 SetErrorCode("Edge 1 could not be built");
1305 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1306 if (edge_e2.IsNull()) {
1307 SetErrorCode("Edge 2 could not be built");
1311 edge_e1->GetLastFunction()->SetDescription("");
1312 edge_e2->GetLastFunction()->SetDescription("");
1314 std::list<Handle(GEOM_Object)> edge_e_elist;
1315 edge_e_elist.push_back(arete_intersect_int);
1316 edge_e_elist.push_back(edge_e1);
1317 edge_e_elist.push_back(arete_intersect_ext);
1318 edge_e_elist.push_back(edge_e2);
1319 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1320 if (wire_t.IsNull()) {
1321 SetErrorCode("Impossible to build wire");
1324 wire_t->GetLastFunction()->SetDescription("");
1325 face_t = myShapesOperations->MakeFace(wire_t, false);
1326 if (face_t.IsNull()) {
1327 SetErrorCode("Impossible to build face");
1330 face_t->GetLastFunction()->SetDescription("");
1332 theShapes.push_back(theShape);
1333 theShapes.push_back(vi1);
1334 theShapes.push_back(vi2);
1335 theShapes.push_back(ve1);
1336 theShapes.push_back(ve2);
1337 theShapes.push_back(edge_e1);
1338 theShapes.push_back(edge_e2);
1339 theShapes.push_back(wire_t);
1340 theShapes.push_back(face_t);
1343 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1344 int idP1, idP2, idP3, idP4;
1347 std::vector<int> LX;
1348 std::vector<int> LY;
1349 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1350 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1351 box_e->GetLastFunction()->SetDescription("");
1352 box_e = myTransformOperations->TranslateDXDYDZ
1353 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1354 box_e->GetLastFunction()->SetDescription("");
1356 aFunction = theShape->GetLastFunction();
1357 theDesc = aFunction->GetDescription();
1358 Handle(TColStd_HSequenceOfTransient) extremVertices =
1359 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1360 // Recover previous description to get rid of Propagate dump
1361 aFunction->SetDescription(theDesc);
1363 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1365 SetErrorCode("Vertices on chamfer not found");
1367 SetErrorCode("Vertices on fillet not found");
1371 theShapes.push_back(theShape);
1372 theShapes.push_back(box_e);
1373 if (extremVertices->Length() != 6) {
1374 // for (int i=1; i<=extremVertices->Length(); i++){
1375 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1377 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1378 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1379 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1380 SetErrorCode("Bad number of vertices on chamfer found");
1384 for (int i=1; i<=extremVertices->Length(); i++){
1385 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1386 aV->GetLastFunction()->SetDescription("");
1387 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1389 if (Abs(aP.X()) <= Precision::Confusion()) {
1390 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1392 if (aP.Z()-ZX > Precision::Confusion()) {
1399 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1401 if (aP.Z() - ZY > Precision::Confusion()) {
1412 if (LX.at(0) == PZX)
1415 if (LY.at(0) == PZY)
1418 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1419 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1420 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1421 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1423 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1424 if (Cote_1.IsNull()) {
1425 SetErrorCode("Impossible to build edge in thickness");
1428 Cote_1->GetLastFunction()->SetDescription("");
1430 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1431 if (Cote_2.IsNull()) {
1432 SetErrorCode("Impossible to build edge in thickness");
1435 Cote_2->GetLastFunction()->SetDescription("");
1437 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1438 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1439 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1440 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1441 if (edge_chan_princ.IsNull()) {
1442 SetErrorCode("Impossible to find edge on main pipe");
1445 edge_chan_princ->GetLastFunction()->SetDescription("");
1447 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1448 if (edge_chan_inc.IsNull()) {
1449 SetErrorCode("Impossible to find edge on incident pipe");
1452 edge_chan_inc->GetLastFunction()->SetDescription("");
1454 std::list<Handle(GEOM_Object)> edgeList1;
1455 edgeList1.push_back(edge_chan_princ);
1456 edgeList1.push_back(Cote_1);
1457 edgeList1.push_back(arete_intersect_int);
1458 edgeList1.push_back(Cote_2);
1460 // std::cerr << "Creating wire 1" << std::endl;
1461 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1462 if (wire_t.IsNull()) {
1463 SetErrorCode("Impossible to build wire");
1466 wire_t->GetLastFunction()->SetDescription("");
1468 // std::cerr << "Creating face 1" << std::endl;
1469 face_t = myShapesOperations->MakeFace(wire_t, false);
1470 if (face_t.IsNull()) {
1471 SetErrorCode("Impossible to build face");
1474 face_t->GetLastFunction()->SetDescription("");
1475 theShapes.push_back(face_t);
1477 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1478 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1479 double deltaZ = aP2.Z() - aP5.Z();
1480 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1481 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1482 if (P5bis.IsNull()) {
1483 SetErrorCode("Impossible to translate vertex");
1486 P5bis->GetLastFunction()->SetDescription("");
1488 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1489 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1490 deltaZ = aP4.Z() - aP6.Z();
1491 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1492 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1493 if (P6bis.IsNull()) {
1494 SetErrorCode("Impossible to translate vertex");
1497 P6bis->GetLastFunction()->SetDescription("");
1499 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1500 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
1501 if (Cote_3.IsNull()) {
1502 SetErrorCode("Impossible to build edge in thickness");
1505 Cote_3->GetLastFunction()->SetDescription("");
1507 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1508 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
1509 if (Cote_4.IsNull()) {
1510 SetErrorCode("Impossible to build edge in thickness");
1513 Cote_4->GetLastFunction()->SetDescription("");
1515 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1516 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1517 if (Cote_4.IsNull()) {
1518 SetErrorCode("Impossible to build edge in thickness");
1521 Cote_5->GetLastFunction()->SetDescription("");
1523 //std::list<Handle(GEOM_Object)> edgeList2;
1524 //edgeList2.push_back(edge_chan_inc);
1525 //edgeList2.push_back(Cote_3);
1526 //edgeList2.push_back(Cote_5);
1527 //edgeList2.push_back(Cote_4);
1528 // std::cerr << "Creating wire 2" << std::endl;
1529 //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
1530 //if (wire_t2.IsNull()) {
1531 // SetErrorCode("Impossible to build wire");
1534 //wire_t2->GetLastFunction()->SetDescription("");
1535 // std::cerr << "Creating face 2" << std::endl;
1536 //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
1538 // Mantis issue 0021682
1539 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - (theR2 + theW2));
1540 //face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
1541 if (face_t2.IsNull()) {
1542 SetErrorCode("Impossible to build face");
1545 face_t2->GetLastFunction()->SetDescription("");
1546 theShapes.push_back(face_t2);
1550 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1551 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1552 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1553 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1554 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1555 aP0->GetLastFunction()->SetDescription("");
1556 aVZ->GetLastFunction()->SetDescription("");
1557 aVXZ->GetLastFunction()->SetDescription("");
1558 aPlnOZ->GetLastFunction()->SetDescription("");
1559 aPlnOXZ->GetLastFunction()->SetDescription("");
1560 theShapes.push_back(aPlnOZ);
1561 theShapes.push_back(aPlnOXZ);
1564 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1565 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1566 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1567 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1568 Handle(TColStd_HArray1OfInteger) theMaterials;
1570 partitionShapes->Append(theShape);
1571 theTools->Append(aPlnOZ);
1572 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1573 theTools->Append(aPlnOXZ);
1574 theTools->Append(face_t);
1576 theTools->Append(face_t2);
1578 Te3 = myBooleanOperations->MakePartition
1579 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1580 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1582 SetErrorCode("Impossible to build partition of TShape");
1585 Te3->GetLastFunction()->SetDescription("");
1587 // Last verification: result should be a block
1588 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1589 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3, -1, errList)) {
1590 SetErrorCode("TShape is not a compound of block");
1594 // // BEGIN Compound of created shapes - Only for debug purpose
1595 // theShapes.clear();
1596 // theShapes.push_back(theShape);
1597 // theShapes.push_back(aPlnOZ);
1598 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1599 // theShapes.push_back(aPlnOXZ);
1600 // theShapes.push_back(face_t);
1602 // theShapes.push_back(face_t2);
1604 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1605 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1606 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1607 // // END Compound of created shapes - Only for debug purpose
1609 TopoDS_Shape aShape = Te3->GetValue();
1610 theShape->GetLastFunction()->SetValue(aShape);
1612 catch (Standard_Failure) {
1613 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1614 SetErrorCode(aFail->GetMessageString());
1622 // Mirror and glue faces
1623 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1624 double theR1, double theW1, double theL1,
1625 double theR2, double theW2, double theL2)
1630 double aSize = 2*(theL1 + theL2);
1631 double aR1Ext = theR1 + theW1;
1634 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1635 aP0->GetLastFunction()->SetDescription("");
1636 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1637 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1638 aVX->GetLastFunction()->SetDescription("");
1639 aVY->GetLastFunction()->SetDescription("");
1640 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1641 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1642 aPlane_OX->GetLastFunction()->SetDescription("");
1643 aPlane_OY->GetLastFunction()->SetDescription("");
1645 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1647 SetErrorCode("Impossible to build mirror of quarter TShape");
1651 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1653 SetErrorCode("Impossible to build mirror of half TShape");
1657 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1659 SetErrorCode("Impossible to build mirror of half TShape");
1663 std::list<Handle(GEOM_Object)> aShapesList;
1664 aShapesList.push_back(theShape);
1665 aShapesList.push_back(Te4);
1666 aShapesList.push_back(Te5);
1667 aShapesList.push_back(Te6);
1668 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1670 SetErrorCode("Impossible to build compound");
1674 // Copy source shape
1675 TopoDS_Shape aShapeCopy;
1676 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1677 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1679 std::list<Handle(GEOM_Object)> Te7list( 1, Te7 );
1680 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7list, 1e-7, true);
1682 SetErrorCode("Impossible to glue faces of TShape");
1686 TopoDS_Shape aShape = Te8->GetValue();
1687 BRepCheck_Analyzer anAna (aShape, Standard_True);
1689 if (!anAna.IsValid()) {
1690 // Try to do gluing with the tolerance equal to maximal
1691 // tolerance of vertices of the source shape.
1692 Standard_Real aTolMax = -RealLast();
1694 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1695 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1696 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1698 if (aTol > aTolMax) {
1704 Te7->GetLastFunction()->SetValue(aShapeCopy);
1705 Te8 = myShapesOperations->MakeGlueFaces(Te7list, aTolMax, true);
1708 SetErrorCode("Impossible to glue faces of TShape");
1712 aShape = Te8->GetValue();
1716 theShape->GetLastFunction()->SetValue(aShape);
1718 Te4->GetLastFunction()->SetDescription("");
1719 Te5->GetLastFunction()->SetDescription("");
1720 Te6->GetLastFunction()->SetDescription("");
1721 Te7->GetLastFunction()->SetDescription("");
1722 Te8->GetLastFunction()->SetDescription("");
1728 //=======================================================================
1729 //function : MakePipeTShapeThicknessReduction
1730 //purpose : Static method. Add thiskness reduction elements at the three
1731 // open ends of the T-Shape.
1732 //=======================================================================
1733 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1734 (TopoDS_Shape theShape,
1735 double r1, double w1, double l1,
1736 double r2, double w2, double l2,
1737 double rL, double wL, double ltransL, double lthinL,
1738 double rR, double wR, double ltransR, double lthinR,
1739 double rI, double wI, double ltransI, double lthinI,
1740 bool fuseReductions)
1742 // Add thickness reduction elements
1743 // at the three extremities: Left, Right and Incident
1745 // ---------------------.
1747 // ---------------------. \
1748 // ^ \ '-----------------.
1750 // | '-----------------'
1752 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1755 TopoDS_Shape aResult = theShape;
1756 double aTol = Precision::Confusion();
1758 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1760 // Left reduction (rL, wL, ltransL, lthinL)
1761 if (rL > aTol && wL > aTol && ltransL > aTol) {
1762 gp_Pnt aPLeft (-l1, 0, 0);
1763 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1764 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1765 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1767 if (fuseReductions) {
1768 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1769 if (!fuseL.IsDone())
1770 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1771 aResult = fuseL.Shape();
1778 B.Add(C, aReductionLeft);
1784 if (rR > aTol && wR > aTol && ltransR > aTol) {
1785 gp_Pnt aPRight (l1, 0, 0);
1786 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1787 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1788 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1790 if (fuseReductions) {
1791 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1792 if (!fuseR.IsDone())
1793 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1794 aResult = fuseR.Shape();
1801 B.Add(C, aReductionRight);
1806 // Incident reduction
1807 if (rI > aTol && wI > aTol && ltransI > aTol) {
1808 gp_Pnt aPInci (0, 0, l2);
1809 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1810 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1811 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1813 if (fuseReductions) {
1814 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1815 if (!fuseInci.IsDone())
1816 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1817 aResult = fuseInci.Shape();
1824 B.Add(C, aReductionInci);
1829 // Get rid of extra compounds
1830 TopTools_ListOfShape listShapeRes;
1831 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1832 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1834 if (!fuseReductions && listShapeRes.Extent() > 1) {
1835 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1840 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1841 for (; itSub.More(); itSub.Next())
1842 B.Add(C, itSub.Value());
1845 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1851 //=======================================================================
1852 //function : MakeThicknessReduction
1853 //purpose : Static method. Create one thickness reduction element.
1854 //=======================================================================
1855 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1856 const double R, const double W,
1857 const double Rthin, const double Wthin,
1858 const double Ltrans, const double Lthin,
1861 double aTol = Precision::Confusion();
1862 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1863 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1865 bool isThinPart = (Lthin > aTol);
1870 // ^ \ '-----------------.
1872 // | '-----------------'
1874 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1877 double RExt = R + W;
1878 double RthinExt = Rthin + Wthin;
1880 gp_Dir aNormal = theAxes.Direction();
1881 gp_Dir anXDir = theAxes.XDirection();
1882 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1883 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1885 // Build the transition part
1886 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1887 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1890 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1891 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1892 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1894 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1895 TopoDS_Shape aReduction = cut1.Shape();
1897 // Build the thin part, if required
1898 TopoDS_Shape aThinPart;
1900 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1901 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1904 if (!CExt.IsDone() || !CInt.IsDone())
1905 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1906 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1908 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1909 aThinPart = cut2.Shape();
1915 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1916 if (!fuse1.IsDone())
1917 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1918 aReduction = fuse1.Shape();
1922 // Partition the reduction on blocks
1923 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1924 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1925 gp_Pln aPln1 (anAxesPln1);
1926 gp_Pln aPln2 (anAxesPln2);
1927 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1928 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1929 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1931 GEOMAlgo_Splitter PS;
1932 PS.AddArgument(aReduction);
1934 PS.AddArgument(aThinPart);
1937 PS.SetLimit(TopAbs_SOLID);
1940 aReduction = PS.Shape();
1946 //=============================================================================
1949 * \brief Create a T-shape object with specified caracteristics for the main and
1950 * the incident pipes (radius, width, half-length).
1951 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1952 * \param theR1 Internal radius of main pipe
1953 * \param theW1 Width of main pipe
1954 * \param theL1 Half-length of main pipe
1955 * \param theR2 Internal radius of incident pipe (R2 < R1)
1956 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1957 * \param theL2 Half-length of incident pipe
1958 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1959 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1961 //=============================================================================
1962 Handle(TColStd_HSequenceOfTransient)
1963 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1964 double theR2, double theW2, double theL2,
1965 double theRL, double theWL, double theLtransL, double theLthinL,
1966 double theRR, double theWR, double theLtransR, double theLthinR,
1967 double theRI, double theWI, double theLtransI, double theLthinI,
1970 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1973 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1975 //Add a new shape function with parameters
1976 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1977 if (aFunction.IsNull()) return NULL;
1979 //Check if the function is set correctly
1980 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1982 AdvancedEngine_IPipeTShape aData (aFunction);
1990 aData.SetHexMesh(theHexMesh);
1992 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1993 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1994 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1996 //Compute the resulting value
1999 if (!GetSolver()->ComputeFunction(aFunction)) {
2000 SetErrorCode("TShape driver failed");
2005 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2007 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2011 if (isTRL || isTRR || isTRI) {
2012 // Add thickness reduction elements
2013 // at the three extremities: Left, Right and Incident
2014 TopoDS_Shape aResShape =
2015 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2016 theRL, theWL, theLtransL, theLthinL,
2017 theRR, theWR, theLtransR, theLthinR,
2018 theRI, theWI, theLtransI, theLthinI,
2020 aFunction->SetValue(aResShape);
2023 catch (Standard_Failure) {
2024 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2025 SetErrorCode(aFail->GetMessageString());
2029 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2030 aSeq->Append(aShape);
2035 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2036 0., 0., 0., aSeq, gp_Trsf()))
2040 // Get internal group.
2041 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2042 theRR, theLtransR, theRI, theLtransI,
2047 catch (Standard_Failure) {
2048 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2049 SetErrorCode(aFail->GetMessageString());
2053 //Make a Python command
2054 TCollection_AsciiString anEntry, aListRes("[");
2055 // Iterate over the sequence aSeq
2056 Standard_Integer aNbGroups = aSeq->Length();
2057 Standard_Integer i = 1;
2058 for (; i <= aNbGroups; i++) {
2059 Handle(Standard_Transient) anItem = aSeq->Value(i);
2060 if (anItem.IsNull()) continue;
2061 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2062 if (aGroup.IsNull()) continue;
2063 //Make a Python command
2064 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2065 aListRes += anEntry + ", ";
2067 aListRes.Trunc(aListRes.Length() - 2);
2069 GEOM::TPythonDump pd (aFunction);
2071 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2072 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2073 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2076 // thickness reduction
2078 pd << ", theRL=" << theRL << ", theWL=" << theWL
2079 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2081 pd << ", theRR=" << theRR << ", theWR=" << theWR
2082 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2084 pd << ", theRI=" << theRI << ", theWI=" << theWI
2085 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2094 //=============================================================================
2096 * MakePipeTShapeWithPosition
2097 * Create a T-shape object with specified caracteristics for the main and
2098 * the incident pipes (radius, width, half-length).
2099 * The extremities of the main pipe are located on junctions points P1 and P2.
2100 * The extremity of the incident pipe is located on junction point P3.
2101 * \param theR1 Internal radius of main pipe
2102 * \param theW1 Width of main pipe
2103 * \param theL1 Half-length of main pipe
2104 * \param theR2 Internal radius of incident pipe (R2 < R1)
2105 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2106 * \param theL2 Half-length of incident pipe
2107 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2108 * \param theP1 1st junction point of main pipe
2109 * \param theP2 2nd junction point of main pipe
2110 * \param theP3 Junction point of incident pipe
2111 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2113 //=============================================================================
2114 Handle(TColStd_HSequenceOfTransient)
2115 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2116 (double theR1, double theW1, double theL1,
2117 double theR2, double theW2, double theL2,
2118 double theRL, double theWL, double theLtransL, double theLthinL,
2119 double theRR, double theWR, double theLtransR, double theLthinR,
2120 double theRI, double theWI, double theLtransI, double theLthinI,
2122 Handle(GEOM_Object) theP1,
2123 Handle(GEOM_Object) theP2,
2124 Handle(GEOM_Object) theP3)
2128 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2132 //Add a new shape function with parameters
2133 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2134 if (aFunction.IsNull()) return NULL;
2136 //Check if the function is set correctly
2137 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2139 // Check new position
2140 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2144 AdvancedEngine_IPipeTShape aData(aFunction);
2152 aData.SetHexMesh(theHexMesh);
2154 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2155 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2156 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2158 //Compute the resulting value
2161 if (!GetSolver()->ComputeFunction(aFunction)) {
2162 SetErrorCode("TShape driver failed");
2167 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2169 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2173 if (isTRL || isTRR || isTRI) {
2174 // Add thickness reduction elements
2175 // at the three extremities: Left, Right and Incident
2176 TopoDS_Shape aResShape =
2177 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2178 theRL, theWL, theLtransL, theLthinL,
2179 theRR, theWR, theLtransR, theLthinR,
2180 theRI, theWI, theLtransI, theLthinI,
2182 aFunction->SetValue(aResShape);
2185 catch (Standard_Failure) {
2186 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2187 SetErrorCode(aFail->GetMessageString());
2191 TopoDS_Shape Te = aShape->GetValue();
2194 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2195 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2196 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2197 aFunction->SetValue(aTrsf_Shape);
2199 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2200 aSeq->Append(aShape);
2205 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2206 0., 0., 0., aSeq, aTrsf)) {
2211 // Get internal group.
2212 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2213 theRR, theLtransR, theRI, theLtransI,
2218 catch (Standard_Failure) {
2219 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2220 SetErrorCode(aFail->GetMessageString());
2224 //Make a Python command
2225 TCollection_AsciiString anEntry, aListRes("[");
2226 // Iterate over the sequence aSeq
2227 Standard_Integer aNbGroups = aSeq->Length();
2228 Standard_Integer i = 1;
2229 for (; i <= aNbGroups; i++) {
2230 Handle(Standard_Transient) anItem = aSeq->Value(i);
2231 if (anItem.IsNull()) continue;
2232 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2233 if (aGroup.IsNull()) continue;
2234 //Make a Python command
2235 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2236 aListRes += anEntry + ", ";
2238 aListRes.Trunc(aListRes.Length() - 2);
2240 GEOM::TPythonDump pd (aFunction);
2242 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2243 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2244 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2245 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2247 // thickness reduction
2249 pd << ", theRL=" << theRL << ", theWL=" << theWL
2250 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2252 pd << ", theRR=" << theRR << ", theWR=" << theWR
2253 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2255 pd << ", theRI=" << theRI << ", theWI=" << theWI
2256 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2265 //=============================================================================
2267 * MakePipeTShapeChamfer
2268 * Create a T-shape object with specified caracteristics for the main and
2269 * the incident pipes (radius, width, half-length). A chamfer is created
2270 * on the junction of the pipes.
2271 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2272 * \param theR1 Internal radius of main pipe
2273 * \param theW1 Width of main pipe
2274 * \param theL1 Half-length of main pipe
2275 * \param theR2 Internal radius of incident pipe (R2 < R1)
2276 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2277 * \param theL2 Half-length of incident pipe
2278 * \param theH Height of chamfer.
2279 * \param theW Width of chamfer.
2280 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2281 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2283 //=============================================================================
2284 Handle(TColStd_HSequenceOfTransient)
2285 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2286 (double theR1, double theW1, double theL1,
2287 double theR2, double theW2, double theL2,
2288 double theRL, double theWL, double theLtransL, double theLthinL,
2289 double theRR, double theWR, double theLtransR, double theLthinR,
2290 double theRI, double theWI, double theLtransI, double theLthinI,
2291 double theH, double theW,
2296 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2297 //Add a new shape function with parameters
2298 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2299 if (aFunction.IsNull()) return NULL;
2301 //Check if the function is set correctly
2302 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2304 AdvancedEngine_IPipeTShape aData(aFunction);
2314 aData.SetHexMesh(theHexMesh);
2316 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2317 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2318 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2320 //Compute the resulting value
2323 if (!GetSolver()->ComputeFunction(aFunction)) {
2324 SetErrorCode("TShape driver failed");
2328 catch (Standard_Failure) {
2329 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2330 SetErrorCode(aFail->GetMessageString());
2335 TopoDS_Shape aShapeShape = aShape->GetValue();
2336 TopTools_IndexedMapOfShape anEdgesIndices;
2337 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2338 // Common edges on external cylinders
2339 Handle(GEOM_Object) box_e;
2341 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2344 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2346 box_e->GetLastFunction()->SetDescription("");
2347 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2348 box_e->GetLastFunction()->SetDescription("");
2350 Handle(TColStd_HSequenceOfInteger) edges_e =
2351 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2352 box_e->GetLastFunction()->SetDescription("");
2354 if (edges_e.IsNull() || edges_e->Length() == 0) {
2355 SetErrorCode("External edges not found");
2358 int nbEdgesInChamfer = 0;
2359 std::list<int> theEdges;
2360 for (int i=1; i<=edges_e->Length();i++) {
2361 int edgeID = edges_e->Value(i);
2362 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2363 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2367 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2368 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2369 nbEdgesInChamfer ++;
2370 theEdges.push_back(edgeID);
2374 if (theHexMesh && nbEdgesInChamfer == 1)
2377 Handle(GEOM_Object) aChamfer;
2379 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2381 catch (Standard_Failure) {
2382 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2383 SetErrorCode(aFail->GetMessageString());
2386 if (aChamfer.IsNull()) {
2387 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2390 aChamfer->GetLastFunction()->SetDescription("");
2392 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2393 aFunction->SetValue(aChamferShape);
2397 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2399 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2403 // Add thickness reduction elements
2404 // at the three extremities: Left, Right and Incident
2407 if (isTRL || isTRR || isTRI) {
2408 TopoDS_Shape aResShape =
2409 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2410 theRL, theWL, theLtransL, theLthinL,
2411 theRR, theWR, theLtransR, theLthinR,
2412 theRI, theWI, theLtransI, theLthinI,
2414 aFunction->SetValue(aResShape);
2417 catch (Standard_Failure) {
2418 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2419 SetErrorCode(aFail->GetMessageString());
2423 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2424 aSeq->Append(aShape);
2429 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2430 theH, theW, 0., aSeq, gp_Trsf()))
2434 // Get internal group.
2435 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2436 theRR, theLtransR, theRI, theLtransI,
2441 catch (Standard_Failure) {
2442 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2443 SetErrorCode(aFail->GetMessageString());
2447 //Make a Python command
2448 TCollection_AsciiString anEntry, aListRes("[");
2449 // Iterate over the sequence aSeq
2450 Standard_Integer aNbGroups = aSeq->Length();
2451 Standard_Integer i = 1;
2452 for (; i <= aNbGroups; i++) {
2453 Handle(Standard_Transient) anItem = aSeq->Value(i);
2454 if (anItem.IsNull()) continue;
2455 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2456 if (aGroup.IsNull()) continue;
2457 //Make a Python command
2458 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2459 aListRes += anEntry + ", ";
2461 aListRes.Trunc(aListRes.Length() - 2);
2463 GEOM::TPythonDump pd (aFunction);
2465 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2466 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2467 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2468 << theH << ", " << theW << ", " << theHexMesh;
2470 // thickness reduction
2472 pd << ", theRL=" << theRL << ", theWL=" << theWL
2473 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2475 pd << ", theRR=" << theRR << ", theWR=" << theWR
2476 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2478 pd << ", theRI=" << theRI << ", theWI=" << theWI
2479 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2488 //=============================================================================
2490 * MakePipeTShapeChamferWithPosition
2491 * Create a T-shape object with specified caracteristics for the main and
2492 * the incident pipes (radius, width, half-length). A chamfer is created
2493 * on the junction of the pipes.
2494 * The extremities of the main pipe are located on junctions points P1 and P2.
2495 * The extremity of the incident pipe is located on junction point P3.
2496 * \param theR1 Internal radius of main pipe
2497 * \param theW1 Width of main pipe
2498 * \param theL1 Half-length of main pipe
2499 * \param theR2 Internal radius of incident pipe (R2 < R1)
2500 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2501 * \param theL2 Half-length of incident pipe
2502 * \param theH Height of chamfer.
2503 * \param theW Width of chamfer.
2504 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2505 * \param theP1 1st junction point of main pipe
2506 * \param theP2 2nd junction point of main pipe
2507 * \param theP3 Junction point of incident pipe
2508 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2510 //=============================================================================
2511 Handle(TColStd_HSequenceOfTransient)
2512 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2513 (double theR1, double theW1, double theL1,
2514 double theR2, double theW2, double theL2,
2515 double theRL, double theWL, double theLtransL, double theLthinL,
2516 double theRR, double theWR, double theLtransR, double theLthinR,
2517 double theRI, double theWI, double theLtransI, double theLthinI,
2518 double theH, double theW,
2520 Handle(GEOM_Object) theP1,
2521 Handle(GEOM_Object) theP2,
2522 Handle(GEOM_Object) theP3)
2526 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2527 //Add a new shape function with parameters
2528 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2529 if (aFunction.IsNull()) return NULL;
2531 //Check if the function is set correctly
2532 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2534 // Check new position
2535 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2539 AdvancedEngine_IPipeTShape aData(aFunction);
2549 aData.SetHexMesh(theHexMesh);
2551 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2552 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2553 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2555 //Compute the resulting value
2558 if (!GetSolver()->ComputeFunction(aFunction)) {
2559 SetErrorCode("TShape driver failed");
2563 catch (Standard_Failure) {
2564 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2565 SetErrorCode(aFail->GetMessageString());
2570 TopoDS_Shape aShapeShape = aShape->GetValue();
2571 TopTools_IndexedMapOfShape anEdgesIndices;
2572 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2573 // Common edges on external cylinders
2574 Handle(GEOM_Object) box_e;
2576 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2579 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2581 box_e->GetLastFunction()->SetDescription("");
2582 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2583 box_e->GetLastFunction()->SetDescription("");
2585 Handle(TColStd_HSequenceOfInteger) edges_e =
2586 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2587 box_e->GetLastFunction()->SetDescription("");
2589 if (edges_e.IsNull() || edges_e->Length() == 0) {
2590 SetErrorCode("External edges not found");
2593 int nbEdgesInChamfer = 0;
2594 std::list<int> theEdges;
2595 for (int i=1; i<=edges_e->Length();i++) {
2596 int edgeID = edges_e->Value(i);
2597 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2598 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2600 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2601 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2602 nbEdgesInChamfer ++;
2603 theEdges.push_back(edgeID);
2607 if (theHexMesh && nbEdgesInChamfer == 1)
2610 Handle(GEOM_Object) aChamfer;
2612 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2614 catch (Standard_Failure) {
2615 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2616 SetErrorCode(aFail->GetMessageString());
2619 if (aChamfer.IsNull()) {
2620 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2623 aChamfer->GetLastFunction()->SetDescription("");
2625 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2626 aFunction->SetValue(aChamferShape);
2630 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2632 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2636 // Add thickness reduction elements
2637 // at the three extremities: Left, Right and Incident
2640 if (isTRL || isTRR || isTRI) {
2641 TopoDS_Shape aResShape =
2642 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2643 theRL, theWL, theLtransL, theLthinL,
2644 theRR, theWR, theLtransR, theLthinR,
2645 theRI, theWI, theLtransI, theLthinI,
2647 aFunction->SetValue(aResShape);
2650 catch (Standard_Failure) {
2651 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2652 SetErrorCode(aFail->GetMessageString());
2657 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2658 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2659 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2660 aFunction->SetValue(aTrsf_Shape);
2662 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2663 aSeq->Append(aShape);
2668 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2669 theH, theW, 0., aSeq, aTrsf))
2673 // Get internal group.
2674 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2675 theRR, theLtransR, theRI, theLtransI,
2680 catch (Standard_Failure) {
2681 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2682 SetErrorCode(aFail->GetMessageString());
2686 //Make a Python command
2687 TCollection_AsciiString anEntry, aListRes("[");
2688 // Iterate over the sequence aSeq
2689 Standard_Integer aNbGroups = aSeq->Length();
2690 Standard_Integer i = 1;
2691 for (; i <= aNbGroups; i++) {
2692 Handle(Standard_Transient) anItem = aSeq->Value(i);
2693 if (anItem.IsNull()) continue;
2694 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2695 if (aGroup.IsNull()) continue;
2696 //Make a Python command
2697 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2698 aListRes += anEntry + ", ";
2700 aListRes.Trunc(aListRes.Length() - 2);
2702 GEOM::TPythonDump pd (aFunction);
2704 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2705 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2706 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2707 << theH << ", " << theW << ", " << theHexMesh << ", "
2708 << theP1 << ", " << theP2 << ", " << theP3;
2710 // thickness reduction
2712 pd << ", theRL=" << theRL << ", theWL=" << theWL
2713 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2715 pd << ", theRR=" << theRR << ", theWR=" << theWR
2716 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2718 pd << ", theRI=" << theRI << ", theWI=" << theWI
2719 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2728 //=============================================================================
2730 * MakePipeTShapeFillet
2731 * Create a T-shape object with specified caracteristics for the main and
2732 * the incident pipes (radius, width, half-length). A fillet is created
2733 * on the junction of the pipes.
2734 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2735 * \param theR1 Internal radius of main pipe
2736 * \param theW1 Width of main pipe
2737 * \param theL1 Half-length of main pipe
2738 * \param theR2 Internal radius of incident pipe (R2 < R1)
2739 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2740 * \param theL2 Half-length of incident pipe
2741 * \param theRF Radius of curvature of fillet.
2742 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2743 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2745 //=============================================================================
2746 Handle(TColStd_HSequenceOfTransient)
2747 AdvancedEngine_IOperations::MakePipeTShapeFillet
2748 (double theR1, double theW1, double theL1,
2749 double theR2, double theW2, double theL2,
2750 double theRL, double theWL, double theLtransL, double theLthinL,
2751 double theRR, double theWR, double theLtransR, double theLthinR,
2752 double theRI, double theWI, double theLtransI, double theLthinI,
2753 double theRF, bool theHexMesh)
2757 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2758 //Add a new shape function with parameters
2759 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2760 if (aFunction.IsNull()) return NULL;
2762 //Check if the function is set correctly
2763 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2765 AdvancedEngine_IPipeTShape aData(aFunction);
2774 aData.SetHexMesh(theHexMesh);
2776 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2777 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2778 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2780 //Compute the resulting value
2783 if (!GetSolver()->ComputeFunction(aFunction)) {
2784 SetErrorCode("TShape driver failed");
2788 catch (Standard_Failure) {
2789 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2790 SetErrorCode(aFail->GetMessageString());
2795 TopoDS_Shape aShapeShape = aShape->GetValue();
2796 TopTools_IndexedMapOfShape anEdgesIndices;
2797 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2798 // Common edges on external cylinders
2799 Handle(GEOM_Object) box_e;
2801 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2804 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2806 box_e->GetLastFunction()->SetDescription("");
2807 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2808 box_e->GetLastFunction()->SetDescription("");
2810 Handle(TColStd_HSequenceOfInteger) edges_e =
2811 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2812 box_e->GetLastFunction()->SetDescription("");
2814 if (edges_e.IsNull() || edges_e->Length() == 0) {
2815 SetErrorCode("External edges not found");
2818 int nbEdgesInFillet = 0;
2819 std::list<int> theEdges;
2820 for (int i=1; i<=edges_e->Length();i++) {
2821 int edgeID = edges_e->Value(i);
2822 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2823 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2825 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2826 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2828 theEdges.push_back(edgeID);
2832 if (theHexMesh && nbEdgesInFillet == 1)
2836 Handle(GEOM_Object) aFillet;
2838 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2840 catch (Standard_Failure) {
2841 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2842 SetErrorCode(aFail->GetMessageString());
2845 if (aFillet.IsNull()) {
2846 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2847 SetErrorCode(myLocalOperations->GetErrorCode());
2850 aFillet->GetLastFunction()->SetDescription("");
2852 TopoDS_Shape aFilletShape = aFillet->GetValue();
2854 #ifdef FILLET_FIX_TOLERANCE
2855 // VSR: 30/12/2014: temporary workaround about Fillet problem
2857 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
2860 GEOMUtils::FixShapeCurves(aFilletShape);
2864 aFunction->SetValue(aFilletShape);
2867 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2868 // the following block, when enabled, leads to partitioning problems
2870 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2871 // BEGIN: Limit tolerances (debug)
2872 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2873 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2874 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2875 aCorr1->GetLastFunction()->SetDescription("");
2876 // END: Limit tolerances (debug)
2877 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2879 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2882 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2884 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2888 // Add thickness reduction elements
2889 // at the three extremities: Left, Right and Incident
2892 if (isTRL || isTRR || isTRI) {
2893 TopoDS_Shape aResShape =
2894 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2895 theRL, theWL, theLtransL, theLthinL,
2896 theRR, theWR, theLtransR, theLthinR,
2897 theRI, theWI, theLtransI, theLthinI,
2899 aFunction->SetValue(aResShape);
2902 catch (Standard_Failure) {
2903 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2904 SetErrorCode(aFail->GetMessageString());
2908 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2909 aSeq->Append(aShape);
2914 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2915 0., 0., theRF, aSeq, gp_Trsf()))
2919 // Get internal group.
2920 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2921 theRR, theLtransR, theRI, theLtransI,
2926 catch (Standard_Failure) {
2927 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2928 SetErrorCode(aFail->GetMessageString());
2932 //Make a Python command
2933 TCollection_AsciiString anEntry, aListRes("[");
2934 // Iterate over the sequence aSeq
2935 Standard_Integer aNbGroups = aSeq->Length();
2936 Standard_Integer i = 1;
2937 for (; i <= aNbGroups; i++) {
2938 Handle(Standard_Transient) anItem = aSeq->Value(i);
2939 if (anItem.IsNull()) continue;
2940 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2941 if (aGroup.IsNull()) continue;
2942 //Make a Python command
2943 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2944 aListRes += anEntry + ", ";
2946 aListRes.Trunc(aListRes.Length() - 2);
2948 GEOM::TPythonDump pd (aFunction);
2950 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2951 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2952 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2953 << theRF << ", " << theHexMesh;
2955 // thickness reduction
2957 pd << ", theRL=" << theRL << ", theWL=" << theWL
2958 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2960 pd << ", theRR=" << theRR << ", theWR=" << theWR
2961 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2963 pd << ", theRI=" << theRI << ", theWI=" << theWI
2964 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2973 //=============================================================================
2975 * MakePipeTShapeFilletWithPosition
2976 * \brief Create a T-shape object with specified caracteristics for the main and
2977 * the incident pipes (radius, width, half-length). A fillet is created
2978 * on the junction of the pipes.
2979 * The extremities of the main pipe are located on junctions points P1 and P2.
2980 * The extremity of the incident pipe is located on junction point P3.
2981 * \param theR1 Internal radius of main pipe
2982 * \param theW1 Width of main pipe
2983 * \param theL1 Half-length of main pipe
2984 * \param theR2 Internal radius of incident pipe (R2 < R1)
2985 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2986 * \param theL2 Half-length of incident pipe
2987 * \param theRF Radius of curvature of fillet
2988 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2989 * \param theP1 1st junction point of main pipe
2990 * \param theP2 2nd junction point of main pipe
2991 * \param theP3 Junction point of incident pipe
2992 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2994 //=============================================================================
2995 Handle(TColStd_HSequenceOfTransient)
2996 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2997 (double theR1, double theW1, double theL1,
2998 double theR2, double theW2, double theL2,
2999 double theRL, double theWL, double theLtransL, double theLthinL,
3000 double theRR, double theWR, double theLtransR, double theLthinR,
3001 double theRI, double theWI, double theLtransI, double theLthinI,
3002 double theRF, bool theHexMesh,
3003 Handle(GEOM_Object) theP1,
3004 Handle(GEOM_Object) theP2,
3005 Handle(GEOM_Object) theP3)
3009 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
3010 //Add a new shape function with parameters
3011 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
3012 if (aFunction.IsNull()) return NULL;
3014 //Check if the function is set correctly
3015 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
3017 // Check new position
3018 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
3022 AdvancedEngine_IPipeTShape aData(aFunction);
3031 aData.SetHexMesh(theHexMesh);
3033 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
3034 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
3035 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
3037 //Compute the resulting value
3040 if (!GetSolver()->ComputeFunction(aFunction)) {
3041 SetErrorCode("TShape driver failed");
3045 catch (Standard_Failure) {
3046 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3047 SetErrorCode(aFail->GetMessageString());
3052 TopoDS_Shape aShapeShape = aShape->GetValue();
3053 TopTools_IndexedMapOfShape anEdgesIndices;
3054 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3055 // Common edges on external cylinders
3056 Handle(GEOM_Object) box_e;
3058 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3061 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3063 box_e->GetLastFunction()->SetDescription("");
3064 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3065 box_e->GetLastFunction()->SetDescription("");
3067 Handle(TColStd_HSequenceOfInteger) edges_e =
3068 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3069 box_e->GetLastFunction()->SetDescription("");
3071 if (edges_e.IsNull() || edges_e->Length() == 0) {
3072 SetErrorCode("External edges not found");
3075 int nbEdgesInFillet = 0;
3076 std::list<int> theEdges;
3077 for (int i=1; i<=edges_e->Length();i++) {
3078 int edgeID = edges_e->Value(i);
3079 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3080 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3082 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3083 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3085 theEdges.push_back(edgeID);
3089 if (theHexMesh && nbEdgesInFillet == 1)
3093 Handle(GEOM_Object) aFillet;
3095 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3097 catch (Standard_Failure) {
3098 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3099 SetErrorCode(aFail->GetMessageString());
3102 if (aFillet.IsNull()) {
3103 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3106 aFillet->GetLastFunction()->SetDescription("");
3108 TopoDS_Shape aFilletShape = aFillet->GetValue();
3110 #ifdef FILLET_FIX_TOLERANCE
3111 // VSR: 30/12/2014: temporary workaround about Fillet problem
3113 GEOMUtils::FixShapeTolerance(aFilletShape, TopAbs_FACE);
3116 GEOMUtils::FixShapeCurves(aFilletShape);
3120 aFunction->SetValue(aFilletShape);
3123 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3124 // the following block, when enabled, leads to partitioning problems
3126 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3127 // BEGIN: Limit tolerances (debug)
3128 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3129 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3130 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3131 aCorr1->GetLastFunction()->SetDescription("");
3132 // END: Limit tolerances (debug)
3133 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3135 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3138 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3140 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3144 // Add thickness reduction elements
3145 // at the three extremities: Left, Right and Incident
3148 if (isTRL || isTRR || isTRI) {
3149 TopoDS_Shape aResShape =
3150 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3151 theRL, theWL, theLtransL, theLthinL,
3152 theRR, theWR, theLtransR, theLthinR,
3153 theRI, theWI, theLtransI, theLthinI,
3155 aFunction->SetValue(aResShape);
3158 catch (Standard_Failure) {
3159 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3160 SetErrorCode(aFail->GetMessageString());
3165 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3166 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3167 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3168 aFunction->SetValue(aTrsf_Shape);
3170 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3171 aSeq->Append(aShape);
3176 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3177 0., 0., theRF, aSeq, aTrsf))
3181 // Get internal group.
3182 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3183 theRR, theLtransR, theRI, theLtransI,
3188 catch (Standard_Failure) {
3189 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3190 SetErrorCode(aFail->GetMessageString());
3194 //Make a Python command
3195 TCollection_AsciiString anEntry, aListRes("[");
3196 // Iterate over the sequence aSeq
3197 Standard_Integer aNbGroups = aSeq->Length();
3198 Standard_Integer i = 1;
3199 for (; i <= aNbGroups; i++) {
3200 Handle(Standard_Transient) anItem = aSeq->Value(i);
3201 if (anItem.IsNull()) continue;
3202 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3203 if (aGroup.IsNull()) continue;
3204 //Make a Python command
3205 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3206 aListRes += anEntry + ", ";
3208 aListRes.Trunc(aListRes.Length() - 2);
3210 GEOM::TPythonDump pd (aFunction);
3212 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3213 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3214 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3215 << theRF << ", " << theHexMesh << ", "
3216 << theP1 << ", " << theP2 << ", " << theP3;
3218 // thickness reduction
3220 pd << ", theRL=" << theRL << ", theWL=" << theWL
3221 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3223 pd << ", theRR=" << theRR << ", theWR=" << theWR
3224 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3226 pd << ", theRI=" << theRI << ", theWI=" << theWI
3227 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3236 //=============================================================================
3238 * This function allows to create a disk already divided into blocks. It can be
3239 * used to create divided pipes for later meshing in hexaedra.
3240 * \param theR Radius of the disk
3241 * \param theRatio Relative size of the central square diagonal against the disk diameter
3242 * \param theOrientation Plane on which the disk will be built
3243 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3244 * \return New GEOM_Object, containing the created shape.
3246 //=============================================================================
3247 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3248 int theOrientation, int thePattern)
3252 if (theOrientation != 1 &&
3253 theOrientation != 2 &&
3254 theOrientation != 3)
3256 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3260 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3262 //Add a new shape function with parameters
3263 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3264 if (aFunction.IsNull()) return NULL;
3266 //Check if the function is set correctly
3267 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3269 AdvancedEngine_IDividedDisk aData (aFunction);
3272 aData.SetRatio(theRatio);
3273 aData.SetOrientation(theOrientation);
3274 aData.SetType(thePattern);
3276 //Compute the resulting value
3279 if (!GetSolver()->ComputeFunction(aFunction)) {
3280 SetErrorCode("DividedDisk driver failed");
3284 catch (Standard_Failure) {
3285 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3286 SetErrorCode(aFail->GetMessageString());
3290 std::string aPatternStr;
3295 aPatternStr = "GEOM.SQUARE";
3298 aPatternStr = "GEOM.HEXAGON";
3302 //Make a Python command
3303 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3310 //=============================================================================
3312 * This function allows to create a disk already divided into blocks. It can be
3313 * used to create divided pipes for later meshing in hexaedra.
3314 * \param theR Radius of the disk
3315 * \param theRatio Relative size of the central square diagonal against the disk diameter
3316 * \return New GEOM_Object, containing the created shape.
3318 //=============================================================================
3319 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3320 Handle(GEOM_Object) theVec,
3328 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3330 //Add a new shape function with parameters
3331 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3332 if (aFunction.IsNull()) return NULL;
3334 //Check if the function is set correctly
3335 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3337 AdvancedEngine_IDividedDisk aData (aFunction);
3339 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3340 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3342 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3344 aData.SetCenter(aRefPnt);
3345 aData.SetVector(aRefVec);
3348 aData.SetRatio(theRatio);
3349 aData.SetType(thePattern);
3351 //Compute the resulting value
3354 if (!GetSolver()->ComputeFunction(aFunction)) {
3355 SetErrorCode("DividedDisk driver failed");
3359 catch (Standard_Failure) {
3360 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3361 SetErrorCode(aFail->GetMessageString());
3365 std::string aPatternStr;
3370 aPatternStr = "GEOM.SQUARE";
3373 aPatternStr = "GEOM.HEXAGON";
3378 //Make a Python command
3379 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3386 //=============================================================================
3388 * Builds a cylinder prepared for hexa meshes
3389 * \param theR Radius of the cylinder
3390 * \param theH Height of the cylinder
3391 * \return New GEOM_Object, containing the created shape.
3393 //=============================================================================
3394 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3401 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3403 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3404 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3406 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3408 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3409 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3410 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3412 std::string aPatternStr;
3417 aPatternStr = "GEOM.SQUARE";
3420 aPatternStr = "GEOM.HEXAGON";
3424 //Make a Python command
3425 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3431 //=============================================================================
3433 * Create a smoothing surface from a set of points
3434 * \param thelPoints list of points or compounds of points
3435 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3436 * \param theDegMax maximum degree of the resulting BSpline surface
3437 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3438 * \return New GEOM_Object, containing the created shape.
3440 //=============================================================================
3441 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3449 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3451 //Add a new shape function with parameters
3452 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3453 if (aFunction.IsNull()) return NULL;
3455 //Check if the function is set correctly
3456 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3458 AdvancedEngine_ISmoothingSurface aData (aFunction);
3460 int aLen = thelPoints.size();
3461 aData.SetLength(aLen);
3463 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3464 for (; it != thelPoints.end(); it++, ind++) {
3465 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3466 if (aRefObj.IsNull()) {
3467 SetErrorCode("NULL point or compound for bSplineFaceShape");
3470 aData.SetPntOrComp(ind, aRefObj);
3473 aData.SetNbMax(theNbMax);
3474 aData.SetDegMax(theDegMax);
3475 aData.SetDMax(theDMax);
3477 //Compute the resulting value
3480 if (!GetSolver()->ComputeFunction(aFunction)) {
3481 SetErrorCode("SmoothingSurface driver failed");
3485 catch (Standard_Failure) {
3486 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3487 SetErrorCode(aFail->GetMessageString());
3491 //Make a Python command
3492 GEOM::TPythonDump pd (aFunction);
3493 pd << aShape << " = geompy.MakeSmoothingSurface([";
3494 it = thelPoints.begin();
3496 while (it != thelPoints.end()) {
3497 pd << ", " << (*it++);
3501 << theDegMax << ", "