]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Démarrage de la macro tuyauterie
authorGérald NICOLAS <gerald.nicolas@edf.fr>
Tue, 15 Jun 2021 09:16:43 +0000 (11:16 +0200)
committerGérald NICOLAS <gerald.nicolas@edf.fr>
Tue, 15 Jun 2021 09:16:43 +0000 (11:16 +0200)
17 files changed:
src/PythonAddons/CMakeLists.txt
src/PythonAddons/PythonAddons_msg_en.ts
src/PythonAddons/PythonAddons_msg_fr.ts [new file with mode: 0644]
src/PythonAddons/Test/Testpiping.py [new file with mode: 0755]
src/PythonAddons/addons_Features.py
src/PythonAddons/addons_Features.xml.in
src/PythonAddons/doc/addons_Features.rst
src/PythonAddons/doc/pipingFeature.rst [new file with mode: 0644]
src/PythonAddons/macros/compoundVertices/widget.xml
src/PythonAddons/macros/importParameters/widget.xml
src/PythonAddons/macros/piping/__init__.py [new file with mode: 0644]
src/PythonAddons/macros/piping/feature.py [new file with mode: 0644]
src/PythonAddons/macros/piping/icons/piping.png [new file with mode: 0644]
src/PythonAddons/macros/piping/piping.txt [new file with mode: 0644]
src/PythonAddons/macros/piping/piping2.txt [new file with mode: 0644]
src/PythonAddons/macros/piping/widget.xml [new file with mode: 0644]
src/PythonAddons/tests.set

index 289f365e7c9dfc1d90bdd0dcd97d047d7b7c901b..a4b0f4c266ffddd85ca5ad7a77559074d4a92974 100644 (file)
@@ -19,6 +19,7 @@
 
 SET(TEXT_RESOURCES
        PythonAddons_msg_en.ts
+       PythonAddons_msg_fr.ts
 )
 
 # configuration
@@ -42,6 +43,7 @@ INSTALL(DIRECTORY macros DESTINATION ${SHAPER_INSTALL_ADDONS})
 INSTALL(DIRECTORY macros/rectangle/icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Addons)
 INSTALL(DIRECTORY macros/compoundVertices/icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Addons)
 INSTALL(DIRECTORY macros/importParameters/icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Addons)
+INSTALL(DIRECTORY macros/piping/icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Addons)
 INSTALL(FILES ${TEXT_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES})
 
 INCLUDE(UnitTest)
index 305ed4131767bf8eecf7e9502b42a027cc6122ac..482222d27384a65376d544812a60788f52303337 100644 (file)
@@ -1,4 +1,66 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
 <TS version="2.0" language="en_US">
+
+  <!-- compoundVertices -->
+  <context>
+    <name>compoundVertices</name>
+    <message>
+      <source>Points set</source>
+      <translation>Import points</translation>
+    </message>
+    <message>
+      <source>Import a set of construction points</source>
+      <translation>Import a set of construction points</translation>
+    </message>
+  </context>
+  <context>
+    <name>compoundVertices:file_path</name>
+    <message>
+      <source>Import file</source>
+      <translation>Import txt file (X Y Z)</translation>
+    </message>
+    <message>
+      <source>Select file</source>
+      <translation>Select the file of the points,
+      defined by their coordinates X Y Z</translation>
+    </message>
+  </context>
+  <context>
+    <name>compoundVertices:separator</name>
+    <message>
+      <source>Separator (optional):</source>
+      <translation>Separator (optional):</translation>
+    </message>
+    <message>
+      <source>"Select separator"</source>
+      <translation>Select a separator; the default value is white spaces.</translation>
+    </message>
+  </context>
+
+  <!-- importParameters -->
+  <context>
+    <name>importParameters</name>
+    <message>
+      <source>Import Parameters</source>
+      <translation>Import parameters</translation>
+    </message>
+    <message>
+      <source>Import a set of parameters</source>
+      <translation>Import a set of parameters</translation>
+    </message>
+  </context>
+  <context>
+    <name>importParameters:file_path</name>
+    <message>
+      <source>Import file</source>
+      <translation>Import file</translation>
+    </message>
+    <message>
+      <source>Select file</source>
+      <translation>Select the file of the parameters,
+      defined by couples: name, value</translation>
+    </message>
+  </context>
+
 </TS>
diff --git a/src/PythonAddons/PythonAddons_msg_fr.ts b/src/PythonAddons/PythonAddons_msg_fr.ts
new file mode 100644 (file)
index 0000000..14ac12a
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+
+  <!-- compoundVertices -->
+  <context>
+    <name>compoundVertices</name>
+    <message>
+      <source>Points set</source>
+      <translation>Importer des points</translation>
+    </message>
+    <message>
+      <source>Import a set of construction points</source>
+      <translation>Importer un ensemble de points de construction</translation>
+    </message>
+  </context>
+  <context>
+    <name>compoundVertices:file_path</name>
+    <message>
+      <source>Import file</source>
+      <translation>Fichier des points à importer (X Y Z)</translation>
+    </message>
+    <message>
+      <source>Select file</source>
+      <translation>Choisir le fichier contenant les points à importer,
+      définis par leurs coordonnées X Y Z</translation>
+    </message>
+  </context>
+  <context>
+    <name>compoundVertices:separator</name>
+    <message>
+      <source>Separator (optional):</source>
+      <translation>Séparateur (optionnel) :</translation>
+    </message>
+    <message>
+      <source>"Select separator"</source>
+      <translation>Choisir éventuellement un séparateur ; par défaut ce sont des blancs.</translation>
+    </message>
+  </context>
+
+  <!-- importParameters -->
+  <context>
+    <name>importParameters</name>
+    <message>
+      <source>Import Parameters</source>
+      <translation>Importer des paramètres</translation>
+    </message>
+    <message>
+      <source>Import a set of parameters</source>
+      <translation>Importer un ensemble de paramètres</translation>
+    </message>
+  </context>
+  <context>
+    <name>importParameters:file_path</name>
+    <message>
+      <source>Import file</source>
+      <translation>Fichier des paramètres à importer</translation>
+    </message>
+    <message>
+      <source>Select file</source>
+      <translation>Choisir le fichier contenant les paramètres à importer,
+      définis par les paires : nom, valeur</translation>
+    </message>
+  </context>
+
+</TS>
diff --git a/src/PythonAddons/Test/Testpiping.py b/src/PythonAddons/Test/Testpiping.py
new file mode 100755 (executable)
index 0000000..825d0bb
--- /dev/null
@@ -0,0 +1,47 @@
+# Copyright (C) 2014-2021  CEA/DEN, 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
+#
+
+from salome.shaper import model
+from salome.shaper import geom
+from ModelAPI import *
+
+import os
+
+aSession = ModelAPI_Session.get()
+
+def getFilePath(fileName):
+    path = os.path.join(os.getenv("SHAPER_ROOT_DIR"), "bin", "salome", "macros", "piping")
+    return os.path.join(path, fileName)
+
+theFile = getFilePath("piping.txt")
+
+aSession.startOperation("Create part for import")
+aPartFeature = aSession.moduleDocument().addFeature("Part")
+aSession.finishOperation()
+aPart = aSession.activeDocument()
+
+aSession.startOperation("Import file")
+aFeatureKind = "piping"
+anImportFeature = aPart.addFeature(aFeatureKind)
+aFieldName = "file_path"
+aFile = anImportFeature.string(aFieldName)
+aFile.setValue(theFile)
+aSession.finishOperation()
+
+assert(model.checkPythonDump())
index 64fbca8484131a2a780a4c1dd17a57b1ff396b1f..bba4206025887a9b628f36a38478efc904816501 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-"""Registration of all user-defined Python features
-"""
+"""Registration of all user-defined Python features"""
 
 import ModelAPI
 from macros.rectangle.feature import SketchPlugin_Rectangle
 from macros.compoundVertices.feature import compoundVertices
 from macros.importParameters.feature import importParameters
+from macros.piping.feature import piping
 
 
 class PythonFeaturesPlugin(ModelAPI.ModelAPI_Plugin):
@@ -49,6 +49,8 @@ class PythonFeaturesPlugin(ModelAPI.ModelAPI_Plugin):
             aFeature = compoundVertices().__disown__()
         elif theFeatureID == importParameters.ID():
             aFeature = importParameters().__disown__()
+        elif theFeatureID == piping.ID():
+            aFeature = piping().__disown__()
         else:
             raise Exception("No such feature %s" % theFeatureID)
 
index 3f3b7666d7f1b41f33820f09202eaf5ddc8597c1..83027f311fe6c6900eb0eda86a030d0f5c478daf 100644 (file)
@@ -2,4 +2,5 @@
   <source path="@ADDONS_FOLDER_PATH@/macros/rectangle/widget.xml"/>
   <source path="@ADDONS_FOLDER_PATH@/macros/compoundVertices/widget.xml"/>
   <source path="@ADDONS_FOLDER_PATH@/macros/importParameters/widget.xml"/>
+  <source path="@ADDONS_FOLDER_PATH@/macros/piping/widget.xml"/>
 </plugin>
index 1db6329d641b948d2c99f16223f01903ea839a8c..a5ec3d401904060d88981aa5e8bba0bb3e3b04cc 100644 (file)
@@ -22,3 +22,4 @@ Some examples of already created custom features are:
    rectangleFeature.rst
    compoundVerticesFeature.rst
    importParametersFeature.rst
+   pipingFeature.rst
diff --git a/src/PythonAddons/doc/pipingFeature.rst b/src/PythonAddons/doc/pipingFeature.rst
new file mode 100644 (file)
index 0000000..7f04edb
--- /dev/null
@@ -0,0 +1,37 @@
+.. _piping:
+.. |compoundVertices.icon|    image:: images/compound.png
+
+Piping
+======
+
+Compound Vertices is a feature and can be edited after execution.
+It allows creation of several points basing on XYZ coords file.
+
+.. warning::
+  Please note that it is better to limit yourself to create a maximum of 100 points.
+
+These set of points will be grouped in a compound and can be used for others features.
+
+To add a new set of points:
+
+#. select in the Main Menu *Macros - > Points set* item  or
+#. click |compoundVertices.icon| **Points set** button in Macros toolbar:
+
+The following property panel appears:
+
+.. figure:: images/compoundVerticesPanel.png
+   :align: center
+
+   set of Points
+
+Select your points file and define a separator if it's different that " " in your points file
+
+Result
+""""""
+
+A resulting compound will contain the points
+
+.. figure:: images/compoundVertices.png
+   :align: center
+
+   Points
index c33e845dd1f9511d3560bbb6a32ca6207dceb280..4899ed4f171ff7577036d4bd543332673ec839a7 100644 (file)
@@ -7,9 +7,9 @@
         tooltip="Import a set of construction points"
         icon="icons/Addons/import.png"
         helpfile="compoundVerticesFeature.html">
-        <file_selector id="file_path" title="Import txt file (X Y Z)" path="">
+        <file_selector id="file_path" title="Import file" tooltip="Select file" path="">
         </file_selector>
-        <stringvalue id="separator"  label="Separator (optional): ">
+        <stringvalue id="separator" label="Separator (optional):" tooltip="Select separator">
         </stringvalue>
       </feature>
     </group>
index 37e0208d7219019bc65ea5d064b2eb1c7c3ece20..6d495416595f109844f76f98c4d16d28f6d5eb5d 100644 (file)
@@ -2,11 +2,11 @@
   <workbench id="Macros" document="Part">
     <group id="Samples">
       <feature id="importParameters"
-        title="List of Parameters"
+        title="Import Parameters"
         tooltip="Import a set of parameters"
         icon="icons/Addons/parameters.png"
         helpfile="importParametersFeature.html">
-        <file_selector id="file_path" title="Import file" path="">
+        <file_selector id="file_path" title="Import file" tooltip="Select file" path="">
         </file_selector>
       </feature>
     </group>
diff --git a/src/PythonAddons/macros/piping/__init__.py b/src/PythonAddons/macros/piping/__init__.py
new file mode 100644 (file)
index 0000000..2614b9c
--- /dev/null
@@ -0,0 +1,19 @@
+# Copyright (C) 2016-2020  CEA/DEN, 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
+#
+
diff --git a/src/PythonAddons/macros/piping/feature.py b/src/PythonAddons/macros/piping/feature.py
new file mode 100644 (file)
index 0000000..5525439
--- /dev/null
@@ -0,0 +1,516 @@
+# Copyright (C) 2016-2020  CEA/DEN, 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
+#
+
+"""piping Feature
+Author: Nathalie Gore
+"""
+
+from salome.shaper import model
+from salome.shaper import geom
+import ModelAPI
+import ParametersAPI
+from GeomAPI import *
+
+class piping(model.Feature):
+    """Import of Construction points
+    """
+
+# Feature initializations
+
+    def __init__(self):
+        """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
+        model.Feature.__init__(self)
+
+    @staticmethod
+    def ID():
+        """Return Id of the Feature."""
+        return "piping"
+
+    @staticmethod
+    def FILE_ID():
+        """Returns ID of the file select parameter."""
+        return "file_path"
+
+    @staticmethod
+    def HEXAS_ID():
+        """Returns ID of the radius parameter."""
+        return "blocking"
+
+    def getKind(self):
+        """Override Feature.getKind()"""
+        return piping.ID()
+
+
+# Initialization of the dialog panel
+
+    def initAttributes(self):
+        """Override Feature.initAttributes()"""
+        # Creating the input argument of the feature
+        self.data().addAttribute(self.FILE_ID(), ModelAPI.ModelAPI_AttributeString_typeId())
+        self.data().addAttribute(self.HEXAS_ID(), ModelAPI.ModelAPI_AttributeBoolean_typeId())
+
+        self.lfeatures = []
+        self.folder = None
+        self.isHexa = False
+        self.twopartwo = "2par2"
+        self.parligne = "par_ligne"
+        self.radius = 0.5
+        #self.paramRadius = None
+        #self.paramFillet = None
+
+# Get existing parameters names
+
+    def existingParameters(self, aDoc):
+        """ Returns list of already existing parameters names"""
+        #aDoc = model.activeDocument()
+        aNbFeatures = aDoc.numInternalFeatures();
+        aNames = []
+        for i in range(aNbFeatures):
+            aParamFeature = aDoc.internalFeature(i);
+            if aParamFeature is not None:
+                if aParamFeature.getKind() == ParametersAPI.ParametersAPI_Parameter.ID():
+                    aNames.append(aParamFeature.name())
+        return aNames
+
+# Retrieve parent pipe
+
+    def decodingCode(self, code):
+        splitCode = code.split(".")
+        if len(splitCode) <= 1:
+           return ""
+        previousCode = code[:len(code)-len(splitCode[-1])-1]
+        return previousCode
+
+
+    def readNodeInfo(self, line):
+        #print(line)
+        splitLine = line.split(" ")
+        if len(splitLine) != 5:
+           print(line) ; return False
+        if splitLine[0] in self.infoPoints:
+           print(line) ; return False
+        if splitLine[1] not in self.infoPoints and splitLine[1] != "-":
+           print(line) ; return False
+        self.infoPoints[splitLine[0]] = {}
+        self.infoPoints[splitLine[0]]["Ref"] = splitLine[1]
+        if splitLine[1] == "-":
+            self.infoPoints[splitLine[0]]["X"] = float(splitLine[2])
+            self.infoPoints[splitLine[0]]["Y"] = float(splitLine[3])
+            self.infoPoints[splitLine[0]]["Z"] = float(splitLine[4])
+        else :
+            self.infoPoints[splitLine[0]]["X"] = self.infoPoints[splitLine[1]]["X"] + float(splitLine[2])
+            self.infoPoints[splitLine[0]]["Y"] = self.infoPoints[splitLine[1]]["Y"] + float(splitLine[3])
+            self.infoPoints[splitLine[0]]["Z"] = self.infoPoints[splitLine[1]]["Z"] + float(splitLine[4])
+        self.infoPoints[splitLine[0]]["isEnd"] = False
+        return True
+
+    def readConnectivity(self, line, method):
+        splitLine = line.split(" ")
+        print(line)
+        if method == self.twopartwo :
+            if self.connectivities == {} :
+               print("nouvelle ligne - Cas 1")
+               self.newConnectivity(splitLine[0], splitLine)
+            else :
+                # Recherche si ligne déjà existante ou si nouvelle ligne
+                print("Lignes existantes")
+                for key, val in self.connectivities.items():
+                    print(key, " ******* ",val)
+                    if val['chainage'][-1] == splitLine[0]:
+                       # La ligne existe
+                       val['chainage'].append(splitLine[1])
+                       return True
+                # La ligne n'existe pas
+                print("nouvelle ligne - Cas 2")
+                self.newConnectivity(splitLine[0], splitLine)
+        else :
+            self.newConnectivity(splitLine[0], splitLine)
+        return True
+
+    def newConnectivity(self, key, value):
+         self.connectivities[key] = {}
+         self.connectivities[key]['chainage'] = value
+
+    def readFillet(self, line):
+        splitLine = line.split(" ")
+        if len(splitLine) != 2:
+           print(line) ; return False
+        if not splitLine[0] in self.infoPoints:
+           print(line) ; return False
+        if splitLine[1] == "angular_connection":
+           self.infoPoints[splitLine[0]]["Fillet"] = "angular_connection"
+           return True
+        elif splitLine[1][:7] == "radius=":
+           self.infoPoints[splitLine[0]]["Fillet"] = "radius"
+           self.infoPoints[splitLine[0]]["Radius"] = float(splitLine[1][7:])
+           return True
+        print(line) ; return False
+
+    def retrieveSubshapesforWire(self, copy, key, ind):
+        exp = GeomAPI_ShapeExplorer(copy.defaultResult().shape(), GeomAPI_Shape.EDGE)
+
+        end = False
+        subshapesForWire = []
+        currentInd = 0
+        isPipe = True
+        print("Current chainage : ", self.connectivities[key]['chainage'][ind:])
+        print("Indice de démarrage = ", ind)
+
+        while exp.more() and not end :
+            print("Analyse Edge n°", currentInd)
+            print(" => ", self.connectivities[key]['chainage'][currentInd], " - ", self.connectivities[key]['chainage'][currentInd+1])
+            print(" ==> ", self.infoPoints[self.connectivities[key]['chainage'][currentInd]]["isAngular"], " - ", self.infoPoints[self.connectivities[key]['chainage'][currentInd+1]]["isAngular"])
+            cur = exp.current().edge()
+            if currentInd < ind:
+                print("Edge non prise en compte")
+                print("test si fillet : ", currentInd+1, ind, self.infoPoints[self.connectivities[key]['chainage'][currentInd+1]]["Fillet"])
+                if currentInd+1 <= ind and self.infoPoints[self.connectivities[key]['chainage'][currentInd+1]]["Fillet"] == "radius" and not self.infoPoints[self.connectivities[key]['chainage'][currentInd]]["isAngular"]:
+                    print("Fillet à ne pas prendre en compte")
+                    exp.next() ; cur = exp.current().edge()
+            else :
+                subshapesForWire.append(model.selection(copy.defaultResult(), cur))
+                print("Mode normal - Nb segments dans le wire : ", len(subshapesForWire))
+                # Cas du fillet : on récupère l'edge suivante
+                if self.infoPoints[self.connectivities[key]['chainage'][currentInd]]["isAngular"] or self.infoPoints[self.connectivities[key]['chainage'][currentInd+1]]["isAngular"]:
+                    end = True
+                    print("Nb segments dans le wire : ", len(subshapesForWire))
+                    if len(subshapesForWire) == 1:
+                        print("Coude droit en cours")
+                        currentInd = currentInd+1
+                        isPipe = False
+                    else :
+                        print("Coude droit à venir")
+                        subshapesForWire = subshapesForWire[:-1]
+                elif self.infoPoints[self.connectivities[key]['chainage'][currentInd]]["Fillet"] == "radius":
+                    print("Ajout edge start Fillet")
+                    exp.next() ; cur = exp.current().edge()
+                    subshapesForWire.append(model.selection(copy.defaultResult(), cur))
+                    #currentInd = currentInd+1
+                    print("Mode Fillet - Nb segments dans le wire : ", len(subshapesForWire))
+                elif self.infoPoints[self.connectivities[key]['chainage'][currentInd+1]]["Fillet"] == "radius":
+                    print("Ajout edge end Fillet")
+                    exp.next() ; cur = exp.current().edge()
+                    subshapesForWire.append(model.selection(copy.defaultResult(), cur))
+                    print("Mode Fillet - Nb segments dans le wire : ", len(subshapesForWire))
+                else :
+                    if self.infoPoints[self.connectivities[key]['chainage'][currentInd+1]]["isEnd"]:
+                        print("Fin detectee")
+                        currentInd = currentInd+1
+                        end = True
+                    else :
+                        print("Branchement")
+            if not end:
+                currentInd = currentInd+1
+            exp.next()
+            print("End = ", end, self.connectivities[key]['chainage'][currentInd])
+
+        return subshapesForWire, currentInd, isPipe, self.connectivities[key]['chainage'][currentInd]
+
+    def retrieveLastElement(self, obj, typeOfElement):
+        exp = GeomAPI_ShapeExplorer(obj.defaultResult().shape(), typeOfElement)
+        while exp.more():
+           if typeOfElement == GeomAPI_Shape.VERTEX :
+                cur = exp.current().vertex(); exp.next()
+           elif typeOfElement == GeomAPI_Shape.EDGE :
+                cur = exp.current().edge(); exp.next()
+           elif typeOfElement == GeomAPI_Shape.FACE :
+                cur = exp.current().face(); exp.next()
+           elif typeOfElement == GeomAPI_Shape.SOLID :
+                cur = exp.current().solid(); exp.next()
+           else :
+                return None
+        return model.selection(obj.defaultResult(), cur)
+
+    def retrieveFirstElement(self, obj, typeOfElement):
+        exp = GeomAPI_ShapeExplorer(obj.defaultResult().shape(), typeOfElement)
+        if typeOfElement == GeomAPI_Shape.VERTEX :
+            cur = exp.current().vertex()
+        elif typeOfElement == GeomAPI_Shape.EDGE :
+            cur = exp.current().edge()
+        elif typeOfElement == GeomAPI_Shape.FACE :
+            cur = exp.current().face()
+        elif typeOfElement == GeomAPI_Shape.SOLID :
+            cur = exp.current().solid()
+        else :
+            return None
+        return model.selection(obj.defaultResult(), cur)
+
+    def createPiping(self, part, connectivityInfos):
+        lPipes = []
+        startFace = None
+        fuse = None
+        for ind in range(len(connectivityInfos['paths'])):
+            print("Step = ", ind)
+            if ind == 0:
+                startFace = connectivityInfos['sketch']
+            if connectivityInfos['isPipe'][ind] :
+                pipe = model.addPipe(part, [startFace], connectivityInfos['paths'][ind].result())
+            else :
+                # recherche du plan
+                if self.infoPoints[connectivityInfos['ends'][ind]]['isAngular']:
+                    pipe = model.addExtrusion(part, [startFace], model.selection(), self.infoPoints[connectivityInfos['ends'][ind]]['plane'], 0, model.selection(), 0, "Faces|Wires")
+                else :
+                    # le plan cible n'existe pas
+                    edge = model.addAxis(part, self.infoPoints[connectivityInfos['starts'][ind]]['point'], self.infoPoints[connectivityInfos['ends'][ind]]['point']); edge.execute(True); self.lfeatures.append(edge)# self.retrieveFirstElement(connectivityInfos['paths'][ind], GeomAPI_Shape.EDGE)
+                    point = self.retrieveLastElement(connectivityInfos['paths'][ind], GeomAPI_Shape.VERTEX)
+                    plane = model.addPlane(part, edge.result(), point, True); plane.execute(True); self.lfeatures.append(plane)
+                    pipe = model.addExtrusion(part, [startFace], edge.result(), plane.result(), 0, model.selection(), 0, "Faces|Wires")
+            pipe.execute(True); self.lfeatures.append(pipe)
+            lPipes.append(pipe.result())
+            if ind < len(connectivityInfos['paths'])-1:
+                copy = model.addCopy(part, [model.selection(pipe.defaultResult())], 1); copy.execute(True); self.lfeatures.append(copy)
+                startFace = self.retrieveLastElement(copy, GeomAPI_Shape.FACE)
+
+        if len(lPipes) > 1 :
+            fuse = model.addFuse(part, lPipes, False); fuse.execute(True); self.lfeatures.append(fuse)
+        else :
+            return pipe
+        return fuse
+
+# Execution of the Import
+
+    def execute(self):
+        """F.execute() -- execute the Feature"""
+        # Retrieving the user input
+        apath    = self.string(self.FILE_ID())
+
+        filepath = apath.value()
+        if filepath != "" :
+            part = model.activeDocument()
+
+            if self.lfeatures :
+                for feature in self.lfeatures:
+                   part.removeFeature(feature.feature())
+                self.lfeatures = []
+                model.removeFolder(self.folder)
+
+            self.infoPoints = {}
+            self.connectivities = {}
+
+            from os.path import basename
+            filename = basename(filepath)
+            nameRes = "piping_" + filename
+
+            # Creating the construction points in the current document
+            lFeatures = []
+            lVertices = []
+            lCodesPipes = []
+            lPipeSupports = {}
+            lPipes = []
+
+            with open(filepath) as file:
+                summary = 0
+                method = ""
+                for line in file:
+                    if line == "\n":
+                        continue                    
+                    if line[0] == "#" or line[:3] == "...":
+                        continue
+                    if summary == 0 and line[:-1] == "nodes section" :
+                        print("========================= Lecture des noeuds =========================")
+                        summary = 1
+                        continue
+                    if summary == 1 and line[:-1] == "connectivity section" :
+                        print("========================= Lecture de la connectivite =========================")
+                        summary = 2
+                        continue
+                    if summary == 2 and line[:6] == "method" :
+                        method = line[7:-1]
+                        print(method)
+                        if method != self.twopartwo and method != self.parligne:
+                            raiseException("Problem with type of connectivity")
+                        continue
+                    if summary == 2 and line[:-1] == "fillets section" :
+                        print("========================= Lecture des fillets =========================")
+                        summary = 3
+                        continue
+
+                    if summary == 1:
+                        isOK = self.readNodeInfo(line[:-1])
+                        if not isOK:
+                            raiseException("Problem with description of nodes")
+                        continue
+                    if summary == 2:
+                        isOK = self.readConnectivity(line[:-1],method)
+                        if not isOK:
+                            raiseException("Problem with description of connectivities")
+                        continue
+                    if summary == 3:
+                        isOK = self.readFillet(line[:-1])
+                        if not isOK:
+                            raiseException("Problem with description of fillets")
+                        continue
+                file.close()
+
+                for key, value in self.connectivities.items():
+                   self.infoPoints[value['chainage'][-1]]["isEnd"] = True
+
+                print("infos points = " , self.infoPoints)
+                print("connectivities = " , self.connectivities)
+
+
+                # Creation des points
+                print("========================= Creation des noeuds =========================")
+                for key, value in self.infoPoints.items():
+                    point = model.addPoint(part, value['X'], value['Y'], value['Z']); point.execute(True); self.lfeatures.append(point)
+                    value["point"] = point.result()
+
+
+                # Creation des polylines
+                print("========================= Creation des polylines =========================")
+                for key, value in self.connectivities.items():
+                    print("key = ", key)
+                    lPoints = []
+                    for id_noeud in value['chainage']:
+                        lPoints.append(self.infoPoints[id_noeud]["point"])
+                    polyline = model.addPolyline3D(part, lPoints, False); polyline.execute(True); self.lfeatures.append(polyline)
+                    value["polyline"] = polyline
+
+
+                # Creation des fillets
+                print("========================= Creation des fillets =========================")
+                for key, value in self.connectivities.items():
+                    print("key = ", key)
+                    # recherche des noeuds fillets
+                    value["fillet"] = value["polyline"]
+                    for id_noeud in value['chainage']:
+                        if self.infoPoints[id_noeud]["Fillet"] == "radius" :
+                            print(self.infoPoints[id_noeud])
+                            fillet1D = model.addFillet(part, [model.selection("VERTEX", (self.infoPoints[id_noeud]["X"],self.infoPoints[id_noeud]["Y"],self.infoPoints[id_noeud]["Z"]))], self.infoPoints[id_noeud]["Radius"]); fillet1D.execute(True); self.lfeatures.append(fillet1D)
+                            value["fillet"] = fillet1D
+
+
+                # Trouver les coudes droits
+                print("========================= Recherche des coudes droits =========================")
+                for key, value in self.connectivities.items():
+                    print("key = ", key, value['chainage'])
+                    # recherche des noeuds fillets
+                    for ind, id_noeud in enumerate(value['chainage']):
+                        #print("Info sur : " id_noeud, " => ", self.infoPoints[id_noeud]["Fillet"])
+                        if ind == 0 or ind == len(value['chainage'])-1 :
+                            self.infoPoints[id_noeud]["isAngular"] = False
+                        else :
+                            if self.infoPoints[id_noeud]["Fillet"] == "radius" :
+                                self.infoPoints[id_noeud]["isAngular"] = False
+                            else :
+                                if id_noeud in self.connectivities:
+                                    self.infoPoints[id_noeud]["isAngular"] = False
+                                else :
+                                    self.infoPoints[id_noeud]["isAngular"] = True
+                                    print("========================= Création du plan =========================")
+                                    # Axe d'extrusion
+                                    print(ind-1, ind, ind+1)
+                                    print(value["chainage"][ind-1], id_noeud, value["chainage"][ind+1])
+                                    print(self.infoPoints[value["chainage"][ind-1]]["point"])
+
+                                    tmpPlane = model.addPlane(part, self.infoPoints[value["chainage"][ind-1]]["point"], self.infoPoints[id_noeud]["point"], self.infoPoints[value["chainage"][ind+1]]["point"]); tmpPlane.execute(True); self.lfeatures.append(tmpPlane)
+                                    axis =  model.addAxis(part, tmpPlane.result(), self.infoPoints[id_noeud]["point"]); axis.execute(True); self.lfeatures.append(axis)
+                                    self.infoPoints[id_noeud]["axis"] = axis.result()
+
+                                    # Edge a extruder
+                                    tmpEdge = model.addEdge(part, self.infoPoints[id_noeud]["point"], self.infoPoints[value["chainage"][ind+1]]["point"]); tmpEdge.execute(True); self.lfeatures.append(tmpEdge)
+                                    length = model.measureDistance(part, self.infoPoints[value["chainage"][ind-1]]["point"], self.infoPoints[id_noeud]["point"])
+                                    point =  model.addPoint(part, tmpEdge.result(), length, False, False); point.execute(True); self.lfeatures.append(point)
+                                    baseEdge = model.addEdge(part, self.infoPoints[value["chainage"][ind-1]]["point"], point.result()); baseEdge.execute(True); self.lfeatures.append(baseEdge)
+                                    middlePoint = model.addPoint(part, baseEdge.result(), 0.5, True, False); middlePoint.execute(True); self.lfeatures.append(middlePoint)
+                                    Edge = model.addEdge(part, self.infoPoints[id_noeud]["point"], middlePoint.result()); Edge.execute(True); self.lfeatures.append(Edge)
+
+                                    # Extrusion
+                                    plane = model.addExtrusion(part, [Edge.result()], axis.result(), 10, 0); plane.execute(True); self.lfeatures.append(plane)
+                                    self.infoPoints[id_noeud]["plane"] = plane.result()
+
+
+                # Création des paths pour le piping
+                print("========================= Création des paths =========================")
+                for key, value in self.connectivities.items():
+                    print("================================================================================= key = ", key, value['chainage'], value['fillet'])
+                    # recherche des noeuds fillets
+                    value["paths"] = []
+                    value["isPipe"] = []
+                    value["starts"] = []
+                    value["ends"] = []
+                    ind = 0
+                    copy = value['fillet']
+                    while ind < len(value['chainage'])-1:
+                        value["starts"].append(self.connectivities[key]['chainage'][ind])
+                        objectsForPath, ind, isPipe, end_noeud = self.retrieveSubshapesforWire(copy, key, ind)                     
+                        print("************************* ind = ", ind)
+                        print("************************* objectsForPath = ", objectsForPath)
+                        path = model.addWire(part, objectsForPath, False); path.execute(True); self.lfeatures.append(path)
+                        value["paths"].append(path)
+                        value["isPipe"].append(isPipe)
+                        value["ends"].append(end_noeud)
+                        if ind < len(value['chainage'])-1:
+                           copy = model.addCopy(part, [model.selection(copy.defaultResult())], 1); copy.execute(True); self.lfeatures.append(copy)                           
+            
+
+                # Création des sketchs pour le piping
+                print("========================= Création des sketchs =========================")
+                for key, value in self.connectivities.items():
+                    print("================================================================================= key = ", key)
+                    # Creating sketch
+                    edge = model.addEdge(part, self.infoPoints[value["chainage"][0]]["point"], self.infoPoints[value["chainage"][1]]["point"]); edge.execute(True); self.lfeatures.append(edge)
+                    plane = model.addPlane(part, edge.result(), self.infoPoints[value["chainage"][0]]["point"], True); plane.execute(True); self.lfeatures.append(plane)
+                    sketch = model.addSketch(part, plane.result()); sketch.execute(True); self.lfeatures.append(sketch)
+                    SketchProjection = sketch.addProjection(self.infoPoints[value["chainage"][0]]["point"], False); SketchProjection.execute(True)
+                    SketchPoint = SketchProjection.createdFeature(); SketchPoint.execute(True)
+                    SketchCircle = sketch.addCircle(0,0,self.radius); SketchCircle.execute(True)
+                    sketch.setCoincident(SketchPoint.result(), SketchCircle.center())
+                    sketch.setRadius(SketchCircle.results()[1], self.radius)
+                    sketch.execute(True)
+                    model.do()
+                    value["sketch"] = sketch.result()
+
+
+                print("infos points = " , self.infoPoints)
+                print("********************************")
+                print("connectivities = " , self.connectivities)
+
+
+                # Création des pipes
+                print("========================= Création des pipes =========================")
+                for key, value in self.connectivities.items():
+                    print("================================================================================= key = ", key)
+                    pipe = self.createPiping(part, value)
+                    value["pipe"] = pipe.result()
+
+
+                # Fusion des pipes
+                print("========================= Fusion des pipes =========================")
+                lPipes = []
+                for key, value in self.connectivities.items():
+                    lPipes.append(value["pipe"])
+                fuse = model.addFuse(part, lPipes, False)
+                fuse.execute(True); self.lfeatures.append(fuse)
+                fuse.result().setName(nameRes)
+                self.folder = model.addFolder(part, self.lfeatures[0], self.lfeatures[-1])
+                self.folder.setName(nameRes)
+
+                return
+
+            raiseException("The file does not exist")
+
+    def isMacro(self):
+        """Override Feature.initAttributes().
+        F.isMacro() -> True
+
+        piping feature is macro: removes itself on the creation transaction
+        finish.
+        """
+        return False
diff --git a/src/PythonAddons/macros/piping/icons/piping.png b/src/PythonAddons/macros/piping/icons/piping.png
new file mode 100644 (file)
index 0000000..7b265be
Binary files /dev/null and b/src/PythonAddons/macros/piping/icons/piping.png differ
diff --git a/src/PythonAddons/macros/piping/piping.txt b/src/PythonAddons/macros/piping/piping.txt
new file mode 100644 (file)
index 0000000..b569485
--- /dev/null
@@ -0,0 +1,10 @@
+21 16 224.00000000000003 1
+33 21 224.00000000000003 1
+35 0 224.00000000000003 1.1
+40 43 224.00000000000003 1
+53 43 224.00000000000003 1.2
+69 29 224.00000000000003 1
+97 58 224.00000000000003 1
+64 100 224.00000000000003 1.2
+100 127 224.00000000000003 1
+88 115 224.00000000000003 1.2
diff --git a/src/PythonAddons/macros/piping/piping2.txt b/src/PythonAddons/macros/piping/piping2.txt
new file mode 100644 (file)
index 0000000..b569485
--- /dev/null
@@ -0,0 +1,10 @@
+21 16 224.00000000000003 1
+33 21 224.00000000000003 1
+35 0 224.00000000000003 1.1
+40 43 224.00000000000003 1
+53 43 224.00000000000003 1.2
+69 29 224.00000000000003 1
+97 58 224.00000000000003 1
+64 100 224.00000000000003 1.2
+100 127 224.00000000000003 1
+88 115 224.00000000000003 1.2
diff --git a/src/PythonAddons/macros/piping/widget.xml b/src/PythonAddons/macros/piping/widget.xml
new file mode 100644 (file)
index 0000000..8f84a8a
--- /dev/null
@@ -0,0 +1,16 @@
+<source>
+  <workbench id="Macros" document="Part">
+    <group id="Samples">
+      <feature
+        id="piping"
+        title="Piping"
+        tooltip="Import a set of pipes"
+        icon="icons/Addons/piping.png"
+        helpfile="pipingFeature.html">
+        <file_selector id="file_path" title="Import txt file (pipe)" path="">
+        </file_selector>
+        <boolvalue id="blocking" label="for hexa meshes" default="false" tooltip="To partition CAD for hexa meshes" obligatory="0"/>
+      </feature>
+    </group>
+  </workbench>
+</source>
index a71c233376167b1a215b8cb37e15261b4afdea32..051a027f597b15b757296cd32454bfb7fbbfb1c7 100644 (file)
@@ -22,4 +22,5 @@ SET(TEST_NAMES
   TestRectangleCentered.py
   TestcompoundVertices.py
   TestimportParameters.py
+  Testpiping.py
 )