1 // Copyright (C) 2007-2013 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.
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 : GEOMImpl_IAdvancedOperations.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 #include "GEOMImpl_IAdvancedOperations.hxx"
24 #include <Basics_OCCTVersion.hxx>
26 #include <utilities.h>
28 #include <Utils_ExceptHandlers.hxx>
30 #include "GEOM_Function.hxx"
31 #include "GEOM_PythonDump.hxx"
32 #include "GEOMUtils.hxx"
33 #include "GEOMAlgo_Splitter.hxx"
34 #include "GEOMAlgo_FinderShapeOn1.hxx"
36 #include "GEOMImpl_Gen.hxx"
37 #include "GEOMImpl_Types.hxx"
39 #include "GEOMImpl_IBasicOperations.hxx"
40 #include "GEOMImpl_IBooleanOperations.hxx"
41 #include "GEOMImpl_IShapesOperations.hxx"
42 #include "GEOMImpl_ITransformOperations.hxx"
43 #include "GEOMImpl_IBlocksOperations.hxx"
44 #include "GEOMImpl_I3DPrimOperations.hxx"
45 #include "GEOMImpl_ILocalOperations.hxx"
46 #include "GEOMImpl_IHealingOperations.hxx"
47 #include "GEOMImpl_IGroupOperations.hxx"
49 #include "GEOMImpl_GlueDriver.hxx"
50 #include "GEOMImpl_PipeTShapeDriver.hxx"
51 #include "GEOMImpl_IPipeTShape.hxx"
52 #include "GEOMImpl_DividedDiskDriver.hxx"
53 #include "GEOMImpl_IDividedDisk.hxx"
54 // #include "GEOMImpl_DividedCylinderDriver.hxx"
55 // #include "GEOMImpl_IDividedCylinder.hxx"
56 #include <GEOMImpl_SmoothingSurfaceDriver.hxx>
57 #include <GEOMImpl_ISmoothingSurface.hxx>
58 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/
60 #include <TDF_Tool.hxx>
61 #include <TFunction_DriverTable.hxx>
62 #include <TFunction_Driver.hxx>
63 #include <TFunction_Logbook.hxx>
64 #include <TNaming_CopyShape.hxx>
67 #include <TopExp_Explorer.hxx>
69 #include <TopoDS_Vertex.hxx>
70 #include <TopTools_IndexedMapOfShape.hxx>
71 #include <TopTools_ListIteratorOfListOfShape.hxx>
72 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
74 #include <BRep_Builder.hxx>
75 #include <BRep_Tool.hxx>
77 #include <BRepAdaptor_Surface.hxx>
78 #include <BRepAlgoAPI_Cut.hxx>
79 #include <BRepAlgoAPI_Fuse.hxx>
80 #include <BRepBuilderAPI_MakeFace.hxx>
81 #include <BRepBuilderAPI_MakeVertex.hxx>
82 #include <BRepBuilderAPI_Transform.hxx>
83 #include <BRepPrimAPI_MakeCone.hxx>
84 #include <BRepPrimAPI_MakeCylinder.hxx>
90 #include <GC_MakeConicalSurface.hxx>
91 #include <Geom_CylindricalSurface.hxx>
95 #include <Standard_Stream.hxx>
96 #include <Standard_Failure.hxx>
97 #include <StdFail_NotDone.hxx>
98 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
100 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
101 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
102 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
103 #define THICKNESS "Thickness" //"Epaisseur"
104 #define FLANGE "Flange" // "Collerette"
105 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
106 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
107 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
108 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
110 #define FIND_GROUPS_BY_POINTS 1
112 //=============================================================================
116 //=============================================================================
117 GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations(GEOM_Engine* theEngine, int theDocID) :
118 GEOM_IOperations(theEngine, theDocID)
120 MESSAGE("GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations");
121 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
122 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
123 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
124 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
125 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
126 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
127 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
128 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
129 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
132 //=============================================================================
136 //=============================================================================
137 GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations()
139 MESSAGE("GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations");
140 delete myBasicOperations;
141 delete myBooleanOperations;
142 delete myShapesOperations;
143 delete myTransformOperations;
144 delete myBlocksOperations;
145 delete my3DPrimOperations;
146 delete myLocalOperations;
147 delete myHealingOperations;
148 delete myGroupOperations;
151 //=============================================================================
155 //=============================================================================
156 gp_Trsf GEOMImpl_IAdvancedOperations::GetPositionTrsf(double theL1, double theL2,
157 Handle(GEOM_Object) theP1,
158 Handle(GEOM_Object) theP2,
159 Handle(GEOM_Object) theP3)
161 // Old Local Coordinates System oldLCS
163 gp_Pnt P1(-theL1, 0, 0);
164 gp_Pnt P2(theL1, 0, 0);
165 gp_Pnt P3(0, 0, theL2);
167 gp_Dir oldX(gp_Vec(P1, P2));
168 gp_Dir oldZ(gp_Vec(P0, P3));
169 gp_Ax3 oldLCS(P0, oldZ, oldX);
171 // New Local Coordinates System newLCS
172 double LocX, LocY, LocZ;
173 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
174 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
175 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
176 LocX = (newP1.X() + newP2.X()) / 2.;
177 LocY = (newP1.Y() + newP2.Y()) / 2.;
178 LocZ = (newP1.Z() + newP2.Z()) / 2.;
179 gp_Pnt newO(LocX, LocY, LocZ);
181 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
182 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
183 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
186 aTrsf.SetDisplacement(oldLCS, newLCS);
191 //=============================================================================
193 * CheckCompatiblePosition
196 //=============================================================================
197 bool GEOMImpl_IAdvancedOperations::CheckCompatiblePosition(double& theL1, double& theL2,
198 Handle(GEOM_Object) theP1,
199 Handle(GEOM_Object) theP2,
200 Handle(GEOM_Object) theP3,
204 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
205 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
206 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
208 double d12 = P1.Distance(P2);
209 double d13 = P1.Distance(P3);
210 double d23 = P2.Distance(P3);
211 // double d2 = newO.Distance(P3);
213 if (Abs(d12) <= Precision::Confusion()) {
214 SetErrorCode("Junctions points P1 and P2 are identical");
217 if (Abs(d13) <= Precision::Confusion()) {
218 SetErrorCode("Junctions points P1 and P3 are identical");
221 if (Abs(d23) <= Precision::Confusion()) {
222 SetErrorCode("Junctions points P2 and P3 are identical");
227 double newL1 = 0.5 * d12;
228 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
230 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
232 if (fabs(newL1 - theL1) > Precision::Approximation()) {
233 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
234 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
235 // std::cerr << "theL1 = newL1" << std::endl;
239 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
245 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
247 if (fabs(newL2 - theL2) > Precision::Approximation()) {
248 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
249 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
253 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
263 //=============================================================================
265 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
267 //=============================================================================
268 bool GEOMImpl_IAdvancedOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
269 double theR1, double theW1, double theL1,
270 double theR2, double theW2, double theL2,
271 double theH, double theW, double theRF,
272 Handle(TColStd_HSequenceOfTransient) theSeq,
277 if (theShape.IsNull()) return false;
279 TopoDS_Shape aShape = theShape->GetValue();
280 if (aShape.IsNull()) {
281 SetErrorCode("Shape is not defined");
285 gp_Trsf aTrsfInv = aTrsf.Inverted();
287 // int expectedGroups = 0;
288 // if (shapeType == TSHAPE_BASIC)
289 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
290 // expectedGroups = 10;
292 // expectedGroups = 11;
293 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
294 // expectedGroups = 12;
296 double aR1Ext = theR1 + theW1;
297 double aR2Ext = theR2 + theW2;
299 /////////////////////////
300 //// Groups of Faces ////
301 /////////////////////////
304 // Comment the following lines when GetInPlace bug is solved
306 // Workaround of GetInPlace bug
307 // Create a bounding box that fits the shape
308 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
309 aBox->GetLastFunction()->SetDescription("");
310 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
311 aBox->GetLastFunction()->SetDescription("");
312 // Apply transformation to box
313 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
314 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
315 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
317 // Get the shell of the box
318 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
319 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
320 aBox->GetLastFunction()->SetDescription("");
321 aShell->GetLastFunction()->SetDescription("");
322 // Get the common shapes between shell and shape
323 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean (theShape, aShell, 1); // MakeCommon
324 if (aCommonCompound.IsNull()) {
325 SetErrorCode(myBooleanOperations->GetErrorCode());
328 aCommonCompound->GetLastFunction()->SetDescription("");
329 // Explode the faces of common shapes => 3 faces
330 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
331 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
332 aCommonCompound->GetLastFunction()->SetDescription("");
333 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
335 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
336 std::list<Handle(GEOM_Object)> aFacesList;
337 for (int j = 1 ; j <= 4 ; j++) {
338 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
339 if (!aFace.IsNull()) {
340 aFace->GetLastFunction()->SetDescription("");
341 aFacesList.push_back(aFace);
344 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
345 if (!aCompoundOfFaces.IsNull()) {
346 aCompoundOfFaces->GetLastFunction()->SetDescription("");
347 aCompoundOfFacesList.push_back(aCompoundOfFaces);
351 if (aCompoundOfFacesList.size() == 3) {
352 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
353 aCompoundOfFacesList.pop_front();
354 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
355 aCompoundOfFacesList.pop_front();
356 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
357 aCompoundOfFacesList.pop_front();
362 // Uncomment the following lines when GetInPlace bug is solved
364 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
365 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
366 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
367 // aP1->GetLastFunction()->SetDescription("");
368 // aP2->GetLastFunction()->SetDescription("");
369 // aP3->GetLastFunction()->SetDescription("");
370 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
371 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
372 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
373 // aV1->GetLastFunction()->SetDescription("");
374 // aV2->GetLastFunction()->SetDescription("");
375 // aV3->GetLastFunction()->SetDescription("");
376 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
377 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
378 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
379 // aPln1->GetLastFunction()->SetDescription("");
380 // aPln2->GetLastFunction()->SetDescription("");
381 // aPln3->GetLastFunction()->SetDescription("");
383 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
384 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
385 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
386 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
387 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
388 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
389 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
390 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
391 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
395 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
396 if (junctionFaces1.IsNull())
397 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
398 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
399 if (!junctionFaces1.IsNull()) {
400 junctionFaces1->GetLastFunction()->SetDescription("");
401 junctionFaces1->SetName("JUNCTION_FACE_1");
402 theSeq->Append(junctionFaces1);
405 SetErrorCode("Junction face 1 not found");
406 // theSeq->Append(aPln1);
409 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
410 if (junctionFaces2.IsNull())
411 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
412 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
413 if (!junctionFaces2.IsNull()) {
414 junctionFaces2->GetLastFunction()->SetDescription("");
415 junctionFaces2->SetName("JUNCTION_FACE_2");
416 theSeq->Append(junctionFaces2);
419 SetErrorCode("Junction face 2 not found");
420 // theSeq->Append(aPln2);
423 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
424 if (junctionFaces3.IsNull())
425 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
426 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
427 if (!junctionFaces3.IsNull()) {
428 junctionFaces3->GetLastFunction()->SetDescription("");
429 junctionFaces3->SetName("JUNCTION_FACE_3");
430 theSeq->Append(junctionFaces3);
433 SetErrorCode("Junction face 3 not found");
434 // theSeq->Append(aPln3);
437 // Comment the following lines when GetInPlace bug is solved
442 /////////////////////////
443 //// Groups of Edges ////
444 /////////////////////////
445 // Result of propagate
447 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
449 TCollection_AsciiString theDesc = aFunction->GetDescription();
450 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
451 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
452 SetErrorCode("Propagation groups not found");
455 Standard_Integer aNbGroups = aSeqPropagate->Length();
456 // Recover previous description to get rid of Propagate dump
457 aFunction->SetDescription(theDesc);
459 #ifdef FIND_GROUPS_BY_POINTS
460 // BEGIN: new groups search
467 // g / ''..| | |..'' \
469 // .---.--'.. | | | ..'--.---.
470 // |a \ '''...........''' / |
471 // |-------\------' | '------/-------.
476 // ._________________|_________________.
482 // |-----------------|-----------------|
484 // '-----------------'-----------------'
487 // "Thickness" group (a)
488 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
489 aPntA.Transform(aTrsf);
490 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
491 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
492 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
494 // "Circular quarter of pipe" group (b)
495 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
496 aPntB.Transform(aTrsf);
497 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
498 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
499 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
501 // "Circular quarter of pipe" group (c)
502 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
503 aPntC.Transform(aTrsf);
504 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
505 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
506 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
508 // "Main pipe half length" group (d)
509 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
510 aPntD.Transform(aTrsf);
511 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
512 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
513 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
515 // "Incident pipe half length" group (e)
516 double aTol10 = Precision::Confusion() * 10.;
517 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
518 aPntE.Transform(aTrsf);
519 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
520 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
521 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
523 // "Flange" group (f)
524 double aFx = - aR2Ext - aTol10;
525 if (shapeType == TSHAPE_CHAMFER)
527 else if (shapeType == TSHAPE_FILLET)
529 gp_Pnt aPntF (aFx, 0, aR1Ext);
530 aPntF.Transform(aTrsf);
531 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
532 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
533 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
535 // "Chamfer or Fillet" group (g)
536 TopoDS_Shape anEdgeG;
537 if (shapeType == TSHAPE_CHAMFER) {
538 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
539 aPntG.Transform(aTrsf);
540 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
541 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
542 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
544 else if (shapeType == TSHAPE_FILLET) {
545 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
546 aPntG.Transform(aTrsf);
547 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
548 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
549 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
552 for (int i = 1 ; i <= aNbGroups; i++) {
553 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
557 TopoDS_Shape aGroupShape = aGroup->GetValue();
558 TopTools_IndexedMapOfShape anEdgesMap;
559 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
561 if (anEdgesMap.Contains(anEdgeA)) { // a
562 aGroup->SetName("THICKNESS");
563 theSeq->Append(aGroup);
565 else if (anEdgesMap.Contains(anEdgeB)) { // b
566 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
567 theSeq->Append(aGroup);
569 else if (anEdgesMap.Contains(anEdgeC)) { // c
570 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
571 theSeq->Append(aGroup);
573 else if (anEdgesMap.Contains(anEdgeD)) { // d
574 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
575 theSeq->Append(aGroup);
577 else if (anEdgesMap.Contains(anEdgeE)) { // e
578 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
579 theSeq->Append(aGroup);
581 else if (anEdgesMap.Contains(anEdgeF)) { // f
582 aGroup->SetName("FLANGE");
583 theSeq->Append(aGroup);
585 else if (shapeType == TSHAPE_CHAMFER) { // g
586 if (anEdgesMap.Contains(anEdgeG)) {
587 aGroup->SetName("CHAMFER");
588 theSeq->Append(aGroup);
591 else if (shapeType == TSHAPE_FILLET) { // g
592 if (anEdgesMap.Contains(anEdgeG)) {
593 aGroup->SetName("FILLET");
594 theSeq->Append(aGroup);
600 // END: new groups search
603 bool circularFoundAndAdded = false;
604 bool circularFound10 = false;
605 bool incidentPipeFound = false;
606 bool mainPipeFound = false;
607 bool mainPipeFoundAndAdded = false;
608 bool radialFound =false;
609 bool flangeFound = false;
610 bool flangeFoundAndAdded = false;
611 bool chamferOrFilletFound = false;
613 for (int i = 1 ; i <= aNbGroups; i++) {
616 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
620 TopoDS_Shape aGroupShape = aGroup->GetValue();
621 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
622 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
624 TopTools_IndexedMapOfShape anEdgesMap;
625 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
626 Standard_Integer nbEdges = anEdgesMap.Extent();
628 if (shapeType == TSHAPE_BASIC) {
629 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
631 aGroup->SetName("THICKNESS");
633 else if (nbEdges == 6) {
634 if (!circularFoundAndAdded) {
635 circularFoundAndAdded = true;
637 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
640 else if (nbEdges == 8) {
641 incidentPipeFound = true;
642 mainPipeFound = false;
646 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
648 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
649 double x=aP.X(), y=aP.Y(), z=aP.Z();
652 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
653 (Abs(y) > aR2Ext + Precision::Confusion())) {
654 incidentPipeFound = false;
657 if ( z < -Precision::Confusion()) {
658 // length of main pipe
659 mainPipeFound = true;
660 if (!mainPipeFoundAndAdded) {
661 mainPipeFoundAndAdded = true;
663 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
667 else if (Abs(x) > (theL1-Precision::Confusion())) {
668 // discretisation circulaire
670 if (!circularFoundAndAdded) {
671 circularFoundAndAdded = true;
673 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
678 if (incidentPipeFound) {
680 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
682 if (!addGroup && (!incidentPipeFound &&
686 // Flange (collerette)
689 aGroup->SetName("FLANGE");
695 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
696 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
698 aGroup->SetName("THICKNESS");
700 else if ((nbEdges == 10) || (nbEdges == 6)) {
701 if (!circularFoundAndAdded) {
703 circularFoundAndAdded = true;
704 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
706 circularFound10 = true;
709 else if (!circularFound10 && nbEdges == 10) {
710 circularFound10 = true;
712 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
715 else if (nbEdges == 8) {
716 incidentPipeFound = true;
717 mainPipeFound = true;
720 bool isNearZ0 = false;
721 bool isBelowZ0 = false;
723 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
725 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
726 double x=aP.X(), y=aP.Y(), z=aP.Z();
728 // tuy_princ_long_avant & tuy_princ_long_apres
729 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
730 // ((y <= aR1Ext + Precision::Confusion()) ||
731 // (y <= -(aR1Ext + Precision::Confusion())) ||
732 // (y <= theR1 + Precision::Confusion()) ||
733 // (y == -(theR1 + Precision::Confusion()))));
734 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
735 (fabs(y) > theR1 - Precision::Confusion() ||
736 fabs(y) < Precision::Confusion()));
739 mainPipeFound = false;
743 //if (z < Precision::Confusion() && !isMain) {
744 // flangeFound = true;
745 // if (!flangeFoundAndAdded) {
746 // flangeFoundAndAdded = true;
748 // aGroup->SetName("FLANGE");
751 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
752 if (z < - Precision::Confusion()) isBelowZ0 = true;
755 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
756 (Abs(y) > aR2Ext + Precision::Confusion())) {
757 incidentPipeFound = false;
763 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
765 if (incidentPipeFound) {
767 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
769 if (isNearZ0 && !isBelowZ0) {
771 if (!flangeFoundAndAdded) {
772 flangeFoundAndAdded = true;
774 aGroup->SetName("FLANGE");
777 if (!addGroup && (!incidentPipeFound &&
780 !chamferOrFilletFound)) {
782 chamferOrFilletFound = true;
783 if (shapeType == TSHAPE_CHAMFER)
784 aGroup->SetName("CHAMFER");
786 aGroup->SetName("FILLET");
792 // Add group to the list
794 theSeq->Append(aGroup);
802 //=============================================================================
804 * Return faces that are laying on surface.
806 //=============================================================================
807 bool GEOMImpl_IAdvancedOperations::GetFacesOnSurf
808 (const TopoDS_Shape &theShape,
809 const Handle_Geom_Surface& theSurface,
810 const Standard_Real theTolerance,
811 TopTools_ListOfShape &theFaces)
813 GEOMAlgo_FinderShapeOn1 aFinder;
815 aFinder.SetShape(theShape);
816 aFinder.SetTolerance(theTolerance);
817 aFinder.SetSurface(theSurface);
818 aFinder.SetShapeType(TopAbs_FACE);
819 aFinder.SetState(GEOMAlgo_ST_ON);
821 // Sets the minimal number of inner points for the faces that do not have own
822 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
824 aFinder.SetNbPntsMin(3);
825 // Sets the maximal number of inner points for edges or faces.
826 // It is usefull for the cases when this number is very big (e.g =2000) to improve
827 // the performance. If this value =0, all inner points will be taken into account.
829 aFinder.SetNbPntsMax(100);
832 // Interprete results
833 Standard_Integer iErr = aFinder.ErrorStatus();
834 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
836 MESSAGE(" iErr : " << iErr);
837 TCollection_AsciiString aMsg (" iErr : ");
838 aMsg += TCollection_AsciiString(iErr);
842 Standard_Integer iWrn = aFinder.WarningStatus();
843 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
845 MESSAGE(" *** iWrn : " << iWrn);
848 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
849 TopTools_ListIteratorOfListOfShape anIter (aListRes);
851 for (; anIter.More(); anIter.Next()) {
852 theFaces.Append(anIter.Value());
858 //=============================================================================
860 * Creates and returns conical face.
862 //=============================================================================
863 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakeConicalFace
864 (const gp_Ax2 &theAxis,
865 const double theRadius,
866 const double theRadiusThin,
867 const double theHeight,
868 const gp_Trsf &theTrsf)
870 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
871 TopoDS_Shape aResult;
874 if (aMkCone.IsDone()) {
875 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
877 for (; anExp.More(); anExp.Next()) {
878 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
880 if (aFace.IsNull() == Standard_False) {
881 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
883 if (anAdaptor.GetType() == GeomAbs_Cone) {
884 // This is a conical face. Transform and return it.
885 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
887 aResult = aTransf.Shape();
897 //=============================================================================
899 * Generate the internal group of a Pipe T-Shape
901 //=============================================================================
902 bool GEOMImpl_IAdvancedOperations::MakeInternalGroup
903 (const Handle(GEOM_Object) &theShape,
904 const double theR1, const double theLen1,
905 const double theR2, const double theLen2,
906 const double theRL, double theTransLenL,
907 const double theRR, double theTransLenR,
908 const double theRI, double theTransLenI,
909 const Handle(TColStd_HSequenceOfTransient) &theSeq,
910 const gp_Trsf &theTrsf)
914 if (theShape.IsNull()) {
918 TopoDS_Shape aShape = theShape->GetValue();
920 if (aShape.IsNull()) {
921 SetErrorCode("Shape is not defined");
926 Standard_Real aMaxTol = -RealLast();
927 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
929 for (; anExp.More(); anExp.Next()) {
930 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
932 if (aVertex.IsNull() == Standard_False) {
933 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
935 if (aTol > aMaxTol) {
941 // Construct internal surfaces.
942 Standard_Integer i = 0;
943 const Standard_Integer aMaxNbSurf = 5;
944 Handle(Geom_Surface) aSurface[aMaxNbSurf];
945 TopTools_ListOfShape aConicalFaces;
946 Standard_Real aTolConf = Precision::Confusion();
948 // 1. Construct the internal surface of main pipe.
949 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
950 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
952 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
954 // 2. Construct the internal surface of incident pipe.
955 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
957 // 3. Construct the internal surface of left reduction pipe.
958 if (theRL > aTolConf) {
959 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
961 if (theTransLenL > aTolConf) {
962 // 3.1. Construct the internal surface of left transition pipe.
963 gp_Pnt aPLeft (-theLen1, 0., 0.);
964 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
965 TopoDS_Shape aConeLeft =
966 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
968 if (aConeLeft.IsNull() == Standard_False) {
969 aConicalFaces.Append(aConeLeft);
974 // 4. Construct the internal surface of right reduction pipe.
975 if (theRR > aTolConf) {
976 // There is no need to construct another cylinder of the same radius. Skip it.
977 if (Abs(theRR - theRL) > aTolConf) {
978 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
981 if (theTransLenL > aTolConf) {
982 // 4.1. Construct the internal surface of right transition pipe.
983 gp_Pnt aPRight (theLen1, 0., 0.);
984 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
985 TopoDS_Shape aConeRight =
986 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
988 if (aConeRight.IsNull() == Standard_False) {
989 aConicalFaces.Append(aConeRight);
994 // 5. Construct the internal surface of incident reduction pipe.
995 if (theRI > aTolConf) {
996 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
998 if (theTransLenI > aTolConf) {
999 // 5.1. Construct the internal surface of incident transition pipe.
1000 gp_Pnt aPInci (0., 0., theLen2);
1001 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1002 TopoDS_Shape aConeInci =
1003 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1005 if (aConeInci.IsNull() == Standard_False) {
1006 aConicalFaces.Append(aConeInci);
1011 // Get faces that are laying on cylindrical surfaces.
1012 TopTools_ListOfShape aFaces;
1013 gp_Trsf anInvTrsf = theTrsf.Inverted();
1015 for (i = 0; i < aMaxNbSurf; i++) {
1016 if (aSurface[i].IsNull()) {
1020 aSurface[i]->Transform(theTrsf);
1022 TopTools_ListOfShape aLocalFaces;
1024 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1029 // Check if the result contains outer cylinders.
1030 // It is required for main and incident pipes.
1031 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1033 while (anIter.More()) {
1034 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1035 Standard_Boolean isInside = Standard_False;
1037 // Get a vertex from this shape
1039 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1041 if (aVtx.IsNull() == Standard_False) {
1042 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1044 aPnt.Transform(anInvTrsf);
1047 // Check if the point is inside the main pipe.
1048 isInside = (Abs(aPnt.X()) <= theLen1);
1050 // Check if the point is inside the incident pipe.
1051 isInside = (aPnt.Z() <= theLen2);
1060 // Remove this face.
1061 aLocalFaces.Remove(anIter);
1066 aFaces.Append(aLocalFaces);
1069 // Get faces that are laying on conical faces.
1070 if (aConicalFaces.IsEmpty() == Standard_False) {
1071 Handle(GEOM_Object) aCone =
1072 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1073 Handle(GEOM_Function) aFunction =
1074 aCone->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1075 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1076 Handle(GEOM_Object) aConeFromShape;
1078 for (; aFIter.More(); aFIter.Next()) {
1079 aFunction->SetValue(aFIter.Value());
1080 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1082 if (aConeFromShape.IsNull() == Standard_False) {
1083 aConeFromShape->GetLastFunction()->SetDescription("");
1084 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1085 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1087 for (; anExp.More(); anExp.Next()) {
1088 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1090 if (aConeFace.IsNull() == Standard_False) {
1091 aFaces.Append(aConeFace);
1098 // Create a group of internal faces.
1099 if (aFaces.IsEmpty() == Standard_False) {
1100 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1102 if (aGroup.IsNull() == Standard_False) {
1103 aGroup->GetLastFunction()->SetDescription("");
1104 aGroup->SetName("INTERNAL_FACES");
1106 TopTools_IndexedMapOfShape anIndices;
1107 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1109 TopExp::MapShapes(aShape, anIndices);
1111 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1113 for (; anIter.More(); anIter.Next()) {
1114 const TopoDS_Shape &aFace = anIter.Value();
1115 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1118 aSeqIDs->Append(anIndex);
1122 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1123 aGroup->GetLastFunction()->SetDescription("");
1124 theSeq->Append(aGroup);
1133 bool GEOMImpl_IAdvancedOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1134 double theR1, double theW1, double theL1,
1135 double theR2, double theW2, double theL2,
1136 double theH, double theW,
1137 double theRF, bool isNormal)
1141 // Build tools for partition operation:
1142 // 1 face and 2 planes
1144 Handle(GEOM_Object) arete_intersect_int;
1145 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1146 Handle(GEOM_Object) chan_racc;
1147 Handle(GEOM_Object) vi1, vi2;
1148 Handle(GEOM_Object) Te3;
1151 #if OCC_VERSION_LARGE > 0x06010000
1154 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1155 Vector_Z->GetLastFunction()->SetDescription("");
1158 double aSize = 2*(theL1 + theL2);
1159 double aR1Ext = theR1 + theW1;
1160 double aR2Ext = theR2 + theW2;
1161 double theVertCylinderRadius = aR2Ext + theW + theRF;
1162 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1164 // Common edges on internal cylinder
1165 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1166 box_i->GetLastFunction()->SetDescription("");
1167 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1168 box_i->GetLastFunction()->SetDescription("");
1170 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1171 TCollection_AsciiString theDesc = aFunction->GetDescription();
1172 Handle(TColStd_HSequenceOfTransient) edges_i =
1173 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1174 // Recover previous description to get rid of Propagate dump
1175 aFunction->SetDescription(theDesc);
1176 if (edges_i.IsNull() || edges_i->Length() == 0) {
1177 SetErrorCode("Internal edges not found");
1180 for (int i=1; i<=edges_i->Length();i++) {
1181 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1182 anObj->GetLastFunction()->SetDescription("");
1184 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1186 // search for vertices located on both internal pipes
1187 aFunction = theShape->GetLastFunction();
1188 theDesc = aFunction->GetDescription();
1189 Handle(TColStd_HSequenceOfTransient) vertices_i =
1190 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1191 // Recover previous description to get rid of Propagate dump
1192 aFunction->SetDescription(theDesc);
1193 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1194 SetErrorCode("Internal vertices not found");
1198 for (int i = 1; i <= vertices_i->Length(); i++) {
1199 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1200 v->GetLastFunction()->SetDescription("");
1201 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1202 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1203 // std::cout << "Coords: " << aP.X() << ", " << aP.Y() << ", " << aP.Z() << std::endl;
1204 if (Abs(aP.X()) <= Precision::Confusion()) {
1205 if (Abs(aP.Y()) - theR1 <= Precision::Confusion()) {
1208 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1209 if (Abs(aP.X()) - theR1 <= Precision::Confusion()) {
1215 std::list<Handle(GEOM_Object)> theShapes;
1218 Handle(GEOM_Object) ve1, ve2;
1220 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1221 box_e->GetLastFunction()->SetDescription("");
1222 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1223 box_e->GetLastFunction()->SetDescription("");
1224 // Common edges on external cylinder
1225 aFunction = theShape->GetLastFunction();
1226 theDesc = aFunction->GetDescription();
1227 Handle(TColStd_HSequenceOfTransient) edges_e =
1228 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1229 // Recover previous description to get rid of Propagate dump
1230 aFunction->SetDescription(theDesc);
1231 if (edges_e.IsNull() || edges_e->Length() == 0) {
1232 SetErrorCode("External edges not found");
1235 for (int i=1; i<=edges_e->Length();i++) {
1236 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1237 anObj->GetLastFunction()->SetDescription("");
1240 // search for vertices located on both external pipes
1241 aFunction = theShape->GetLastFunction();
1242 theDesc = aFunction->GetDescription();
1243 Handle(TColStd_HSequenceOfTransient) vertices_e =
1244 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1245 // Recover previous description to get rid of Propagate dump
1246 aFunction->SetDescription(theDesc);
1247 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1248 SetErrorCode("External vertices not found");
1252 for (int i = 1; i <= vertices_e->Length(); i++) {
1253 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1254 v->GetLastFunction()->SetDescription("");
1255 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1256 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1257 // std::cout << "Coords: " << aP.X() << ", " << aP.Y() << ", " << aP.Z() << std::endl;
1258 if (Abs(aP.X()) <= Precision::Confusion()) {
1259 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1262 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1263 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1267 if ( !ve1.IsNull() && !ve2.IsNull())
1270 Handle(GEOM_Object) edge_e1, edge_e2;
1272 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1273 if (edge_e1.IsNull()) {
1274 SetErrorCode("Edge 1 could not be built");
1278 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1279 if (edge_e2.IsNull()) {
1280 SetErrorCode("Edge 2 could not be built");
1284 edge_e1->GetLastFunction()->SetDescription("");
1285 edge_e2->GetLastFunction()->SetDescription("");
1287 std::list<Handle(GEOM_Object)> edge_e_elist;
1288 edge_e_elist.push_back(arete_intersect_int);
1289 edge_e_elist.push_back(edge_e1);
1290 edge_e_elist.push_back(Handle(GEOM_Object)::DownCast(edges_e->Value(1)));
1291 edge_e_elist.push_back(edge_e2);
1292 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1293 if (wire_t.IsNull()) {
1294 SetErrorCode("Impossible to build wire");
1297 wire_t->GetLastFunction()->SetDescription("");
1298 face_t = myShapesOperations->MakeFace(wire_t, false);
1299 if (face_t.IsNull()) {
1300 SetErrorCode("Impossible to build face");
1303 face_t->GetLastFunction()->SetDescription("");
1305 theShapes.push_back(theShape);
1306 theShapes.push_back(vi1);
1307 theShapes.push_back(vi2);
1308 theShapes.push_back(ve1);
1309 theShapes.push_back(ve2);
1310 theShapes.push_back(edge_e1);
1311 theShapes.push_back(edge_e2);
1312 theShapes.push_back(wire_t);
1313 theShapes.push_back(face_t);
1316 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1317 int idP1, idP2, idP3, idP4;
1320 std::vector<int> LX;
1321 std::vector<int> LY;
1322 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1323 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1324 box_e->GetLastFunction()->SetDescription("");
1325 box_e = myTransformOperations->TranslateDXDYDZ
1326 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1327 box_e->GetLastFunction()->SetDescription("");
1329 aFunction = theShape->GetLastFunction();
1330 theDesc = aFunction->GetDescription();
1331 Handle(TColStd_HSequenceOfTransient) extremVertices =
1332 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1333 // Recover previous description to get rid of Propagate dump
1334 aFunction->SetDescription(theDesc);
1336 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1338 SetErrorCode("Vertices on chamfer not found");
1340 SetErrorCode("Vertices on fillet not found");
1344 theShapes.push_back(theShape);
1345 theShapes.push_back(box_e);
1346 if (extremVertices->Length() != 6) {
1347 // for (int i=1; i<=extremVertices->Length(); i++){
1348 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1350 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1351 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1352 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1353 SetErrorCode("Bad number of vertices on chamfer found");
1357 for (int i=1; i<=extremVertices->Length(); i++){
1358 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1359 aV->GetLastFunction()->SetDescription("");
1360 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1362 if (Abs(aP.X()) <= Precision::Confusion()) {
1363 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1365 if (aP.Z()-ZX > Precision::Confusion()) {
1372 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1374 if (aP.Z() - ZY > Precision::Confusion()) {
1385 if (LX.at(0) == PZX)
1388 if (LY.at(0) == PZY)
1391 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1392 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1393 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1394 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1396 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1397 if (Cote_1.IsNull()) {
1398 SetErrorCode("Impossible to build edge in thickness");
1401 Cote_1->GetLastFunction()->SetDescription("");
1403 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1404 if (Cote_2.IsNull()) {
1405 SetErrorCode("Impossible to build edge in thickness");
1408 Cote_2->GetLastFunction()->SetDescription("");
1410 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1411 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1412 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1413 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1414 if (edge_chan_princ.IsNull()) {
1415 SetErrorCode("Impossible to find edge on main pipe");
1418 edge_chan_princ->GetLastFunction()->SetDescription("");
1420 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1421 if (edge_chan_inc.IsNull()) {
1422 SetErrorCode("Impossible to find edge on incident pipe");
1425 edge_chan_inc->GetLastFunction()->SetDescription("");
1427 std::list<Handle(GEOM_Object)> edgeList1;
1428 edgeList1.push_back(edge_chan_princ);
1429 edgeList1.push_back(Cote_1);
1430 edgeList1.push_back(arete_intersect_int);
1431 edgeList1.push_back(Cote_2);
1433 // std::cerr << "Creating wire 1" << std::endl;
1434 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1435 if (wire_t.IsNull()) {
1436 SetErrorCode("Impossible to build wire");
1439 wire_t->GetLastFunction()->SetDescription("");
1441 // std::cerr << "Creating face 1" << std::endl;
1442 face_t = myShapesOperations->MakeFace(wire_t, false);
1443 if (face_t.IsNull()) {
1444 SetErrorCode("Impossible to build face");
1447 face_t->GetLastFunction()->SetDescription("");
1448 theShapes.push_back(face_t);
1450 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1451 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1452 double deltaZ = aP2.Z() - aP5.Z();
1453 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1454 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1455 if (P5bis.IsNull()) {
1456 SetErrorCode("Impossible to translate vertex");
1459 P5bis->GetLastFunction()->SetDescription("");
1461 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1462 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1463 deltaZ = aP4.Z() - aP6.Z();
1464 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1465 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1466 if (P6bis.IsNull()) {
1467 SetErrorCode("Impossible to translate vertex");
1470 P6bis->GetLastFunction()->SetDescription("");
1472 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1473 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
1474 if (Cote_3.IsNull()) {
1475 SetErrorCode("Impossible to build edge in thickness");
1478 Cote_3->GetLastFunction()->SetDescription("");
1480 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1481 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
1482 if (Cote_4.IsNull()) {
1483 SetErrorCode("Impossible to build edge in thickness");
1486 Cote_4->GetLastFunction()->SetDescription("");
1488 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1489 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1490 if (Cote_4.IsNull()) {
1491 SetErrorCode("Impossible to build edge in thickness");
1494 Cote_5->GetLastFunction()->SetDescription("");
1496 //std::list<Handle(GEOM_Object)> edgeList2;
1497 //edgeList2.push_back(edge_chan_inc);
1498 //edgeList2.push_back(Cote_3);
1499 //edgeList2.push_back(Cote_5);
1500 //edgeList2.push_back(Cote_4);
1501 // std::cerr << "Creating wire 2" << std::endl;
1502 //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
1503 //if (wire_t2.IsNull()) {
1504 // SetErrorCode("Impossible to build wire");
1507 //wire_t2->GetLastFunction()->SetDescription("");
1508 // std::cerr << "Creating face 2" << std::endl;
1509 //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
1511 // Mantis issue 0021682
1512 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - (theR2 + theW2));
1513 //face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
1514 if (face_t2.IsNull()) {
1515 SetErrorCode("Impossible to build face");
1518 face_t2->GetLastFunction()->SetDescription("");
1519 theShapes.push_back(face_t2);
1523 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1524 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1525 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1526 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1527 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1528 aP0->GetLastFunction()->SetDescription("");
1529 aVZ->GetLastFunction()->SetDescription("");
1530 aVXZ->GetLastFunction()->SetDescription("");
1531 aPlnOZ->GetLastFunction()->SetDescription("");
1532 aPlnOXZ->GetLastFunction()->SetDescription("");
1533 theShapes.push_back(aPlnOZ);
1534 theShapes.push_back(aPlnOXZ);
1537 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1538 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1539 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1540 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1541 Handle(TColStd_HArray1OfInteger) theMaterials;
1543 partitionShapes->Append(theShape);
1544 theTools->Append(aPlnOZ);
1545 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1546 theTools->Append(aPlnOXZ);
1547 theTools->Append(face_t);
1549 theTools->Append(face_t2);
1551 Te3 = myBooleanOperations->MakePartition
1552 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1553 TopAbs_SOLID, false, theMaterials, 0, false);
1555 SetErrorCode("Impossible to build partition of TShape");
1558 Te3->GetLastFunction()->SetDescription("");
1560 // Last verification: result should be a block
1561 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1562 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3,errList)) {
1563 SetErrorCode("TShape is not a compound of block");
1567 // // BEGIN Compound of created shapes - Only for debug purpose
1568 // theShapes.clear();
1569 // theShapes.push_back(theShape);
1570 // theShapes.push_back(aPlnOZ);
1571 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1572 // theShapes.push_back(aPlnOXZ);
1573 // theShapes.push_back(face_t);
1575 // theShapes.push_back(face_t2);
1577 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1578 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1579 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1580 // // END Compound of created shapes - Only for debug purpose
1582 TopoDS_Shape aShape = Te3->GetValue();
1583 theShape->GetLastFunction()->SetValue(aShape);
1585 catch (Standard_Failure) {
1586 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1587 SetErrorCode(aFail->GetMessageString());
1595 // Mirror and glue faces
1596 bool GEOMImpl_IAdvancedOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1597 double theR1, double theW1, double theL1,
1598 double theR2, double theW2, double theL2)
1603 double aSize = 2*(theL1 + theL2);
1604 double aR1Ext = theR1 + theW1;
1607 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1608 aP0->GetLastFunction()->SetDescription("");
1609 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1610 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1611 aVX->GetLastFunction()->SetDescription("");
1612 aVY->GetLastFunction()->SetDescription("");
1613 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1614 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1615 aPlane_OX->GetLastFunction()->SetDescription("");
1616 aPlane_OY->GetLastFunction()->SetDescription("");
1618 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1620 SetErrorCode("Impossible to build mirror of quarter TShape");
1624 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1626 SetErrorCode("Impossible to build mirror of half TShape");
1630 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1632 SetErrorCode("Impossible to build mirror of half TShape");
1636 std::list<Handle(GEOM_Object)> aShapesList;
1637 aShapesList.push_back(theShape);
1638 aShapesList.push_back(Te4);
1639 aShapesList.push_back(Te5);
1640 aShapesList.push_back(Te6);
1641 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1643 SetErrorCode("Impossible to build compound");
1647 // Copy source shape
1648 TopoDS_Shape aShapeCopy;
1649 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1650 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1652 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7, 1e-7, true);
1654 SetErrorCode("Impossible to glue faces of TShape");
1658 TopoDS_Shape aShape = Te8->GetValue();
1659 BRepCheck_Analyzer anAna (aShape, Standard_True);
1661 if (!anAna.IsValid()) {
1662 // Try to do gluing with the tolerance equal to maximal
1663 // tolerance of vertices of the source shape.
1664 Standard_Real aTolMax = -RealLast();
1666 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1667 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1668 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1670 if (aTol > aTolMax) {
1676 Te7->GetLastFunction()->SetValue(aShapeCopy);
1677 Te8 = myShapesOperations->MakeGlueFaces(Te7, aTolMax, true);
1680 SetErrorCode("Impossible to glue faces of TShape");
1684 aShape = Te8->GetValue();
1688 theShape->GetLastFunction()->SetValue(aShape);
1690 Te4->GetLastFunction()->SetDescription("");
1691 Te5->GetLastFunction()->SetDescription("");
1692 Te6->GetLastFunction()->SetDescription("");
1693 Te7->GetLastFunction()->SetDescription("");
1694 Te8->GetLastFunction()->SetDescription("");
1700 //=======================================================================
1701 //function : MakePipeTShapeThicknessReduction
1702 //purpose : Static method. Add thiskness reduction elements at the three
1703 // open ends of the T-Shape.
1704 //=======================================================================
1705 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakePipeTShapeThicknessReduction
1706 (TopoDS_Shape theShape,
1707 double r1, double w1, double l1,
1708 double r2, double w2, double l2,
1709 double rL, double wL, double ltransL, double lthinL,
1710 double rR, double wR, double ltransR, double lthinR,
1711 double rI, double wI, double ltransI, double lthinI,
1712 bool fuseReductions)
1714 // Add thickness reduction elements
1715 // at the three extremities: Left, Right and Incident
1717 // ---------------------.
1719 // ---------------------. \
1720 // ^ \ '-----------------.
1722 // | '-----------------'
1724 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1727 TopoDS_Shape aResult = theShape;
1728 double aTol = Precision::Confusion();
1730 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1732 // Left reduction (rL, wL, ltransL, lthinL)
1733 if (rL > aTol && wL > aTol && ltransL > aTol) {
1734 gp_Pnt aPLeft (-l1, 0, 0);
1735 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1736 TopoDS_Shape aReductionLeft = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1737 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1739 if (fuseReductions) {
1740 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1741 if (!fuseL.IsDone())
1742 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1743 aResult = fuseL.Shape();
1750 B.Add(C, aReductionLeft);
1756 if (rR > aTol && wR > aTol && ltransR > aTol) {
1757 gp_Pnt aPRight (l1, 0, 0);
1758 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1759 TopoDS_Shape aReductionRight = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1760 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1762 if (fuseReductions) {
1763 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1764 if (!fuseR.IsDone())
1765 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1766 aResult = fuseR.Shape();
1773 B.Add(C, aReductionRight);
1778 // Incident reduction
1779 if (rI > aTol && wI > aTol && ltransI > aTol) {
1780 gp_Pnt aPInci (0, 0, l2);
1781 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1782 TopoDS_Shape aReductionInci = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1783 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1785 if (fuseReductions) {
1786 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1787 if (!fuseInci.IsDone())
1788 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1789 aResult = fuseInci.Shape();
1796 B.Add(C, aReductionInci);
1801 // Get rid of extra compounds
1802 TopTools_ListOfShape listShapeRes;
1803 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1804 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1806 if (!fuseReductions && listShapeRes.Extent() > 1) {
1807 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1812 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1813 for (; itSub.More(); itSub.Next())
1814 B.Add(C, itSub.Value());
1817 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1823 //=======================================================================
1824 //function : MakeThicknessReduction
1825 //purpose : Static method. Create one thickness reduction element.
1826 //=======================================================================
1827 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1828 const double R, const double W,
1829 const double Rthin, const double Wthin,
1830 const double Ltrans, const double Lthin,
1833 double aTol = Precision::Confusion();
1834 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1835 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1837 bool isThinPart = (Lthin > aTol);
1842 // ^ \ '-----------------.
1844 // | '-----------------'
1846 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1849 double RExt = R + W;
1850 double RthinExt = Rthin + Wthin;
1852 gp_Dir aNormal = theAxes.Direction();
1853 gp_Dir anXDir = theAxes.XDirection();
1854 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1855 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1857 // Build the transition part
1858 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1859 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1862 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1863 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1864 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1866 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1867 TopoDS_Shape aReduction = cut1.Shape();
1869 // Build the thin part, if required
1870 TopoDS_Shape aThinPart;
1872 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1873 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1876 if (!CExt.IsDone() || !CInt.IsDone())
1877 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1878 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1880 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1881 aThinPart = cut2.Shape();
1887 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1888 if (!fuse1.IsDone())
1889 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1890 aReduction = fuse1.Shape();
1894 // Partition the reduction on blocks
1895 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1896 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1897 gp_Pln aPln1 (anAxesPln1);
1898 gp_Pln aPln2 (anAxesPln2);
1899 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1900 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1901 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1903 GEOMAlgo_Splitter PS;
1904 PS.AddShape(aReduction);
1906 PS.AddShape(aThinPart);
1909 PS.SetLimit(TopAbs_SOLID);
1912 aReduction = PS.Shape();
1918 //=============================================================================
1921 * \brief Create a T-shape object with specified caracteristics for the main and
1922 * the incident pipes (radius, width, half-length).
1923 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1924 * \param theR1 Internal radius of main pipe
1925 * \param theW1 Width of main pipe
1926 * \param theL1 Half-length of main pipe
1927 * \param theR2 Internal radius of incident pipe (R2 < R1)
1928 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1929 * \param theL2 Half-length of incident pipe
1930 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1931 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1933 //=============================================================================
1934 Handle(TColStd_HSequenceOfTransient)
1935 GEOMImpl_IAdvancedOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1936 double theR2, double theW2, double theL2,
1937 double theRL, double theWL, double theLtransL, double theLthinL,
1938 double theRR, double theWR, double theLtransR, double theLthinR,
1939 double theRI, double theWI, double theLtransI, double theLthinI,
1942 MESSAGE("GEOMImpl_IAdvancedOperations::MakePipeTShape");
1945 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1947 //Add a new shape function with parameters
1948 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1949 if (aFunction.IsNull()) return NULL;
1951 //Check if the function is set correctly
1952 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1954 GEOMImpl_IPipeTShape aData (aFunction);
1962 aData.SetHexMesh(theHexMesh);
1964 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1965 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1966 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1968 //Compute the resulting value
1970 #if OCC_VERSION_LARGE > 0x06010000
1973 if (!GetSolver()->ComputeFunction(aFunction)) {
1974 SetErrorCode("TShape driver failed");
1979 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1981 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1985 if (isTRL || isTRR || isTRI) {
1986 // Add thickness reduction elements
1987 // at the three extremities: Left, Right and Incident
1988 TopoDS_Shape aResShape =
1989 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
1990 theRL, theWL, theLtransL, theLthinL,
1991 theRR, theWR, theLtransR, theLthinR,
1992 theRI, theWI, theLtransI, theLthinI,
1994 aFunction->SetValue(aResShape);
1997 catch (Standard_Failure) {
1998 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1999 SetErrorCode(aFail->GetMessageString());
2003 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2004 aSeq->Append(aShape);
2009 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2010 0., 0., 0., aSeq, gp_Trsf()))
2014 // Get internal group.
2015 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2016 theRR, theLtransR, theRI, theLtransI,
2021 catch (Standard_Failure) {
2022 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2023 SetErrorCode(aFail->GetMessageString());
2027 //Make a Python command
2028 TCollection_AsciiString anEntry, aListRes("[");
2029 // Iterate over the sequence aSeq
2030 Standard_Integer aNbGroups = aSeq->Length();
2031 Standard_Integer i = 1;
2032 for (; i <= aNbGroups; i++) {
2033 Handle(Standard_Transient) anItem = aSeq->Value(i);
2034 if (anItem.IsNull()) continue;
2035 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2036 if (aGroup.IsNull()) continue;
2037 //Make a Python command
2038 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2039 aListRes += anEntry + ", ";
2041 aListRes.Trunc(aListRes.Length() - 2);
2043 GEOM::TPythonDump pd (aFunction);
2045 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2046 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2047 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2050 // thickness reduction
2052 pd << ", theRL=" << theRL << ", theWL=" << theWL
2053 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2055 pd << ", theRR=" << theRR << ", theWR=" << theWR
2056 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2058 pd << ", theRI=" << theRI << ", theWI=" << theWI
2059 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2068 //=============================================================================
2070 * MakePipeTShapeWithPosition
2071 * Create a T-shape object with specified caracteristics for the main and
2072 * the incident pipes (radius, width, half-length).
2073 * The extremities of the main pipe are located on junctions points P1 and P2.
2074 * The extremity of the incident pipe is located on junction point P3.
2075 * \param theR1 Internal radius of main pipe
2076 * \param theW1 Width of main pipe
2077 * \param theL1 Half-length of main pipe
2078 * \param theR2 Internal radius of incident pipe (R2 < R1)
2079 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2080 * \param theL2 Half-length of incident pipe
2081 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2082 * \param theP1 1st junction point of main pipe
2083 * \param theP2 2nd junction point of main pipe
2084 * \param theP3 Junction point of incident pipe
2085 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2087 //=============================================================================
2088 Handle(TColStd_HSequenceOfTransient)
2089 GEOMImpl_IAdvancedOperations::MakePipeTShapeWithPosition
2090 (double theR1, double theW1, double theL1,
2091 double theR2, double theW2, double theL2,
2092 double theRL, double theWL, double theLtransL, double theLthinL,
2093 double theRR, double theWR, double theLtransR, double theLthinR,
2094 double theRI, double theWI, double theLtransI, double theLthinI,
2096 Handle(GEOM_Object) theP1,
2097 Handle(GEOM_Object) theP2,
2098 Handle(GEOM_Object) theP3)
2102 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2106 //Add a new shape function with parameters
2107 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2108 if (aFunction.IsNull()) return NULL;
2110 //Check if the function is set correctly
2111 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2113 // Check new position
2114 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2118 GEOMImpl_IPipeTShape aData(aFunction);
2126 aData.SetHexMesh(theHexMesh);
2128 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2129 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2130 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2132 //Compute the resulting value
2134 #if OCC_VERSION_LARGE > 0x06010000
2137 if (!GetSolver()->ComputeFunction(aFunction)) {
2138 SetErrorCode("TShape driver failed");
2143 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2145 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2149 if (isTRL || isTRR || isTRI) {
2150 // Add thickness reduction elements
2151 // at the three extremities: Left, Right and Incident
2152 TopoDS_Shape aResShape =
2153 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2154 theRL, theWL, theLtransL, theLthinL,
2155 theRR, theWR, theLtransR, theLthinR,
2156 theRI, theWI, theLtransI, theLthinI,
2158 aFunction->SetValue(aResShape);
2161 catch (Standard_Failure) {
2162 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2163 SetErrorCode(aFail->GetMessageString());
2167 TopoDS_Shape Te = aShape->GetValue();
2170 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2171 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2172 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2173 aFunction->SetValue(aTrsf_Shape);
2175 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2176 aSeq->Append(aShape);
2181 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2182 0., 0., 0., aSeq, aTrsf)) {
2187 // Get internal group.
2188 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2189 theRR, theLtransR, theRI, theLtransI,
2194 catch (Standard_Failure) {
2195 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2196 SetErrorCode(aFail->GetMessageString());
2200 //Make a Python command
2201 TCollection_AsciiString anEntry, aListRes("[");
2202 // Iterate over the sequence aSeq
2203 Standard_Integer aNbGroups = aSeq->Length();
2204 Standard_Integer i = 1;
2205 for (; i <= aNbGroups; i++) {
2206 Handle(Standard_Transient) anItem = aSeq->Value(i);
2207 if (anItem.IsNull()) continue;
2208 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2209 if (aGroup.IsNull()) continue;
2210 //Make a Python command
2211 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2212 aListRes += anEntry + ", ";
2214 aListRes.Trunc(aListRes.Length() - 2);
2216 GEOM::TPythonDump pd (aFunction);
2218 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2219 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2220 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2221 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2223 // thickness reduction
2225 pd << ", theRL=" << theRL << ", theWL=" << theWL
2226 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2228 pd << ", theRR=" << theRR << ", theWR=" << theWR
2229 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2231 pd << ", theRI=" << theRI << ", theWI=" << theWI
2232 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2241 //=============================================================================
2243 * MakePipeTShapeChamfer
2244 * Create a T-shape object with specified caracteristics for the main and
2245 * the incident pipes (radius, width, half-length). A chamfer is created
2246 * on the junction of the pipes.
2247 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2248 * \param theR1 Internal radius of main pipe
2249 * \param theW1 Width of main pipe
2250 * \param theL1 Half-length of main pipe
2251 * \param theR2 Internal radius of incident pipe (R2 < R1)
2252 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2253 * \param theL2 Half-length of incident pipe
2254 * \param theH Height of chamfer.
2255 * \param theW Width of chamfer.
2256 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2257 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2259 //=============================================================================
2260 Handle(TColStd_HSequenceOfTransient)
2261 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamfer
2262 (double theR1, double theW1, double theL1,
2263 double theR2, double theW2, double theL2,
2264 double theRL, double theWL, double theLtransL, double theLthinL,
2265 double theRR, double theWR, double theLtransR, double theLthinR,
2266 double theRI, double theWI, double theLtransI, double theLthinI,
2267 double theH, double theW,
2272 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2273 //Add a new shape function with parameters
2274 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2275 if (aFunction.IsNull()) return NULL;
2277 //Check if the function is set correctly
2278 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2280 GEOMImpl_IPipeTShape aData(aFunction);
2290 aData.SetHexMesh(theHexMesh);
2292 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2293 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2294 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2296 //Compute the resulting value
2298 #if OCC_VERSION_LARGE > 0x06010000
2301 if (!GetSolver()->ComputeFunction(aFunction)) {
2302 SetErrorCode("TShape driver failed");
2306 catch (Standard_Failure) {
2307 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2308 SetErrorCode(aFail->GetMessageString());
2313 TopoDS_Shape aShapeShape = aShape->GetValue();
2314 TopTools_IndexedMapOfShape anEdgesIndices;
2315 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2316 // Common edges on external cylinders
2317 Handle(GEOM_Object) box_e;
2319 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2322 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2324 box_e->GetLastFunction()->SetDescription("");
2325 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2326 box_e->GetLastFunction()->SetDescription("");
2328 Handle(TColStd_HSequenceOfInteger) edges_e =
2329 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2330 box_e->GetLastFunction()->SetDescription("");
2332 if (edges_e.IsNull() || edges_e->Length() == 0) {
2333 SetErrorCode("External edges not found");
2336 int nbEdgesInChamfer = 0;
2337 std::list<int> theEdges;
2338 for (int i=1; i<=edges_e->Length();i++) {
2339 int edgeID = edges_e->Value(i);
2340 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2341 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2345 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2346 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2347 nbEdgesInChamfer ++;
2348 theEdges.push_back(edgeID);
2352 if (theHexMesh && nbEdgesInChamfer == 1)
2355 Handle(GEOM_Object) aChamfer;
2357 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2359 catch (Standard_Failure) {
2360 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2361 SetErrorCode(aFail->GetMessageString());
2364 if (aChamfer.IsNull()) {
2365 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2368 aChamfer->GetLastFunction()->SetDescription("");
2370 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2371 aFunction->SetValue(aChamferShape);
2375 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2377 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2381 // Add thickness reduction elements
2382 // at the three extremities: Left, Right and Incident
2384 #if OCC_VERSION_LARGE > 0x06010000
2387 if (isTRL || isTRR || isTRI) {
2388 TopoDS_Shape aResShape =
2389 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2390 theRL, theWL, theLtransL, theLthinL,
2391 theRR, theWR, theLtransR, theLthinR,
2392 theRI, theWI, theLtransI, theLthinI,
2394 aFunction->SetValue(aResShape);
2397 catch (Standard_Failure) {
2398 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2399 SetErrorCode(aFail->GetMessageString());
2403 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2404 aSeq->Append(aShape);
2409 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2410 theH, theW, 0., aSeq, gp_Trsf()))
2414 // Get internal group.
2415 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2416 theRR, theLtransR, theRI, theLtransI,
2421 catch (Standard_Failure) {
2422 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2423 SetErrorCode(aFail->GetMessageString());
2427 //Make a Python command
2428 TCollection_AsciiString anEntry, aListRes("[");
2429 // Iterate over the sequence aSeq
2430 Standard_Integer aNbGroups = aSeq->Length();
2431 Standard_Integer i = 1;
2432 for (; i <= aNbGroups; i++) {
2433 Handle(Standard_Transient) anItem = aSeq->Value(i);
2434 if (anItem.IsNull()) continue;
2435 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2436 if (aGroup.IsNull()) continue;
2437 //Make a Python command
2438 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2439 aListRes += anEntry + ", ";
2441 aListRes.Trunc(aListRes.Length() - 2);
2443 GEOM::TPythonDump pd (aFunction);
2445 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2446 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2447 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2448 << theH << ", " << theW << ", " << theHexMesh;
2450 // thickness reduction
2452 pd << ", theRL=" << theRL << ", theWL=" << theWL
2453 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2455 pd << ", theRR=" << theRR << ", theWR=" << theWR
2456 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2458 pd << ", theRI=" << theRI << ", theWI=" << theWI
2459 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2468 //=============================================================================
2470 * MakePipeTShapeChamferWithPosition
2471 * Create a T-shape object with specified caracteristics for the main and
2472 * the incident pipes (radius, width, half-length). A chamfer is created
2473 * on the junction of the pipes.
2474 * The extremities of the main pipe are located on junctions points P1 and P2.
2475 * The extremity of the incident pipe is located on junction point P3.
2476 * \param theR1 Internal radius of main pipe
2477 * \param theW1 Width of main pipe
2478 * \param theL1 Half-length of main pipe
2479 * \param theR2 Internal radius of incident pipe (R2 < R1)
2480 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2481 * \param theL2 Half-length of incident pipe
2482 * \param theH Height of chamfer.
2483 * \param theW Width of chamfer.
2484 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2485 * \param theP1 1st junction point of main pipe
2486 * \param theP2 2nd junction point of main pipe
2487 * \param theP3 Junction point of incident pipe
2488 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2490 //=============================================================================
2491 Handle(TColStd_HSequenceOfTransient)
2492 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamferWithPosition
2493 (double theR1, double theW1, double theL1,
2494 double theR2, double theW2, double theL2,
2495 double theRL, double theWL, double theLtransL, double theLthinL,
2496 double theRR, double theWR, double theLtransR, double theLthinR,
2497 double theRI, double theWI, double theLtransI, double theLthinI,
2498 double theH, double theW,
2500 Handle(GEOM_Object) theP1,
2501 Handle(GEOM_Object) theP2,
2502 Handle(GEOM_Object) theP3)
2506 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2507 //Add a new shape function with parameters
2508 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2509 if (aFunction.IsNull()) return NULL;
2511 //Check if the function is set correctly
2512 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2514 // Check new position
2515 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2519 GEOMImpl_IPipeTShape aData(aFunction);
2529 aData.SetHexMesh(theHexMesh);
2531 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2532 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2533 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2535 //Compute the resulting value
2537 #if OCC_VERSION_LARGE > 0x06010000
2540 if (!GetSolver()->ComputeFunction(aFunction)) {
2541 SetErrorCode("TShape driver failed");
2545 catch (Standard_Failure) {
2546 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2547 SetErrorCode(aFail->GetMessageString());
2552 TopoDS_Shape aShapeShape = aShape->GetValue();
2553 TopTools_IndexedMapOfShape anEdgesIndices;
2554 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2555 // Common edges on external cylinders
2556 Handle(GEOM_Object) box_e;
2558 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2561 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2563 box_e->GetLastFunction()->SetDescription("");
2564 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2565 box_e->GetLastFunction()->SetDescription("");
2567 Handle(TColStd_HSequenceOfInteger) edges_e =
2568 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2569 box_e->GetLastFunction()->SetDescription("");
2571 if (edges_e.IsNull() || edges_e->Length() == 0) {
2572 SetErrorCode("External edges not found");
2575 int nbEdgesInChamfer = 0;
2576 std::list<int> theEdges;
2577 for (int i=1; i<=edges_e->Length();i++) {
2578 int edgeID = edges_e->Value(i);
2579 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2580 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2582 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2583 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2584 nbEdgesInChamfer ++;
2585 theEdges.push_back(edgeID);
2589 if (theHexMesh && nbEdgesInChamfer == 1)
2592 Handle(GEOM_Object) aChamfer;
2594 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2596 catch (Standard_Failure) {
2597 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2598 SetErrorCode(aFail->GetMessageString());
2601 if (aChamfer.IsNull()) {
2602 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2605 aChamfer->GetLastFunction()->SetDescription("");
2607 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2608 aFunction->SetValue(aChamferShape);
2612 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2614 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2618 // Add thickness reduction elements
2619 // at the three extremities: Left, Right and Incident
2621 #if OCC_VERSION_LARGE > 0x06010000
2624 if (isTRL || isTRR || isTRI) {
2625 TopoDS_Shape aResShape =
2626 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2627 theRL, theWL, theLtransL, theLthinL,
2628 theRR, theWR, theLtransR, theLthinR,
2629 theRI, theWI, theLtransI, theLthinI,
2631 aFunction->SetValue(aResShape);
2634 catch (Standard_Failure) {
2635 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2636 SetErrorCode(aFail->GetMessageString());
2641 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2642 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2643 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2644 aFunction->SetValue(aTrsf_Shape);
2646 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2647 aSeq->Append(aShape);
2652 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2653 theH, theW, 0., aSeq, aTrsf))
2657 // Get internal group.
2658 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2659 theRR, theLtransR, theRI, theLtransI,
2664 catch (Standard_Failure) {
2665 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2666 SetErrorCode(aFail->GetMessageString());
2670 //Make a Python command
2671 TCollection_AsciiString anEntry, aListRes("[");
2672 // Iterate over the sequence aSeq
2673 Standard_Integer aNbGroups = aSeq->Length();
2674 Standard_Integer i = 1;
2675 for (; i <= aNbGroups; i++) {
2676 Handle(Standard_Transient) anItem = aSeq->Value(i);
2677 if (anItem.IsNull()) continue;
2678 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2679 if (aGroup.IsNull()) continue;
2680 //Make a Python command
2681 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2682 aListRes += anEntry + ", ";
2684 aListRes.Trunc(aListRes.Length() - 2);
2686 GEOM::TPythonDump pd (aFunction);
2688 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2689 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2690 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2691 << theH << ", " << theW << ", " << theHexMesh << ", "
2692 << theP1 << ", " << theP2 << ", " << theP3;
2694 // thickness reduction
2696 pd << ", theRL=" << theRL << ", theWL=" << theWL
2697 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2699 pd << ", theRR=" << theRR << ", theWR=" << theWR
2700 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2702 pd << ", theRI=" << theRI << ", theWI=" << theWI
2703 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2712 //=============================================================================
2714 * MakePipeTShapeFillet
2715 * Create a T-shape object with specified caracteristics for the main and
2716 * the incident pipes (radius, width, half-length). A fillet is created
2717 * on the junction of the pipes.
2718 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2719 * \param theR1 Internal radius of main pipe
2720 * \param theW1 Width of main pipe
2721 * \param theL1 Half-length of main pipe
2722 * \param theR2 Internal radius of incident pipe (R2 < R1)
2723 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2724 * \param theL2 Half-length of incident pipe
2725 * \param theRF Radius of curvature of fillet.
2726 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2727 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2729 //=============================================================================
2730 Handle(TColStd_HSequenceOfTransient)
2731 GEOMImpl_IAdvancedOperations::MakePipeTShapeFillet
2732 (double theR1, double theW1, double theL1,
2733 double theR2, double theW2, double theL2,
2734 double theRL, double theWL, double theLtransL, double theLthinL,
2735 double theRR, double theWR, double theLtransR, double theLthinR,
2736 double theRI, double theWI, double theLtransI, double theLthinI,
2737 double theRF, bool theHexMesh)
2741 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2742 //Add a new shape function with parameters
2743 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2744 if (aFunction.IsNull()) return NULL;
2746 //Check if the function is set correctly
2747 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2749 GEOMImpl_IPipeTShape aData(aFunction);
2758 aData.SetHexMesh(theHexMesh);
2760 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2761 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2762 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2764 //Compute the resulting value
2766 #if OCC_VERSION_LARGE > 0x06010000
2769 if (!GetSolver()->ComputeFunction(aFunction)) {
2770 SetErrorCode("TShape driver failed");
2774 catch (Standard_Failure) {
2775 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2776 SetErrorCode(aFail->GetMessageString());
2781 TopoDS_Shape aShapeShape = aShape->GetValue();
2782 TopTools_IndexedMapOfShape anEdgesIndices;
2783 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2784 // Common edges on external cylinders
2785 Handle(GEOM_Object) box_e;
2787 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2790 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2792 box_e->GetLastFunction()->SetDescription("");
2793 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2794 box_e->GetLastFunction()->SetDescription("");
2796 Handle(TColStd_HSequenceOfInteger) edges_e =
2797 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2798 box_e->GetLastFunction()->SetDescription("");
2800 if (edges_e.IsNull() || edges_e->Length() == 0) {
2801 SetErrorCode("External edges not found");
2804 int nbEdgesInFillet = 0;
2805 std::list<int> theEdges;
2806 for (int i=1; i<=edges_e->Length();i++) {
2807 int edgeID = edges_e->Value(i);
2808 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2809 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2811 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2812 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2814 theEdges.push_back(edgeID);
2818 if (theHexMesh && nbEdgesInFillet == 1)
2822 Handle(GEOM_Object) aFillet;
2824 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2826 catch (Standard_Failure) {
2827 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2828 SetErrorCode(aFail->GetMessageString());
2831 if (aFillet.IsNull()) {
2832 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2833 SetErrorCode(myLocalOperations->GetErrorCode());
2836 aFillet->GetLastFunction()->SetDescription("");
2838 TopoDS_Shape aFilletShape = aFillet->GetValue();
2839 aFunction->SetValue(aFilletShape);
2842 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2843 // the following block, when enabled, leads to partitioning problems
2845 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2846 // BEGIN: Limit tolerances (debug)
2847 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2848 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2849 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2850 aCorr1->GetLastFunction()->SetDescription("");
2851 // END: Limit tolerances (debug)
2852 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2854 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2857 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2859 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2863 // Add thickness reduction elements
2864 // at the three extremities: Left, Right and Incident
2866 #if OCC_VERSION_LARGE > 0x06010000
2869 if (isTRL || isTRR || isTRI) {
2870 TopoDS_Shape aResShape =
2871 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2872 theRL, theWL, theLtransL, theLthinL,
2873 theRR, theWR, theLtransR, theLthinR,
2874 theRI, theWI, theLtransI, theLthinI,
2876 aFunction->SetValue(aResShape);
2879 catch (Standard_Failure) {
2880 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2881 SetErrorCode(aFail->GetMessageString());
2885 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2886 aSeq->Append(aShape);
2891 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2892 0., 0., theRF, aSeq, gp_Trsf()))
2896 // Get internal group.
2897 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2898 theRR, theLtransR, theRI, theLtransI,
2903 catch (Standard_Failure) {
2904 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2905 SetErrorCode(aFail->GetMessageString());
2909 //Make a Python command
2910 TCollection_AsciiString anEntry, aListRes("[");
2911 // Iterate over the sequence aSeq
2912 Standard_Integer aNbGroups = aSeq->Length();
2913 Standard_Integer i = 1;
2914 for (; i <= aNbGroups; i++) {
2915 Handle(Standard_Transient) anItem = aSeq->Value(i);
2916 if (anItem.IsNull()) continue;
2917 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2918 if (aGroup.IsNull()) continue;
2919 //Make a Python command
2920 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2921 aListRes += anEntry + ", ";
2923 aListRes.Trunc(aListRes.Length() - 2);
2925 GEOM::TPythonDump pd (aFunction);
2927 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2928 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2929 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2930 << theRF << ", " << theHexMesh;
2932 // thickness reduction
2934 pd << ", theRL=" << theRL << ", theWL=" << theWL
2935 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2937 pd << ", theRR=" << theRR << ", theWR=" << theWR
2938 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2940 pd << ", theRI=" << theRI << ", theWI=" << theWI
2941 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2950 //=============================================================================
2952 * MakePipeTShapeFilletWithPosition
2953 * \brief Create a T-shape object with specified caracteristics for the main and
2954 * the incident pipes (radius, width, half-length). A fillet is created
2955 * on the junction of the pipes.
2956 * The extremities of the main pipe are located on junctions points P1 and P2.
2957 * The extremity of the incident pipe is located on junction point P3.
2958 * \param theR1 Internal radius of main pipe
2959 * \param theW1 Width of main pipe
2960 * \param theL1 Half-length of main pipe
2961 * \param theR2 Internal radius of incident pipe (R2 < R1)
2962 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2963 * \param theL2 Half-length of incident pipe
2964 * \param theRF Radius of curvature of fillet
2965 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2966 * \param theP1 1st junction point of main pipe
2967 * \param theP2 2nd junction point of main pipe
2968 * \param theP3 Junction point of incident pipe
2969 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2971 //=============================================================================
2972 Handle(TColStd_HSequenceOfTransient)
2973 GEOMImpl_IAdvancedOperations::MakePipeTShapeFilletWithPosition
2974 (double theR1, double theW1, double theL1,
2975 double theR2, double theW2, double theL2,
2976 double theRL, double theWL, double theLtransL, double theLthinL,
2977 double theRR, double theWR, double theLtransR, double theLthinR,
2978 double theRI, double theWI, double theLtransI, double theLthinI,
2979 double theRF, bool theHexMesh,
2980 Handle(GEOM_Object) theP1,
2981 Handle(GEOM_Object) theP2,
2982 Handle(GEOM_Object) theP3)
2986 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2987 //Add a new shape function with parameters
2988 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2989 if (aFunction.IsNull()) return NULL;
2991 //Check if the function is set correctly
2992 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2994 // Check new position
2995 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2999 GEOMImpl_IPipeTShape aData(aFunction);
3008 aData.SetHexMesh(theHexMesh);
3010 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
3011 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
3012 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
3014 //Compute the resulting value
3016 #if OCC_VERSION_LARGE > 0x06010000
3019 if (!GetSolver()->ComputeFunction(aFunction)) {
3020 SetErrorCode("TShape driver failed");
3024 catch (Standard_Failure) {
3025 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3026 SetErrorCode(aFail->GetMessageString());
3031 TopoDS_Shape aShapeShape = aShape->GetValue();
3032 TopTools_IndexedMapOfShape anEdgesIndices;
3033 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3034 // Common edges on external cylinders
3035 Handle(GEOM_Object) box_e;
3037 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3040 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3042 box_e->GetLastFunction()->SetDescription("");
3043 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3044 box_e->GetLastFunction()->SetDescription("");
3046 Handle(TColStd_HSequenceOfInteger) edges_e =
3047 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3048 box_e->GetLastFunction()->SetDescription("");
3050 if (edges_e.IsNull() || edges_e->Length() == 0) {
3051 SetErrorCode("External edges not found");
3054 int nbEdgesInFillet = 0;
3055 std::list<int> theEdges;
3056 for (int i=1; i<=edges_e->Length();i++) {
3057 int edgeID = edges_e->Value(i);
3058 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3059 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3061 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3062 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3064 theEdges.push_back(edgeID);
3068 if (theHexMesh && nbEdgesInFillet == 1)
3072 Handle(GEOM_Object) aFillet;
3074 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3076 catch (Standard_Failure) {
3077 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3078 SetErrorCode(aFail->GetMessageString());
3081 if (aFillet.IsNull()) {
3082 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3085 aFillet->GetLastFunction()->SetDescription("");
3087 TopoDS_Shape aFilletShape = aFillet->GetValue();
3088 aFunction->SetValue(aFilletShape);
3091 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3092 // the following block, when enabled, leads to partitioning problems
3094 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3095 // BEGIN: Limit tolerances (debug)
3096 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3097 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3098 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3099 aCorr1->GetLastFunction()->SetDescription("");
3100 // END: Limit tolerances (debug)
3101 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3103 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3106 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3108 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3112 // Add thickness reduction elements
3113 // at the three extremities: Left, Right and Incident
3115 #if OCC_VERSION_LARGE > 0x06010000
3118 if (isTRL || isTRR || isTRI) {
3119 TopoDS_Shape aResShape =
3120 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3121 theRL, theWL, theLtransL, theLthinL,
3122 theRR, theWR, theLtransR, theLthinR,
3123 theRI, theWI, theLtransI, theLthinI,
3125 aFunction->SetValue(aResShape);
3128 catch (Standard_Failure) {
3129 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3130 SetErrorCode(aFail->GetMessageString());
3135 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3136 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3137 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3138 aFunction->SetValue(aTrsf_Shape);
3140 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3141 aSeq->Append(aShape);
3146 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3147 0., 0., theRF, aSeq, aTrsf))
3151 // Get internal group.
3152 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3153 theRR, theLtransR, theRI, theLtransI,
3158 catch (Standard_Failure) {
3159 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3160 SetErrorCode(aFail->GetMessageString());
3164 //Make a Python command
3165 TCollection_AsciiString anEntry, aListRes("[");
3166 // Iterate over the sequence aSeq
3167 Standard_Integer aNbGroups = aSeq->Length();
3168 Standard_Integer i = 1;
3169 for (; i <= aNbGroups; i++) {
3170 Handle(Standard_Transient) anItem = aSeq->Value(i);
3171 if (anItem.IsNull()) continue;
3172 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3173 if (aGroup.IsNull()) continue;
3174 //Make a Python command
3175 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3176 aListRes += anEntry + ", ";
3178 aListRes.Trunc(aListRes.Length() - 2);
3180 GEOM::TPythonDump pd (aFunction);
3182 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3183 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3184 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3185 << theRF << ", " << theHexMesh << ", "
3186 << theP1 << ", " << theP2 << ", " << theP3;
3188 // thickness reduction
3190 pd << ", theRL=" << theRL << ", theWL=" << theWL
3191 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3193 pd << ", theRR=" << theRR << ", theWR=" << theWR
3194 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3196 pd << ", theRI=" << theRI << ", theWI=" << theWI
3197 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3206 //=============================================================================
3208 * This function allows to create a disk already divided into blocks. It can be
3209 * used to create divided pipes for later meshing in hexaedra.
3210 * \param theR Radius of the disk
3211 * \param theRatio Relative size of the central square diagonal against the disk diameter
3212 * \param theOrientation Plane on which the disk will be built
3213 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3214 * \return New GEOM_Object, containing the created shape.
3216 //=============================================================================
3217 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedDisk (double theR, double theRatio,
3218 int theOrientation, int thePattern)
3222 if (theOrientation != 1 &&
3223 theOrientation != 2 &&
3224 theOrientation != 3)
3226 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3230 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3232 //Add a new shape function with parameters
3233 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3234 if (aFunction.IsNull()) return NULL;
3236 //Check if the function is set correctly
3237 if (aFunction->GetDriverGUID() != GEOMImpl_DividedDiskDriver::GetID()) return NULL;
3239 GEOMImpl_IDividedDisk aData (aFunction);
3242 aData.SetRatio(theRatio);
3243 aData.SetOrientation(theOrientation);
3244 aData.SetType(thePattern);
3246 //Compute the resulting value
3248 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3251 if (!GetSolver()->ComputeFunction(aFunction)) {
3252 SetErrorCode("DividedDisk driver failed");
3256 catch (Standard_Failure) {
3257 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3258 SetErrorCode(aFail->GetMessageString());
3262 std::string aPatternStr;
3267 aPatternStr = "GEOM.SQUARE";
3270 aPatternStr = "GEOM.HEXAGON";
3274 //Make a Python command
3275 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3282 //=============================================================================
3284 * This function allows to create a disk already divided into blocks. It can be
3285 * used to create divided pipes for later meshing in hexaedra.
3286 * \param theR Radius of the disk
3287 * \param theRatio Relative size of the central square diagonal against the disk diameter
3288 * \return New GEOM_Object, containing the created shape.
3290 //=============================================================================
3291 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3292 Handle(GEOM_Object) theVec,
3300 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3302 //Add a new shape function with parameters
3303 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3304 if (aFunction.IsNull()) return NULL;
3306 //Check if the function is set correctly
3307 if (aFunction->GetDriverGUID() != GEOMImpl_DividedDiskDriver::GetID()) return NULL;
3309 GEOMImpl_IDividedDisk aData (aFunction);
3311 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3312 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3314 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3316 aData.SetCenter(aRefPnt);
3317 aData.SetVector(aRefVec);
3320 aData.SetRatio(theRatio);
3321 aData.SetType(thePattern);
3323 //Compute the resulting value
3325 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3328 if (!GetSolver()->ComputeFunction(aFunction)) {
3329 SetErrorCode("DividedDisk driver failed");
3333 catch (Standard_Failure) {
3334 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3335 SetErrorCode(aFail->GetMessageString());
3339 std::string aPatternStr;
3344 aPatternStr = "GEOM.SQUARE";
3347 aPatternStr = "GEOM.HEXAGON";
3352 //Make a Python command
3353 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3360 //=============================================================================
3362 * Builds a cylinder prepared for hexa meshes
3363 * \param theR Radius of the cylinder
3364 * \param theH Height of the cylinder
3365 * \return New GEOM_Object, containing the created shape.
3367 //=============================================================================
3368 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedCylinder (double theR,
3375 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3377 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3378 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3380 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3382 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3383 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3384 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3386 std::string aPatternStr;
3391 aPatternStr = "GEOM.SQUARE";
3394 aPatternStr = "GEOM.HEXAGON";
3398 //Make a Python command
3399 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3405 //=============================================================================
3407 * Create a smoothing surface from a set of points
3408 * \param thelPoints list of points
3409 * \return New GEOM_Object, containing the created shape.
3411 //=============================================================================
3412 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints)
3417 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3419 //Add a new shape function with parameters
3420 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3421 if (aFunction.IsNull()) return NULL;
3423 //Check if the function is set correctly
3424 if (aFunction->GetDriverGUID() != GEOMImpl_SmoothingSurfaceDriver::GetID()) return NULL;
3426 GEOMImpl_ISmoothingSurface aData (aFunction);
3428 int aLen = thelPoints.size();
3429 aData.SetLength(aLen);
3431 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3432 for (; it != thelPoints.end(); it++, ind++) {
3433 Handle(GEOM_Function) aRefPnt = (*it)->GetLastFunction();
3434 if (aRefPnt.IsNull()) {
3435 SetErrorCode("NULL point for bSplineFaceShape");
3438 aData.SetPoint(ind, aRefPnt);
3442 //Compute the resulting value
3444 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3447 if (!GetSolver()->ComputeFunction(aFunction)) {
3448 SetErrorCode("SmoothingSurface driver failed");
3452 catch (Standard_Failure) {
3453 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3454 SetErrorCode(aFail->GetMessageString());
3458 //Make a Python command
3459 GEOM::TPythonDump pd (aFunction);
3460 pd << aShape << " = geompy.MakeSmoothingSurface([";
3461 it = thelPoints.begin();
3463 while (it != thelPoints.end()) {
3464 pd << ", " << (*it++);
3472 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/