##
IF(SALOME_BUILD_GUI)
- # Qt
IF(NOT SALOME_GUI_BUILD_WITH_QT5)
+ # Qt
FIND_PACKAGE(SalomeQt4 REQUIRED COMPONENTS QtCore QtGui QtXml QtWebKit QtOpenGL QtNetwork)
+ # PyQt
+ FIND_PACKAGE(SalomePyQt4 REQUIRED)
ELSE()
+ # Qt
FIND_PACKAGE(SalomeQt5 REQUIRED)
+ # PyQt
+ FIND_PACKAGE(SalomePyQt5 REQUIRED)
ENDIF()
ENDIF(SALOME_BUILD_GUI)
ARCHIMEDE BlockFix GEOMAlgo SKETCHER GEOM ShHealOper GEOMUtils XAO XAO_Swig
GEOMImpl GEOM_I GEOMClient GEOM_I_Superv GEOM_SWIG GEOM_PY
AdvancedEngine OCC2VTK
- STLPlugin BREPPlugin STEPPlugin IGESPlugin XAOPlugin VTKPlugin
+ STLPlugin BREPPlugin STEPPlugin IGESPlugin XAOPlugin VTKPlugin Tools
)
##
typedef std::map< TCollection_AsciiString, TCollection_AsciiString > TSting2StringMap;
typedef std::map< TCollection_AsciiString, TObjectData > TSting2ObjDataMap;
typedef std::map< TCollection_AsciiString, TObjectData* > TSting2ObjDataPtrMap;
+typedef std::map< int, std::list < int > > TIntToListIntMap;
static GEOM_Engine* TheEngine = NULL;
std::set<TCollection_AsciiString>& theIgnoreObjs,
bool& theIsDumpCollected);
+static int GetTag(const TCollection_AsciiString &theEntry);
+
+static void FillMapOfRef(const Handle(GEOM_Function) &theFunction,
+ TIntToListIntMap &theRefMap);
+
void ReplaceVariables(TCollection_AsciiString& theCommand,
const TVariablesList& theVariables);
std::map< int, TCollection_AsciiString >& theEntryToCmdMap,
std::set<TCollection_AsciiString>& theMapOfPublished);
+static TCollection_AsciiString GetPublishCommands
+ (const int theTag,
+ const std::map< int, TCollection_AsciiString > &theEntryToCmdMap,
+ const TIntToListIntMap &theMapRefs,
+ std::set< int > &thePublished);
+
//================================================================================
/*!
* \brief Fix up the name of python variable
// Mantis issue 0020768
Standard_Integer objectCounter = 0;
Resource_DataMapOfAsciiStringAsciiString aNameToEntry;
+ TIntToListIntMap aRefMap;
if (aDoc->Main().FindAttribute(GEOM_Function::GetFunctionTreeID(), aRoot)) {
TDataStd_ChildNodeIterator Itr(aRoot);
continue; // aCurScript is already at the end of aFuncScript
aFuncScript += aCurScript;
}
+
+ // Fill the map of references.
+ FillMapOfRef(aFunction, aRefMap);
+
if (isDumpCollected ) {
// Replace entries by the names
ReplaceEntriesByNames( aFuncScript, aEntry2ObjData, isPublished,
aNameToEntry, anEntryToCmdMap, anIgnoreObjMap );
}
// add publishing commands to the script
+ std::set< int > aPublished;
std::map< int, TCollection_AsciiString >::iterator anEntryToCmd = anEntryToCmdMap.begin();
- for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd )
- aFuncScript += anEntryToCmd->second;
+
+ for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd ) {
+ const TCollection_AsciiString aPublishCmds =
+ GetPublishCommands(anEntryToCmd->first, anEntryToCmdMap,
+ aRefMap, aPublished);
+
+ aFuncScript += aPublishCmds;
+ }
// PTv, 0020001 add result objects from RestoreGivenSubShapes into ignore list,
// because they will be published during command execution
aNameToEntry, anEntryToCmdMap, anIgnoreObjMap );
}
// add publishing commands to the script
+ std::set< int > aPublished;
std::map< int, TCollection_AsciiString >::iterator anEntryToCmd = anEntryToCmdMap.begin();
- for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd )
- aScript += anEntryToCmd->second;
+
+ for ( ; anEntryToCmd != anEntryToCmdMap.end(); ++anEntryToCmd ) {
+ const TCollection_AsciiString aPublishCmds =
+ GetPublishCommands(anEntryToCmd->first, anEntryToCmdMap,
+ aRefMap, aPublished);
+
+ aScript += aPublishCmds;
+ }
}
//RNV: issue 16219: EDF PAL 469: "RemoveFromStudy" Function
return true;
}
+//=============================================================================
+/*!
+ * GetTag: Returns the tag from entry
+ */
+//=============================================================================
+int GetTag(const TCollection_AsciiString &theEntry)
+{
+ const int aGeomObjDepth = 3;
+ const int aTag = theEntry.Token(":", aGeomObjDepth).IntegerValue();
+
+ return aTag;
+}
+
+//=============================================================================
+/*!
+ * FillMapOfRef: Fill the map of references
+ */
+//=============================================================================
+void FillMapOfRef(const Handle(GEOM_Function) &theFunction,
+ TIntToListIntMap &theRefMap)
+{
+ TDF_LabelSequence aSeq;
+ TCollection_AsciiString anObjEntry;
+ int anObjTag;
+
+ TDF_Tool::Entry(theFunction->GetOwnerEntry(), anObjEntry);
+ anObjTag = GetTag(anObjEntry);
+ theFunction->GetDependency(aSeq);
+
+ const Standard_Integer aLen = aSeq.Length();
+ Standard_Integer i;
+
+ for (i = 1; i <= aLen; i++) {
+ TDF_Label aRefLabel = aSeq.Value(i);
+ Handle(TDF_Reference) aRef;
+
+ if (aRefLabel.FindAttribute(TDF_Reference::GetID(), aRef)) {
+ if (!aRef.IsNull() && !aRef->Get().IsNull()) {
+ Handle(TDataStd_TreeNode) aT;
+
+ if (TDataStd_TreeNode::Find(aRef->Get(), aT)) {
+ TDF_Label aDepLabel = aT->Label();
+ Handle(GEOM_Function) aRefFunct = GEOM_Function::GetFunction(aDepLabel);
+
+ if (!aRefFunct.IsNull()) {
+ // Get entry of the referenced object.
+ TDF_Tool::Entry(aRefFunct->GetOwnerEntry(), anObjEntry);
+
+ const int aRefTag = GetTag(anObjEntry);
+
+ theRefMap[anObjTag].push_back(aRefTag);
+ }
+ }
+ }
+ }
+ }
+}
+
//=============================================================================
/*!
* FindEntries: Returns a sequence of start/end positions of entries in the string
if ( stEntry2DataPtr != theStEntry2ObjDataPtr.end() )
aFatherData = stEntry2DataPtr->second;
- const int geomObjDepth = 3;
-
// treat multiply published object
if ( theObjectData._pyName.IsEmpty() )
{
aCreationCommand += theObjectData._pyName + " = " + data0._pyName;
// store aCreationCommand before publishing commands
- int tag = theObjectData._entry.Token( ":", geomObjDepth ).IntegerValue();
+ int tag = GetTag(theObjectData._entry);
theEntryToCmdMap.insert( std::make_pair( tag + 2*theEntry2ObjData.size(), aCreationCommand ));
}
aCommand += theObjectData._pyName + ", '" + theObjectData._name + "' )";
// bind a command to the study entry
- int tag = theObjectData._entry.Token( ":", geomObjDepth ).IntegerValue();
+ int tag = GetTag(theObjectData._entry);
theEntryToCmdMap.insert( std::make_pair( tag, aCommand ));
theObjectData._studyEntry.Clear(); // not to publish any more
}
+//================================================================================
+/*!
+ * \brief Returns the string of publishing commands. Take into account that
+ * references should be published prior to the objects refer to them.
+ */
+//================================================================================
+TCollection_AsciiString GetPublishCommands
+ (const int theTag,
+ const std::map< int, TCollection_AsciiString > &theEntryToCmdMap,
+ const TIntToListIntMap &theMapRefs,
+ std::set< int > &thePublished)
+{
+ TCollection_AsciiString aResult;
+
+ if (!thePublished.count(theTag)) {
+ // This object is not published yet.
+ std::map< int, TCollection_AsciiString >::const_iterator anIt =
+ theEntryToCmdMap.find(theTag);
+
+ if (anIt != theEntryToCmdMap.end()) {
+ // There is a pubish cmd.
+ TIntToListIntMap::const_iterator aRefIt = theMapRefs.find(theTag);
+
+ if (aRefIt != theMapRefs.end()) {
+ // Recursively publish all references.
+ std::list< int >::const_iterator aRefTagIt = aRefIt->second.begin();
+
+ for(; aRefTagIt != aRefIt->second.end(); ++aRefTagIt) {
+ const TCollection_AsciiString aRefCmd = GetPublishCommands
+ (*aRefTagIt, theEntryToCmdMap, theMapRefs, thePublished);
+
+ aResult += aRefCmd;
+ }
+ }
+
+ // Add the object command.
+ aResult += anIt->second;
+ }
+
+ thePublished.insert(theTag);
+ }
+
+ return aResult;
+}
+
//================================================================================
/*!
* \brief Constructor
</message>
<message>
<source>GEOM_PLUGINS_OTHER</source>
- <translation>Other</translation>
+ <translation>Python Plugins</translation>
</message>
<message>
<source>SHOW_ONLY_SELECTED</source>
</message>
<message>
<source>GEOM_PLUGINS_OTHER</source>
- <translation>Autre</translation>
+ <translation>Plugins Python</translation>
</message>
<message>
<source>SHOW_ONLY_SELECTED</source>
#include <Geom_Plane.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_Surface.hxx>
+#include <Geom_TrimmedCurve.hxx>
#include <Precision.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TDF_Tool.hxx>
U = U11+range*2.0/3.0;
gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
+ C2 = new Geom_TrimmedCurve(C2, U21, U22);
+
if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
return false;
#define GROUP_SIDE2 3
#define GROUP_OTHER 4
+static const Standard_Real TolPipeSurf = 5.e-4;
+
static bool FillGroups(const TopTools_SequenceOfShape *theGroups,
const TopTools_IndexedMapOfShape &theIndices,
Handle(TColStd_HArray1OfInteger) *theGroupIds);
Standard_Boolean isDone = theBuilder.IsDone();
- if (!isDone) {
+ if (!isDone ||
+ theBuilder.ErrorOnSurface() > TolPipeSurf) {
// Try to use Descrete Trihedron mode.
theBuilder.SetDiscreteMode();
theBuilder.Build();
GeomFill_Trihedron theBestMode = EvaluateBestSweepMode(aWirePath);
BRepOffsetAPI_MakePipe aMkPipe(aWirePath, aShapeBase, theBestMode);
- if (aMkPipe.IsDone()) {
+ if (aMkPipe.IsDone() && aMkPipe.ErrorOnSurface() <= TolPipeSurf) {
aShape = aMkPipe.Shape();
if (!CreateGroups(aShapeBase, aWirePath, aMkPipe, aCI)) {
TopoDS_Shape aShape;
if (GEOMBase::GetShape(aGeomObj, aShape)) {
if (aGeomObj->GetType() == GEOM_GROUP || aShape.ShapeType() == getShapeType()) {
+ if (subSelectionWay() != ALL_SUBSHAPES &&
+ GEOMBase::GetName(aGeomObj) == myShape2Name->text()) {
+ // Skip selected in place object.
+ continue;
+ }
+
TopTools_IndexedMapOfShape aMainMap;
TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
TopExp::MapShapes(aMainShape, aMainMap);
if ( hasEdges != 0 )
hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_EDGE ) > 0;
if ( hasFaces != 0 )
- hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_FACE ) > 0;
+ hasFaces = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_FACE ) > 0;
if ( hasSolids != 0 )
- hasEdges = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_SOLID ) > 0;
+ hasSolids = aShOp->NumberOfSubShapes( aShapePtr.get(), TopAbs_SOLID ) > 0;
}
fillTypes( hasEdges, hasFaces, hasSolids );
}
--- /dev/null
+# Copyright (C) 2012-2014 EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+ADD_SUBDIRECTORY(t_shape)
+
+
+IF(SALOME_BUILD_GUI)
+ # scripts / static
+ SET(plugin_SCRIPTS
+ geom_plugins.py
+ )
+
+ # --- rules ---
+ SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_GEOM_INSTALL_PLUGINS})
+ENDIF()
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Renaud Nédélec (OpenCascade S.A.S)
+
+import salome_pluginsmanager
+
+def t_shape_fluid(context):
+ #from salome.geom.t_shape import t_shape_builder
+ from salome.geom.t_shape import t_shape_dialog
+ from salome.geom.t_shape import t_shape_progress
+ import xalome
+ from PyQt4.QtGui import QMessageBox
+ activeStudy = context.study
+
+ dialog = t_shape_dialog.TShapeDialog()
+
+ # Get the parameter values from a gui dialog box. If the dialog is
+ # closed using the Ok button, then the data are requested from the
+ # gui and used to create the shape of the tube.
+ dialog.exec_()
+ if dialog.wasOk():
+ r1, r2, h1, h2, thickness = dialog.getData()
+ #QMessageBox.about(None, "Building in progress", "building shape, please be patient")
+ #shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2, thickness)
+ shapeBuilder = t_shape_progress.t_shape_progress()
+ shape = shapeBuilder.run(activeStudy, r1, r2, h1, h2, thickness)
+ entry = xalome.addToStudy(activeStudy, shape, "T_shape_fluid" )
+ xalome.displayShape(entry)
+ #if dialog.wasOk():
+ #radius, length, width = dialog.getData()
+ #shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+ #entry = xalome.addToStudy(activeStudy, shape, "Tube" )
+ #xalome.displayShape(entry)
+
+
+salome_pluginsmanager.AddFunction('T shape fluid',
+ 'Creates the fluid part of a pipe T-shape',
+ t_shape_fluid)
\ No newline at end of file
--- /dev/null
+# Copyright (C) 2012-2014 EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+IF(SALOME_BUILD_GUI)
+ INCLUDE(UsePyQt)
+ENDIF()
+
+# --- scripts ---
+
+# base scripts
+SET(base_SCRIPTS
+ __init__.py
+ t_shape_builder.py
+ )
+
+IF(SALOME_BUILD_GUI)
+ # gui scripts
+ SET(gui_SCRIPTS
+ t_shape_dialog.py
+ t_shape_dialog.ui
+ t_shape_progress.py
+ )
+
+ # uic files / to be processed by pyuic
+ SET(_pyuic_files
+ t_shape_dialog.ui
+ )
+
+ # scripts / pyuic wrappings
+ PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files})
+ENDIF()
+
+# --- rules ---
+
+SALOME_INSTALL_SCRIPTS("${base_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/geom/t_shape)
+
+IF(SALOME_BUILD_GUI)
+ SALOME_INSTALL_SCRIPTS("${gui_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/geom/t_shape)
+ SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/geom/t_shape)
+ENDIF()
\ No newline at end of file
--- /dev/null
+# -*- coding: utf-8 -*-
--- /dev/null
+# -*- coding: utf-8 -*-
+
+import sys
+import salome
+
+import GEOM
+from salome.geom import geomBuilder
+import math
+import SALOMEDS
+import time
+
+geompy = None
+
+def demidisk(study, r1, a1, roty=0, solid_thickness=0):
+ if solid_thickness < 1e-7:
+ with_solid = False
+ else:
+ with_solid = True
+
+ #geompy = geomBuilder.New(study)
+
+ O = geompy.MakeVertex(0, 0, 0)
+ OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
+ OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
+ OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
+
+ v=range(8)
+ l=range(8)
+ v0 = geompy.MakeVertex(0, 0, 0)
+ v[0] = geompy.MakeVertex(0, r1/2.0, 0)
+ v[1] = geompy.MakeVertex(0, r1, 0)
+ l[1] = geompy.MakeLineTwoPnt(v[0], v[1])
+ l[2] = geompy.MakeRotation(l[1], OX, a1*math.pi/180.0)
+ v[4] = geompy.MakeRotation(v[0], OX, a1*math.pi/180.0)
+ v[6] = geompy.MakeRotation(v[1], OX, a1*math.pi/180.0)
+
+ v[2] = geompy.MakeVertex(0, -r1/2.0, 0)
+ v[3] = geompy.MakeVertex(0, -r1, 0)
+ l[3] = geompy.MakeLineTwoPnt(v[2], v[3])
+ l[4] = geompy.MakeRotation(l[3], OX, -a1*math.pi/180.0)
+ v[5] = geompy.MakeRotation(v[2], OX, -a1*math.pi/180.0)
+ v[7] = geompy.MakeRotation(v[3], OX, -a1*math.pi/180.0)
+
+ l[5] = geompy.MakeLineTwoPnt(v[4], v[5])
+ l[6] = geompy.MakeLineTwoPnt(v[0], v[4])
+ l[7] = geompy.MakeLineTwoPnt(v[2], v[5])
+
+ v7 = geompy.MakeVertex(0, 0, r1)
+ arc1 = geompy.MakeArc(v[1], v7, v[3])
+ l[0] = geompy.MakeLineTwoPnt(v[1], v[3])
+ face1 = geompy.MakeFaceWires([arc1, l[0]], 1)
+ part1 = geompy.MakePartition([face1], [l[2], l[4], l[5], l[6], l[7]], [], [], geompy.ShapeType["FACE"], 0, [], 0, True)
+
+ if with_solid:
+ # Add some faces corresponding to the solid layer outside
+ # the fluid part
+
+ # --- Vertices
+ v0 = geompy.MakeVertex(0, r1 + solid_thickness, 0)
+ v1 = geompy.MakeRotation(v0, OX, a1*math.pi/180.0)
+ v2 = geompy.MakeRotation(v0, OX, math.pi - (a1*math.pi/180.0))
+ v3 = geompy.MakeRotation(v0, OX, math.pi)
+ v.extend([v0,v1,v3,v2]) # The order is important for use in pointsProjetes
+ # --- Lines
+ l0 = geompy.MakeLineTwoPnt(v[1], v0)
+ l2 = geompy.MakeRotation(l0, OX, a1*math.pi/180.0)
+ l3 = geompy.MakeRotation(l0, OX, math.pi - (a1*math.pi/180.0))
+ # --- Faces
+ face2 = geompy.MakeRevolution(l0, OX, a1*math.pi/180.0)
+ face3 = geompy.MakeRevolution(l2, OX, math.pi - 2*a1*math.pi/180.0)
+ face4 = geompy.MakeRevolution(l3, OX, a1*math.pi/180.0)
+ # --- Compound of the "fluid part" of the divided disk and the additional faces
+ compound1 = geompy.MakeCompound([part1, face2, face3, face4])
+ # --- Glue edges
+ part1 = geompy.MakeGlueEdges(compound1,1e-7)
+
+ if roty != 0:
+ vrot = [ geompy.MakeRotation(vert, OY, roty*math.pi/180.0) for vert in v ]
+ lrot = [ geompy.MakeRotation(lin, OY, roty*math.pi/180.0) for lin in l ]
+ arc = geompy.MakeRotation(arc1, OY, roty*math.pi/180.0)
+ part = geompy.MakeRotation(part1, OY, roty*math.pi/180.0)
+ return vrot, lrot, arc, part
+ else:
+ return v, l, arc1, part1
+
+def pointsProjetes(study, vref, face):
+ #geompy = geomBuilder.New(study)
+ vface = geompy.ExtractShapes(face, geompy.ShapeType["VERTEX"], True)
+ vord = range(len(vref))
+ plan = geompy.MakePlaneThreePnt(vref[0], vref[1], vref[-1], 10000)
+ vproj = [ geompy.MakeProjection(vert, plan) for vert in vface ]
+ for i,v in enumerate(vproj):
+ dist = [ (geompy.MinDistance(v, vr), j) for j,vr in enumerate(vref) ]
+ dist.sort()
+ if dist[0][0] < 1.e-3:
+ vord[dist[0][1]] = vface[i]
+ return vord
+
+def arcsProjetes(study, vf, face):
+ #geompy = geomBuilder.New(study)
+ lface = geompy.ExtractShapes(face, geompy.ShapeType["EDGE"], True)
+ lord = range(3)
+ ends = [vf[1], vf[6], vf[7], vf[3]]
+ for i in range(3):
+ for lf in lface:
+ pts = geompy.ExtractShapes(lf, geompy.ShapeType["VERTEX"], True)
+ if (((geompy.MinDistance(pts[0], ends[i]) < 0.001) and (geompy.MinDistance(pts[1], ends[i+1]) < 0.001)) or
+ ((geompy.MinDistance(pts[1], ends[i]) < 0.001) and (geompy.MinDistance(pts[0], ends[i+1]) < 0.001))):
+ lord[i] = lf
+ #print "arc_%d OK"%i
+ break
+ pass
+ return lord
+
+def build_shape(study, r1, r2, h1, h2, solid_thickness=0, progressBar=None ):
+ """ Builds the final shape """
+
+ if progressBar is not None:
+ time0 = time.time()
+ print time.time() -time0
+
+ if solid_thickness < 1e-7:
+ with_solid = False
+ else:
+ with_solid = True
+
+ global geompy
+ geompy = geomBuilder.New(study)
+
+ O = geompy.MakeVertex(0, 0, 0)
+ OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
+ OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
+ OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
+
+ a1 = 45.0
+ seuilmax = 0.1
+ ratio = float(r2)/float(r1)
+ if ratio > (1.0 -seuilmax):
+ a1 = 45.0*(1.0 -ratio)/seuilmax
+
+ # --- Creation of the jonction faces
+ [faci, sect45, arc1, l1, lord90, lord45, edges, arcextru] = jonction(study, r1, r2,\
+ h1, h2, a1)
+ if progressBar is not None:
+ progressBar.addSteps(2)
+ print time.time() -time0
+
+ if with_solid:
+ # The same code is executed again with different external radiuses in order
+ # to get the needed faces and edges to build the solid layer of the pipe
+ [faci_ext, sect45_ext, arc1_ext, l1_ext, \
+ lord90_ext, lord45_ext, edges_ext, arcextru_ext] = jonction(study, r1 + solid_thickness, r2 + solid_thickness,\
+ h1, h2, a1)
+ faces_jonction_ext = []
+ for i,l in enumerate(lord90):
+ faces_jonction_ext.append(geompy.MakeQuad2Edges(lord90[i],lord90_ext[i]))
+ for i in [1, 3, 6, 7]:
+ faces_jonction_ext.append(geompy.MakeQuad2Edges(edges[i],edges_ext[i]))
+ for i,l in enumerate(lord45):
+ faces_jonction_ext.append(geompy.MakeQuad2Edges(lord45[i],lord45_ext[i]))
+
+ if progressBar is not None:
+ progressBar.addSteps(4)
+ print time.time() -time0
+
+ # --- extrusion droite des faces de jonction, pour reconstituer les demi cylindres
+ if with_solid:
+ sect45 = geompy.MakeCompound([sect45]+faces_jonction_ext[-3:])
+ sect45 = geompy.MakeGlueEdges(sect45, 1e-7)
+
+ if progressBar is not None:
+ progressBar.addSteps(1)
+ print time.time() -time0
+
+ extru1 = geompy.MakePrismVecH(sect45, OX, h1+10)
+
+ faces_coupe = faci[5:]
+ if with_solid:
+ faces_coupe = faci[5:]+faces_jonction_ext[:3]
+ base2 = geompy.MakePartition(faces_coupe, [], [], [], geompy.ShapeType["FACE"], 0, [], 0, True)
+ extru2 = geompy.MakePrismVecH(base2, OZ, h2)
+
+ if progressBar is not None:
+ progressBar.addSteps(1)
+ print time.time() -time0
+
+ # --- partition et coupe
+
+ if with_solid:
+ demiDisque = geompy.MakeFaceWires([arc1_ext, l1_ext[0]], 1)
+ else:
+ demiDisque = geompy.MakeFaceWires([arc1, l1[0]], 1)
+ demiCylindre = geompy.MakePrismVecH(demiDisque, OX, h1)
+
+ if progressBar is not None:
+ progressBar.addSteps(1)
+ print time.time() -time0
+
+ box = geompy.MakeBox(0, -2*(r1+h1), -2*(r1+h1), 2*(r1+h1), 2*(r1+h1), 2*(r1+h1))
+ rot = geompy.MakeRotation(box, OY, 45*math.pi/180.0)
+
+ # NOTE: The following Cut takes almost half of the total execution time
+ garder = geompy.MakeCutList(demiCylindre, [extru2, rot], True)
+
+ if progressBar is not None:
+ progressBar.addSteps(9)
+ print time.time() -time0
+
+ faces_coupe = faci[:5]
+ if with_solid:
+ faces_coupe.extend(faces_jonction_ext[-7:])
+ raccord = geompy.MakePartition([garder], faces_coupe + [arcextru], [], [], geompy.ShapeType["SOLID"], 0, [], 0, True)
+ assemblage = geompy.MakeCompound([raccord, extru1, extru2])
+ assemblage = geompy.MakeGlueFaces(assemblage, 1e-7)
+
+ if progressBar is not None:
+ progressBar.addSteps(3)
+ print time.time() -time0
+
+ box = geompy.MakeBox(-1, -(r1+r2+2*solid_thickness), -1, h1, r1+r2+2*solid_thickness, h2)
+
+ # NOTE: This operation takes about 1/4 of the total execution time
+ final = geompy.MakeCommonList([box, assemblage], True)
+
+ if progressBar is not None:
+ progressBar.addSteps(5)
+ print time.time() -time0
+
+ # --- Partie inférieure
+
+ v3, l3, arc3, part3 = demidisk(study, r1, a1, 180.0, solid_thickness)
+ extru3 = geompy.MakePrismVecH(part3, OX, h1)
+
+ # --- Symétrie
+
+ compound = geompy.MakeCompound([final, extru3])
+ plane = geompy.MakePlane(O,OX,2000)
+ compound_mirrored = geompy.MakeMirrorByPlane(compound, plane)
+ final = geompy.MakeCompound([compound, compound_mirrored])
+
+ if progressBar is not None:
+ progressBar.addSteps(1)
+ print time.time() -time0
+
+ return final
+
+
+def jonction(study, r1, r2, h1, h2, a1):
+ """ Builds the jonction faces and
+ returns what is needed to build the whole pipe
+ """
+ #geompy = geomBuilder.New(study)
+
+ O = geompy.MakeVertex(0, 0, 0)
+ OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
+ OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
+ OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
+
+ # --- sections droites des deux demi cylindres avec le partionnement
+ v1, l1, arc1, part1 = demidisk(study, r1, a1, 0.)
+ v2, l2, arc2, part2 = demidisk(study, r2, a1, 90.0)
+
+ # --- extrusion des sections --> demi cylindres de travail, pour en extraire les sections utilisées au niveau du Té
+ # et enveloppe cylindrique du cylindre principal
+
+ demicyl1 = geompy.MakePrismVecH(part1, OX, h1)
+ demicyl2 = geompy.MakePrismVecH(part2, OZ, h2)
+ arcextru = geompy.MakePrismVecH(arc1, OX, h1)
+
+ # --- plan de coupe à 45° sur le cylindre principal,
+ # section à 45° du cylndre principal,
+ # section du cylindre secondaire par l'enveloppe cylindrique du cylindre principal
+
+ plan1 = geompy.MakePlane(O, OX, 4*r1)
+ planr = geompy.MakeRotation(plan1, OY, 45*math.pi/180.0)
+
+ sect45 = geompy.MakeCommonList([demicyl1, planr], True)
+ sect90 = geompy.MakeCommonList([demicyl2, arcextru], True)
+ #geompy.addToStudy(sect90, "sect90")
+
+ # --- liste ordonnée des points projetés sur les deux sections
+
+ vord45 = pointsProjetes(study, v1, sect45)
+ vord90 = pointsProjetes(study, v2, sect90)
+
+ # --- identification des projections des trois arcs de cercle, sur les deux sections.
+
+ lord45 = arcsProjetes(study, vord45, sect45)
+ lord90 = arcsProjetes(study, vord90, sect90)
+
+ # --- abaissement des quatre points centraux de la section du cylindre secondaire
+
+ dz = -r2/2.0
+ for i in (0, 2, 4, 5):
+ vord90[i] = geompy.TranslateDXDYDZ(vord90[i], 0, 0, dz, True)
+ #geompy.addToStudyInFather(sect90, vord90[i], 'vm%d'%i)
+
+ # --- création des deux arêtes curvilignes sur l'enveloppe cylindrique du cylindre principal, à la jonction
+
+ curv = [None for i in range(4)] # liaisons entre les points 1, 3, 6 et 7 des 2 sections
+
+ curv[0] = geompy.MakeArcCenter(O, vord90[1] , vord45[1], False)
+ curv[1] = geompy.MakeArcCenter(O, vord90[3] , vord45[3], False)
+
+ lipts = ((6, 6, 4), (7, 7, 5))
+ for i, ipts in enumerate(lipts):
+ #print i, ipts
+ p0 = vord90[ipts[0]]
+ p1 = vord45[ipts[1]]
+ p2 = vord45[ipts[2]]
+ plan = geompy.MakePlaneThreePnt(p0, p1, p2, 10000)
+ #geompy.addToStudy(plan, "plan%d"%i)
+ section = geompy.MakeSection(plan, arcextru, True)
+ secpart = geompy.MakePartition([section], [sect45, sect90], [], [], geompy.ShapeType["EDGE"], 0, [], 0, True)
+ #geompy.addToStudy(secpart, "secpart%d"%i)
+ lsec = geompy.ExtractShapes(secpart, geompy.ShapeType["EDGE"], True)
+
+ for l in lsec:
+ pts = geompy.ExtractShapes(l, geompy.ShapeType["VERTEX"], True)
+ if (((geompy.MinDistance(pts[0], p0) < 0.001) and (geompy.MinDistance(pts[1], p1) < 0.001)) or
+ ((geompy.MinDistance(pts[1], p0) < 0.001) and (geompy.MinDistance(pts[0], p1) < 0.001))):
+ curv[i+2] =l
+ #print "curv_%d OK"%i
+ break
+
+ # --- creation des arêtes droites manquantes, des faces et volumes pour les quatre volumes de la jonction
+
+ edges = [None for i in range(8)]
+ edges[0] = geompy.MakeLineTwoPnt(vord45[0], vord90[0])
+ edges[1] = curv[0]
+ edges[2] = geompy.MakeLineTwoPnt(vord45[2], vord90[2])
+ edges[3] = curv[1]
+ edges[4] = geompy.MakeLineTwoPnt(vord45[4], vord90[4])
+ edges[5] = geompy.MakeLineTwoPnt(vord45[5], vord90[5])
+ edges[6] = curv[2]
+ edges[7] = curv[3]
+
+ ed45 = [None for i in range(8)]
+ ed45[0] = geompy.MakeLineTwoPnt(vord45[0], vord45[2])
+ ed45[1] = geompy.MakeLineTwoPnt(vord45[0], vord45[1])
+ ed45[2] = geompy.MakeLineTwoPnt(vord45[4], vord45[6])
+ ed45[3] = geompy.MakeLineTwoPnt(vord45[2], vord45[3])
+ ed45[4] = geompy.MakeLineTwoPnt(vord45[5], vord45[7])
+ ed45[5] = geompy.MakeLineTwoPnt(vord45[4], vord45[5])
+ ed45[6] = geompy.MakeLineTwoPnt(vord45[0], vord45[4])
+ ed45[7] = geompy.MakeLineTwoPnt(vord45[2], vord45[5])
+
+ ed90 = [None for i in range(8)]
+ ed90[0] = geompy.MakeLineTwoPnt(vord90[0], vord90[2])
+ ed90[1] = geompy.MakeLineTwoPnt(vord90[0], vord90[1])
+ ed90[2] = geompy.MakeLineTwoPnt(vord90[4], vord90[6])
+ ed90[3] = geompy.MakeLineTwoPnt(vord90[2], vord90[3])
+ ed90[4] = geompy.MakeLineTwoPnt(vord90[5], vord90[7])
+ ed90[5] = geompy.MakeLineTwoPnt(vord90[4], vord90[5])
+ ed90[6] = geompy.MakeLineTwoPnt(vord90[0], vord90[4])
+ ed90[7] = geompy.MakeLineTwoPnt(vord90[2], vord90[5])
+
+ faci = []
+ faci.append(geompy.MakeFaceWires([ed45[6], edges[0], ed90[6], edges[4]], 0))
+ faci.append(geompy.MakeFaceWires([ed45[7], edges[2], ed90[7], edges[5]], 0))
+ faci.append(geompy.MakeFaceWires([ed45[2], edges[4], ed90[2], edges[6]], 0))
+ faci.append(geompy.MakeFaceWires([ed45[5], edges[4], ed90[5], edges[5]], 0))
+ faci.append(geompy.MakeFaceWires([ed45[4], edges[5], ed90[4], edges[7]], 0))
+ faci.append(geompy.MakeFaceWires([ed90[0], ed90[6], ed90[5], ed90[7]], 0))
+ faci.append(geompy.MakeFaceWires([ed90[1], ed90[6], ed90[2], lord90[0]], 0))
+ faci.append(geompy.MakeFaceWires([ed90[2], ed90[5], ed90[4], lord90[1]], 0))
+ faci.append(geompy.MakeFaceWires([ed90[3], ed90[7], ed90[4], lord90[2]], 0))
+
+ return faci, sect45, arc1, l1, lord90, lord45, edges, arcextru
+
+def test_t_shape_builder():
+ """For testing purpose"""
+ salome.salome_init()
+ theStudy = salome.myStudy
+ geompy = geomBuilder.New(theStudy)
+ for r1 in [1., 100.]:
+ for r2 in [0.9*r1, 0.5*r1, 0.1*r1, 0.05*r1]:
+ for thickness in [r1/100., r1/10., r1/2.]:
+ print r1, r2, thickness
+ h1 = r1 * 2.0
+ h2 = h1
+ try:
+ res = build_shape(theStudy, r1, r2, h1, h2, thickness)
+ geompy.addToStudy(res, "res_%f_%f_%f"%(r1,r2, thickness))
+ except:
+ print "problem with res_%f_%f_%f"%(r1,r2, thickness)
+
+if __name__=="__main__":
+ """For testing purpose"""
+ test_t_shape_builder()
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Renaud Nédélec (OpenCascade S.A.S)
+
+import sys
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+from t_shape_dialog_ui import Ui_Dialog
+
+
+class TShapeDialog(QtGui.QDialog):
+ def __init__(self):
+ QtGui.QDialog.__init__(self, None, QtCore.Qt.Tool)
+ # Set up the user interface from Designer.
+ self.ui = Ui_Dialog()
+ self.ui.setupUi(self)
+ self.show()
+ self._wasOk = False
+ self.ui.dsb_solidThickness.setEnabled(False)
+ self.ui.label_5.setEnabled(False)
+ self.ui.dsb_bigRadius.setValue(50.0)
+ self.ui.dsb_smallRadius.setValue(40.0)
+ self.ui.dsb_bigHeight.setValue(80.0)
+ self.ui.dsb_smallHeight.setValue(80.0)
+
+ def accept(self):
+ self._wasOk = True
+ QtGui.QDialog.accept(self)
+
+ def getData(self):
+ r1 = self.ui.dsb_bigRadius.value()
+ r2 = self.ui.dsb_smallRadius.value()
+ h1 = self.ui.dsb_bigHeight.value()
+ h2 = self.ui.dsb_smallHeight.value()
+ thickness = 0.0
+ if self.ui.cb_buildSolid.isChecked():
+ thickness = self.ui.dsb_solidThickness.value()
+
+ return r1, r2, h1, h2, thickness
+
+ def reject(self):
+ self._wasOk = False
+ QtGui.QDialog.reject(self)
+
+ def wasOk(self):
+ return self._wasOk
+
+
+# ================
+# Tests
+# ================
+
+def main( args ):
+ import sys
+ app = QtGui.QApplication(sys.argv)
+ Dialog = TShapeDialog()
+ ui = Ui_Dialog()
+ ui.setupUi(Dialog)
+ Dialog.show()
+ sys.exit(app.exec_())
+
+if __name__=="__main__":
+ main(sys.argv)
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>349</width>
+ <height>283</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="1">
+ <widget class="QDoubleSpinBox" name="dsb_smallRadius">
+ <property name="decimals">
+ <number>5</number>
+ </property>
+ <property name="maximum">
+ <double>100000.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>40.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Big pipe radius</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QDoubleSpinBox" name="dsb_bigHeight">
+ <property name="decimals">
+ <number>5</number>
+ </property>
+ <property name="maximum">
+ <double>1000000.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>80.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QDoubleSpinBox" name="dsb_smallHeight">
+ <property name="decimals">
+ <number>5</number>
+ </property>
+ <property name="maximum">
+ <double>1000000.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>80.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QDoubleSpinBox" name="dsb_bigRadius">
+ <property name="decimals">
+ <number>5</number>
+ </property>
+ <property name="maximum">
+ <double>100000.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>50.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Big pipe height</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Small pipe radius</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Small pipe height</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="cb_buildSolid">
+ <property name="text">
+ <string>Build solid part</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Solid thickness</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="dsb_solidThickness">
+ <property name="decimals">
+ <number>5</number>
+ </property>
+ <property name="maximum">
+ <double>1000000.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>5.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Dialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>205</x>
+ <y>241</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>250</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Dialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>205</x>
+ <y>241</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>214</x>
+ <y>250</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cb_buildSolid</sender>
+ <signal>clicked(bool)</signal>
+ <receiver>label_5</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>99</x>
+ <y>170</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>107</x>
+ <y>205</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cb_buildSolid</sender>
+ <signal>clicked(bool)</signal>
+ <receiver>dsb_solidThickness</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>150</x>
+ <y>170</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>277</x>
+ <y>212</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Renaud Nédélec (OpenCascade S.A.S)
+
+from salome.geom.t_shape import t_shape_builder
+from PyQt4.QtGui import QProgressDialog
+from PyQt4 import QtCore
+
+class t_shape_progress(QProgressDialog):
+ _totSteps = 0
+ _nmaxSteps = 27
+
+ def __init__(self, parent=None):
+ QProgressDialog.__init__(self, "t_shape fluid build", "stop", 0, self._nmaxSteps, parent, QtCore.Qt.Tool)
+ self.show()
+
+ def run(self, activeStudy, r1, r2, h1, h2, thickness):
+ shape = t_shape_builder.build_shape(activeStudy, r1, r2, h1, h2, thickness, self)
+ self.setValue(self._nmaxSteps)
+ return shape
+
+ def addSteps(self, nbSteps):
+ self._totSteps += nbSteps
+ self.setValue(self._totSteps)