ADD_SUBDIRECTORY (src/SketcherPrs)
ADD_SUBDIRECTORY (src/SketchPlugin)
ADD_SUBDIRECTORY (src/SketchSolver)
+ADD_SUBDIRECTORY (src/SAMPlugin)
ADD_SUBDIRECTORY (src/ModuleBase)
ADD_SUBDIRECTORY (src/PartSet)
ParametersPlugin
PythonAddons
SketchAPI
+ SAMPlugin
ConstructionAPI
PartSetAPI
GeomDataAPI
<plugin library="SketchPlugin" configuration="plugin-SketchCopy.xml"/>
<plugin script="ConnectorPlugin" configuration="plugin-Connector.xml" dependency="GEOM"/>
<plugin library="ParametersPlugin" configuration="plugin-Parameters.xml"/>
+ <plugin script="SAMPlugin" configuration="plugin-SAM.xml"/>
+ <!--<plugin script="SAMPlugin" configuration="plugin-SAM.xml" dependency="SAM"/>-->
@DEFAULT_SOLVER@
<!--
@ALL_SOLVERS@
--- /dev/null
+# Copyright (C) 2014-2022 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
+#
+
+INCLUDE(Common)
+INCLUDE(UnitTest)
+
+SET(PYTHON_FILES
+ SAMPlugin.py
+ SAMPlugin_SuggestConstraintsFeature.py
+ SAMPlugin_ConvertSketch.py
+ SAMPlugin_ConvertPrimitives.py
+ SAMPlugin_ConvertConstraints.py
+)
+
+SET(XML_RESOURCES
+ plugin-SAM.xml
+)
+
+SET(TEXT_RESOURCES
+ SAMPlugin_msg_fr.ts
+)
+
+SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES})
+
+ADD_CUSTOM_TARGET(SAMPlugin SOURCES ${PYTHON_FILES} ${XML_RESOURCES} ${TEXT_RESOURCES})
+
+INSTALL(FILES ${PYTHON_FILES} DESTINATION ${SHAPER_INSTALL_PYTHON_FILES})
+INSTALL(FILES ${XML_RESOURCES} ${TEXT_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES})
+INSTALL(DIRECTORY icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Connector)
+
+ADD_SUBDIRECTORY(Test)
--- /dev/null
+# Copyright (C) 2014-2022 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
+#
+
+## @package Plugins
+# Python plugin for exporting entities into Salome's GEOM module
+
+import ModelAPI
+
+from SAMPlugin_SuggestConstraintsFeature import SuggestConstraintsFeature
+
+## @ingroup Plugins
+# The main class for management the construction features as plugin.
+class SAMPlugin(ModelAPI.ModelAPI_Plugin):
+
+ ## The constructor.
+ def __init__(self):
+ ModelAPI.ModelAPI_Plugin.__init__(self)
+ pass
+
+ ## Creates the feature objects of this plugin by the feature string ID.
+ def createFeature(self, theFeatureID):
+ if theFeatureID == SuggestConstraintsFeature.ID():
+ return SuggestConstraintsFeature().__disown__()
+ #elif theFeatureID == PublishToStudyFeature.ID():
+ # return PublishToStudyFeature().__disown__()
+ else:
+ print("SAMPlugin: No such feature %s" % theFeatureID)
+
+## The plugin created on module importing (from c++)
+isSHAPER_SUGGESTION_GENERATOR = True
+#TODO
+if isSHAPER_SUGGESTION_GENERATOR:
+ plugin = SAMPlugin()
+ ## Main session of the application
+ aSession = ModelAPI.ModelAPI_Session.get()
+ aSession.registerPlugin(plugin)
+ pass
--- /dev/null
+from sam.catalog_constraint import *
+
+import math
+
+from SketchAPI import *
+from shapervssam.utils.logger import logger
+
+
+def get_params_value(entity):
+ try :
+ value_attr = entity.feature().real("ConstraintValue")
+ if value_attr is not None:
+ return value_attr.value()
+ except Exception as e :
+ logger.info(f'Problem with constraint parameters: {e}')
+ return None
+
+class ShapertoSAMConstraints:
+
+ def convert(entity, refs):
+
+ if entity.getKind() == 'SketchConstraintAngle':
+ return Angle(references = refs, angle = get_params_value(entity))
+
+ if entity.getKind() == 'SketchConstraintCoincidence':
+ return Coincident(references = refs)
+
+ if entity.getKind() == 'SketchConstraintDistance':
+ return Distance(references = refs, distance_min = get_params_value(entity))
+
+ if entity.getKind() == 'SketchConstraintDistanceHorizontal':
+ return HorizontalDistance(references = refs, distance_min = get_params_value(entity))
+
+ if entity.getKind() == 'SketchConstraintDistanceVertical':
+ return VerticalDistance(references = refs, distance_min = get_params_value(entity))
+
+ if entity.getKind() == 'SketchConstraintEqual':
+ return Equal(references = refs)
+
+ if entity.getKind() == 'SketchConstraintHorizontal':
+ return Horizontal(references = refs)
+
+ if entity.getKind() == 'SketchConstraintMiddle' :
+ return Midpoint(references = refs)
+
+ if entity.getKind() == 'SketchConstraintParallel' :
+ return Parallel(references = refs)
+
+ if entity.getKind() == 'SketchConstraintPerpendicular' :
+ return Perpendicular(references = refs)
+
+ if entity.getKind() == 'SketchConstraintTangent' :
+ return Tangent(references = refs)
+
+ if entity.getKind() == 'SketchConstraintVertical':
+ return Vertical(references = refs)
+
+
+ if entity.getKind() == 'SketchConstraintRadius':
+
+ return Radius(references = refs, radius = get_params_value(entity))
+
+
+ if entity.getKind() == 'SketchConstraintLength':
+ return Length(references = refs, length = get_params_value(entity))
+
+
+ return None
+
+
+
+
\ No newline at end of file
--- /dev/null
+from sam.catalog_primitive import Arc, Line, Circle, Point
+
+import math
+
+from SketchAPI import *
+from GeomAPI import *
+from shapervssam.utils.logger import logger
+
+def convert_angle(angle):
+ a = int(angle / 360)
+ if math.fabs(angle) >= 360. :
+ return angle - a * 360
+ else :
+ return angle
+
+class ShapertoSAMPrimitive:
+
+ def convert(entity):
+
+ if entity.getKind() == 'SketchPoint':
+ return ShapertoSAMPrimitive.convert_point(entity)
+ if entity.getKind() == 'SketchArc':
+ return ShapertoSAMPrimitive.convert_arc(entity)
+ if entity.getKind() == 'SketchCircle':
+ return ShapertoSAMPrimitive.convert_circle(entity)
+ if entity.getKind() == 'SketchLine':
+ return ShapertoSAMPrimitive.convert_line(entity)
+ return None, {}
+
+ def check_construction(entity):
+ auxAttr = entity.auxiliary()
+ return auxAttr is not None and auxAttr.value()
+
+ def convert_point(entity):
+ feat = SketchAPI_Point(entity)
+ p1 = feat.coordinates()
+ return Point(status_construction= ShapertoSAMPrimitive.check_construction(entity), point = [p1.x(), p1.y()]), {}
+
+ def convert_line(entity):
+ feat = SketchAPI_Line(entity)
+
+ p1 = feat.startPoint()
+ p2 = feat.endPoint()
+ line = Line(status_construction=ShapertoSAMPrimitive.check_construction(entity), pnt1= [p1.x(), p1.y()], pnt2= [p2.x(), p2.y()])
+ return line, {(p1.x(), p1.y(), feat.name()) : line.pnt1, (p2.x(), p2.y(), feat.name()) : line.pnt2}
+
+ def convert_circle(entity):
+ feat = SketchAPI_Circle(entity)
+ c = feat.center()
+ radius = feat.radius()
+
+ circle = Circle(status_construction=ShapertoSAMPrimitive.check_construction(entity),
+ center = [c.x(), c.y()],
+ radius= radius.value())#feat.radius().value())
+ return circle, {(c.x(), c.y(), feat.name()) : circle.center}
+
+ def convert_arc(entity):
+ status = ShapertoSAMPrimitive.check_construction(entity)
+ feat = SketchAPI_Arc(entity)
+ c = feat.center()
+ s = entity.defaultResult()
+ edge = GeomAPI_Edge(s.shape())
+ a0,a1 = edge.getRange()
+ start_angle = convert_angle(math.degrees(a0))
+ end_angle = convert_angle(math.degrees(a1))
+
+ arc = Arc(status_construction=status,
+ center = [c.x(), c.y()],
+ radius= feat.radius().value(),
+ angles= [start_angle, end_angle])
+ arc.add_points_startend()
+ return arc, {(c.x(), c.y(), feat.name()) : arc.center}
--- /dev/null
+from shapervssam.utils.logger import logger
+
+from shapervssam.shaper_to_sam.convert_primitive import ShapertoSAMPrimitive
+from shapervssam.shaper_to_sam.convert_constraints import ShapertoSAMConstraints
+from sam.sketch import Sketch
+
+from ModelAPI import *
+from SketchAPI import *
+from GeomDataAPI import *
+
+
+def convert_sketch(sketch: object): # a shaper sketch
+
+ exchange_sketch = Sketch()
+
+ mapping = {}
+ # Add the primitives
+ for sub in sketch.features().list():
+ feat = ModelAPI.objectToFeature(sub)
+
+ if feat is not None :
+ entity = SketchAPI_SketchEntity(feat)
+ entity_type = entity.getKind()
+
+ convert, update_mapping = ShapertoSAMPrimitive.convert(entity)
+ if convert is not None:
+ mapping[entity.name()] = convert
+
+ mapping.update(update_mapping)
+
+ if convert is not None:
+ exchange_sketch.add(convert)
+
+ logger.debug(f'Mapping; {mapping}')
+
+ # Add the constraints
+ sketchFeature = featureToCompositeFeature(sketch.feature())
+ n = sketchFeature.numberOfSubs()
+ for i in range(n):
+ entity = sketchFeature.subFeature(i)
+ entity_type = entity.getKind()
+
+ if 'Constraint' in entity_type :
+ refs = []
+ l_attributs = [entity.refattr("ConstraintEntityA"), entity.refattr("ConstraintEntityB"),
+ entity.refattr("ConstraintEntityC"), entity.refattr("ConstraintEntityD")]
+ for ref in l_attributs:
+ if ref is None: continue
+ if ref.isObject():
+ attr = ModelAPI_Feature.feature(ref.object())
+ refs.append(mapping[attr.name()])
+
+ else :
+ attr = ref.attr()
+ owner = objectToFeature(attr.owner())
+ elt = geomDataAPI_Point2D(attr).pnt()
+ refs.append(mapping.get((elt.x(), elt.y(), owner.name()), owner.name()))
+
+ convert = ShapertoSAMConstraints.convert(entity, refs)
+ exchange_sketch.add(convert)
+
+ return exchange_sketch
+
+
--- /dev/null
+# Copyright (C) 2014-2022 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
+#
+
+## @package Plugins
+# SuggestConstraintsFeature class definition
+
+import ModelAPI
+#import ExchangeAPI
+import EventsAPI
+
+import salome
+
+from salome.shaper import model
+
+import os
+
+## @ingroup Plugins
+# Feature to suggest constraints using a Machine Learning model
+class SuggestConstraintsFeature(model.Feature):
+#class SuggestConstraintsFeature(ModelAPI.ModelAPI_Feature):
+
+ ## The constructor.
+ def __init__(self):
+ #ModelAPI.ModelAPI_Feature.__init__(self)
+ model.Feature.__init__(self)
+ pass
+
+ @staticmethod
+ ## Export kind. Static.
+ def ID():
+ return "SuggestConstraints"
+
+ ## Returns the kind of a feature.
+ def getKind(self):
+ return SuggestConstraintsFeature.ID()
+
+ ## True: This feature is action: has no property panel and executes immediately.
+ ## False: Otherwise.
+ def isAction(self):
+ return False
+ #TODO
+ #return True
+
+ def isMacro(self):
+ """
+ Override Feature.isMacro().
+ Rectangle feature is macro: removes itself on the creation transaction finish.
+ """
+ return True
+
+ ## Init attributes
+ def initAttributes(self):
+ #TODO
+ pass
+
+ ## Export the results, groups and fields via XAO
+ def convertToSAM(self):
+ # if part-set is active, iterate also parts
+ #for isPart in (True, False):
+ print("SuggestConstraintsFeature: convertToSAM")
+ #TODO
+ pass
+
+ ## Exports all shapes and groups into the GEOM module.
+ def execute(self):
+ #aSession = ModelAPI.ModelAPI_Session.get()
+ ## Get active document
+ #self.Part = aSession.activeDocument()
+
+ print("SuggestConstraintsFeature: execute")
+ self.convertToSAM()
+ # TODO: Lot3 and Lot4
+
+ pass
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+ <context>
+ <name>SketchToSAMConverter</name>
+ <message>
+ <source>Impossible to apply the suggested constraints. The primitives %1 and constraints %2 are not currently considered by the model.</source>
+ <translation>Impossible d'appliquer la suggestion de contraintes. Les primitives %1 et contraintes %2 ne sont pour le moment pas prises en compte par le modele.</translation>
+ </message>
+ </context>
+</TS>
--- /dev/null
+# Copyright (C) 2021-2022 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
+#
+
+include(tests.set)
+
+ADD_UNIT_TESTS(${TEST_NAMES})
+
+if(${HAVE_SALOME})
+ enable_testing()
+ set(TEST_INSTALL_DIRECTORY "${SALOME_SHAPER_INSTALL_TESTS}/SAMPlugin")
+
+ install(FILES CTestTestfileInstall.cmake
+ DESTINATION ${TEST_INSTALL_DIRECTORY}
+ RENAME CTestTestfile.cmake)
+ install(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY})
+
+ set(TMP_TESTS_NAMES)
+ foreach(tfile ${TEST_NAMES})
+ list(APPEND TMP_TESTS_NAMES "${tfile}")
+ endforeach(tfile ${TEST_NAMES})
+
+ # tests which require SHAPER_SUGGESTION_GENERATOR
+ install(DIRECTORY data DESTINATION ${TEST_INSTALL_DIRECTORY})
+
+ install(FILES ${TMP_TESTS_NAMES} DESTINATION ${TEST_INSTALL_DIRECTORY})
+endif(${HAVE_SALOME})
--- /dev/null
+# Copyright (C) 2021-2022 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
+#
+
+include(tests.set)
+
+foreach(tfile ${TEST_NAMES})
+ set(TEST_NAME ${COMPONENT_NAME}_${tfile})
+ add_test(${TEST_NAME} python ${tfile})
+ set_tests_properties(${TEST_NAME} PROPERTIES LABELS "${SALOME_TEST_LABEL_ADV}")
+endforeach()
--- /dev/null
+# Copyright (C) 2021-2022 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
+#
+
+SET(TEST_NAMES
+ TestSAMPlugin_Primitives.py
+ TestSAMPlugin_Constraints.py
+ TestSAMPlugin_Sketch.py
+)
--- /dev/null
+
+.. _sAMPlugin:
+
+SAM plug-in
+================
+
+SAM plug-in implements features for Sketch conversion to SAM format and to call Suggest Constraints macro.
+It provides the following features:
+
+.. toctree::
+ :titlesonly:
+ :maxdepth: 1
+
+ suggestConstraintsFeature.rst
--- /dev/null
+<plugin>
+ <workbench id="Sketch">
+ <group id="Automatic constraints">
+ <feature
+ id="SuggestConstraints"
+ title="Suggest constraints"
+ tooltip="Suggest constraints using a Machine Learning model"
+ icon="icons/SAM/suggest_constraints.png"
+ helpfile="SAMPlugin/SAMPlugin.html"/>
+ </group>
+ </workbench>
+</plugin>
SketchConstraintMirror SketchConstraintAngle
SketchMultiRotation SketchMultiTranslation
SketchOffset
- SketchConstraintCollinear SketchConstraintMiddle"
+ SketchConstraintCollinear SketchConstraintMiddle SuggestConstraints"
when_nested="accept abort"
title="Sketch"
tooltip="Create sketch"