SET(CMAKE_AUTOMOC ON)
-INSTALL(DIRECTORY extension geom modeler DESTINATION PythonAPI)
+INSTALL(DIRECTORY extension geom model DESTINATION PythonAPI)
# --------- Unit tests -----------
INCLUDE(UnitTest)
ADD_UNIT_TESTS(
- TestModeler.py
+ TestModel.py
TestSketcherAddPoint.py
TestSketcherAddLine.py
TestSketcherAddArc.py
# Author: Daniel Brunier-Coulin
# -----------------------------
-import modeler
+import model
# Initialisation
-modeler.begin()
-mypartset = modeler.moduleDocument()
+model.begin()
+mypartset = model.moduleDocument()
# Creating a new Part
-mypart = modeler.addPart(mypartset).document()
+mypart = model.addPart(mypartset).document()
# Creating the base of the box
-mybase = modeler.addSketch( mypart, modeler.defaultPlane("XOY") )
+mybase = model.addSketch( mypart, model.defaultPlane("XOY") )
l1 = mybase.addLine( 0, 0, 0, 1 )
l2 = mybase.addLine( 0, 1, 1, 1 )
# Creating the extrusion
-mybox = modeler.addExtrusion( mypart, mybase.selectFace(), 50 )
+mybox = model.addExtrusion( mypart, mybase.selectFace(), 50 )
# Creating a cylinder on a face of the box
thiszmin = "Sketch_1/Edge5_1"
thiszmax = "Extrusion_1/LateralFace_2|Extrusion_1/TopFace_1"
-mystand = modeler.addSketch( mypart, thisface )
+mystand = model.addSketch( mypart, thisface )
c1 = mystand.addCircle( 0, 25, 5)
mystand.setDistance( c1.centerData(), thisxmin, 10 )
mystand.setDistance( c1.centerData(), thiszmax, 10 )
-myboss = modeler.addExtrusion( mypart, mystand.selectFace(c1.result()), -5 )
+myboss = model.addExtrusion( mypart, mystand.selectFace(c1.result()), -5 )
# Subtracting the cylinder to the box
-modeler.addSubtraction( mypart, mybox.result(), myboss.result() )
-modeler.end()
+model.addSubtraction( mypart, mybox.result(), myboss.result() )
+model.end()
# Editing the box
-modeler.begin()
+model.begin()
mybase.setValue( mylength, 100 )
mybox.setSize( 80 )
-modeler.end()
+model.end()
# Author: Daniel Brunier-Coulin
# -----------------------------
-import modeler
+import model
import geom
# Initialisation
-modeler.begin()
-mypartset = modeler.moduleDocument()
+model.begin()
+mypartset = model.moduleDocument()
# Creating a new Part
-mypart = modeler.addPart(mypartset).document()
+mypart = model.addPart(mypartset).document()
# Creating the base of the box
-mybase = modeler.addSketch( mypart, modeler.defaultPlane("XOY") )
+mybase = model.addSketch( mypart, model.defaultPlane("XOY") )
p1 = geom.Pnt2d( 0, 0 )
p2 = geom.Pnt2d( 0, 1 )
# Creating the extrusion
-mybox = modeler.addExtrusion( mypart, mybase.selectFace(), 50 )
+mybox = model.addExtrusion( mypart, mybase.selectFace(), 50 )
# Creating a cylinder on a face of the box
thisxmin = "Extrusion_1/LateralFace_3|Extrusion_1/LateralFace_2"
thiszmax = "Extrusion_1/LateralFace_2|Extrusion_1/TopFace_1"
-mystand = modeler.addSketch( mypart, thisface )
+mystand = model.addSketch( mypart, thisface )
circle = mystand.addCircle( 0, 25, 5)
mystand.setDistance( circle.centerData(), thisxmin, 10 )
mystand.setDistance( circle.centerData(), thiszmax, 10 )
-myboss = modeler.addExtrusion( mypart, mystand.selectFace(), -5 )
+myboss = model.addExtrusion( mypart, mystand.selectFace(), -5 )
# Subtracting the cylinder to the box
-modeler.addSubtraction( mypart, mybox.result(), myboss.result() )
-modeler.end()
+model.addSubtraction( mypart, mybox.result(), myboss.result() )
+model.end()
# Editing the box
-modeler.begin()
+model.begin()
mybase.setValue( mylength, 100 )
mybox.setSize( 20 )
-modeler.end()
+model.end()
# Author: Daniel Brunier-Coulin
# -----------------------------
-import modeler
+import model
import extension
# Initialisation
-modeler.begin()
-mypartset = modeler.moduleDocument()
+model.begin()
+mypartset = model.moduleDocument()
# Creating a new Part
-mypart = modeler.addPart(mypartset).document()
+mypart = model.addPart(mypartset).document()
# Creating the base of the box
extension.addBox( mypart, 10, 20, 30 )
-modeler.end()
+model.end()
import unittest
-import modeler
+import model
-class ModelerTestCase(unittest.TestCase):
+class ModelTestCase(unittest.TestCase):
def setUp(self):
- modeler.begin()
- partset = modeler.moduleDocument()
- self.part = modeler.addPart(partset).document()
+ model.begin()
+ partset = model.moduleDocument()
+ self.part = model.addPart(partset).document()
def tearDown(self):
- modeler.end()
+ model.end()
def test_add_sketch(self):
- plane = modeler.defaultPlane("XOY")
- modeler.addSketch(self.part, plane)
+ plane = model.defaultPlane("XOY")
+ model.addSketch(self.part, plane)
if __name__ == "__main__":
unittest.main()
import unittest
-import modeler
+import model
class SketcherTestCase(unittest.TestCase):
def setUp(self):
- modeler.begin()
- partset = modeler.moduleDocument()
- part = modeler.addPart(partset).document()
- plane = modeler.defaultPlane("XOY")
- self.sketch = modeler.addSketch(part, plane)
+ model.begin()
+ partset = model.moduleDocument()
+ part = model.addPart(partset).document()
+ plane = model.defaultPlane("XOY")
+ self.sketch = model.addSketch(part, plane)
def tearDown(self):
- modeler.end()
+ model.end()
import unittest
-import modeler
+import model
import geom
-from modeler import WrongNumberOfArguments
+from model import WrongNumberOfArguments
from TestSketcher import SketcherTestCase
import unittest
-import modeler
+import model
from TestSketcher import SketcherTestCase
class SketcherAddCircle(SketcherTestCase):
import unittest
-import modeler
+import model
from TestSketcher import SketcherTestCase
class SketcherAddLine(SketcherTestCase):
import unittest
-import modeler
+import model
from TestSketcher import SketcherTestCase
class SketcherAddPoint(SketcherTestCase):
import unittest
-import modeler
+import model
from TestSketcher import SketcherTestCase
class SketcherSetCoincident(SketcherTestCase):
import unittest
-import modeler
+import model
from TestSketcher import SketcherTestCase
class SketcherSetParallel(SketcherTestCase):
Copyright (C) 2014-20xx CEA/DEN, EDF R&D
"""
-import modeler
+import model
from macros.box.feature import BoxFeature as MY
-class Box(modeler.Interface):
+class Box(model.Interface):
"""Executes the macro-feature Box.
"""
def __init__(self, part, dx, dy, dz):
- modeler.Interface.__init__(self, part, MY.ID())
+ model.Interface.__init__(self, part, MY.ID())
self.setRealInput( MY.WIDTH_ID(), dx )
self.setRealInput( MY.LENGTH_ID(), dy )
--- /dev/null
+"""This package defines the Parametric Geometry API of the Modeler.
+"""
+
+# General purpose functions and abstract root classes
+
+from services import *
+from roots import *
+
+# Built-in features
+
+from part import Part as addPart
+from sketcher.sketch import addSketch
+from extrusion import Extrusion as addExtrusion
+from boolean import Addition as addAddition
+from boolean import Subtraction as addSubtraction
+from boolean import Intersection as addIntersection
+
+# Custom exceptions
+
+from errors import WrongNumberOfArguments
\ No newline at end of file
--- /dev/null
+"""Boolean operations Interface
+Author: Daniel Brunier-Coulin
+Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+"""
+
+from ModelAPI import *
+from GeomAlgoAPI import *
+
+
+class Boolean():
+ """Abstract root class of Boolean Features."""
+ def __init__(self, part, object, tool, type):
+ self.my = part.addFeature("Boolean")
+ self.my.data().reference("main_object").setValue(object)
+ self.my.data().reference("tool_object").setValue(tool)
+ self.my.data().integer("bool_type").setValue(type)
+
+ if ModelAPI_Session.get().validators().validate(self.my):
+ self.my.execute()
+ else:
+ raise Exception("cannot make the Boolean")
+
+
+class Addition(Boolean):
+
+ def __init__(self, part, object, tool):
+ """Inserts an addition to the given Part and executes the operation.
+ This operation adds tool to the given object.
+ """
+ Boolean.__init__(self, part, object, tool, GeomAlgoAPI_Boolean.BOOL_FUSE)
+
+
+class Subtraction(Boolean):
+
+ def __init__(self, part, object, tool):
+ """Inserts a subtraction to the given Part and executes the operation.
+ This operation subtracts tool to the given object.
+ """
+ Boolean.__init__(self, part, object, tool, GeomAlgoAPI_Boolean.BOOL_CUT)
+
+
+class Intersection(Boolean):
+
+ def __init__(self, part, object, tool):
+ """Inserts an intersection to the given Part and executes the operation.
+ This operation intersects tool to the given object.
+ """
+ Boolean.__init__(self, part, object, tool, GeomAlgoAPI_Boolean.BOOL_COMMON)
\ No newline at end of file
--- /dev/null
+# Package exceptions
+
+class ModelError(Exception):
+ """Base class for exceptions in this package."""
+ pass
+
+class WrongNumberOfArguments(ModelError):
+ """Exception raised when a wrong number of arguments is given."""
+ pass
+
+ #Attributes:
+ #expr -- input expression in which the error occurred
+ #msg -- explanation of the error
+ #"""
+
+ #def __init__(self, expr, msg):
+ #self.expr = expr
+ #self.msg = msg
--- /dev/null
+"""Extrusion Interface
+Author: Daniel Brunier-Coulin with contribution by Mikhail Ponikarov
+Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+"""
+
+from ModelAPI import *
+
+
+class Extrusion():
+
+ def __init__ (self, part, sketch, size):
+ """Inserts an extrusion of the given Sketch to the given Part and executes the operation."""
+ self.my = part.addFeature("Extrusion")
+ self.my.string("CreationMethod").setValue("BySizes")
+ self.my.data().selectionList("base").append(sketch.result(), sketch.buildShape())
+ if size < 0:
+ self.my.data().real("from_size").setValue(-size)
+ self.my.data().real("to_size").setValue(0)
+ else:
+ self.my.data().real("to_size").setValue(size)
+ self.my.data().real("from_size").setValue(0)
+
+
+ if ModelAPI_Session.get().validators().validate(self.my):
+ self.my.execute()
+ else:
+ raise Exception("cannot make the Extrusion")
+
+
+ def setSize (self, size):
+ """Modifies the size of this extrusion according to the given size."""
+ if size < 0:
+ self.my.data().real("from_size").setValue(-size)
+ self.my.data().real("to_size").setValue(0)
+ else:
+ self.my.data().real("to_size").setValue(size)
+ self.my.data().real("from_size").setValue(0)
+
+ self.my.execute()
+
+ def result (self):
+ """Returns the result data of this Feature."""
+ return self.my.firstResult()
--- /dev/null
+"""Part Feature Interface
+Author: Daniel Brunier-Coulin
+Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+"""
+
+import model # Required by the temporary implementation of result member function
+
+
+class Part():
+
+ def __init__ (self, partset):
+ """Adds a new Part to the given Partset and activates the Part."""
+ self.my = partset.addFeature("Part")
+ self.my.execute()
+
+ def document (self):
+ """Returns the Part document created by this feature."""
+ #TODO: Get the document referenced by this feature
+ return model.activeDocument()
\ No newline at end of file
--- /dev/null
+"""Abstract root classes of user-defined Python features producing a Body
+Author: Daniel Brunier-Coulin
+Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+"""
+
+from ModelAPI import *
+
+
+class Feature(ModelAPI_Feature):
+ """Base class of user-defined Python features."""
+
+ def __init__(self):
+ ModelAPI_Feature.__init__(self)
+
+ def addRealInput (self, inputid):
+ self.data().addAttribute(inputid, ModelAPI_AttributeDouble_typeId())
+
+ def getRealInput (self, inputid):
+ return self.data().real(inputid).value()
+
+ def addResult (self, result):
+ shape = result.shape()
+ body = self.document().createBody( self.data() )
+ body.store(shape)
+ self.setResult(body)
+
+
+class Interface():
+ """Base class of hight level Python interfaces to features."""
+
+ def __init__(self, container, fid):
+ self.my = container.addFeature(fid)
+
+ def setRealInput (self, inputid, value):
+ self.my.data().real(inputid).setValue(value)
+
+ def areInputValid (self):
+ return ModelAPI_Session.get().validators().validate(self.my)
+
+ def execute (self):
+ self.my.execute()
\ No newline at end of file
--- /dev/null
+"""General purpose Interface
+Author: Daniel Brunier-Coulin
+Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+"""
+
+from ModelAPI import *
+from GeomAPI import *
+import geom # To be removed when gp_Ax3 will be Pythonized
+
+
+def moduleDocument ():
+ """Returns the main document (the Partset) created or open from the Modeler.
+ This document is unique in the application session.
+ """
+ return ModelAPI_Session.get().moduleDocument()
+
+
+def activeDocument ():
+ """Returns the active document.
+ This document can be either the main application document (i.e. the Partset) or one of documents
+ referred to by the main document (a Part).
+ """
+ return ModelAPI_Session.get().activeDocument()
+
+
+def defaultPlane (name):
+ """Returns one of the three planes defined by the global coordinate system.
+ These planes are respectively referred to by name "XOY" (Z=0), "XOZ" (Y=0) or "YOZ" (X=0).
+ """
+# Temporary implementation before the availability of default planes.
+
+ o = GeomAPI_Pnt( 0, 0, 0 )
+ if name == "XOY":
+ n = GeomAPI_Dir( 0, 0, 1)
+ x = GeomAPI_Dir( 1, 0, 0)
+ elif name == "XOZ":
+ n = GeomAPI_Dir( 0, 1, 0)
+ x = GeomAPI_Dir( 1, 0, 0)
+ elif name == "YOZ":
+ n = GeomAPI_Dir( 1, 0, 0)
+ x = GeomAPI_Dir( 0, 1, 0)
+
+ return geom.Ax3( o, n, x )
+
+
+def begin ():
+ """Starts a data structure transaction, as such making a control point for being able to discard or undo
+ all operations done during this transaction.
+ """
+ ModelAPI_Session.get().startOperation()
+
+
+def end ():
+ """Commits the data structure transaction and makes all operations done since the last control point undo-able."""
+ ModelAPI_Session.get().finishOperation()
+
+
+def do ():
+ """Commits the data structure transaction and makes all operations done since the last control point undo-able."""
+ session = ModelAPI_Session.get()
+ session.finishOperation()
+ session.startOperation()
+
+
+def undo ():
+ """Rolls-back the data structure to the previous control point."""
+ ModelAPI_Session.get().undo()
+
+
+def redo ():
+ """Restore the data structure rolled-back by the last undo."""
+ ModelAPI_Session.get().redo()
--- /dev/null
+"""Sketch circle feature interface."""
+
+from GeomDataAPI import geomDataAPI_Point2D
+from model.errors import WrongNumberOfArguments
+
+class Arc():
+ def __init__(self, arc_feature, *args):
+ self._feature = arc_feature
+ self._center = geomDataAPI_Point2D(
+ self._feature.data().attribute("ArcCenter")
+ )
+ self._start_point = geomDataAPI_Point2D(
+ self._feature.data().attribute("ArcStartPoint")
+ )
+ self._end_point = geomDataAPI_Point2D(
+ self._feature.data().attribute("ArcEndPoint")
+ )
+ if len(args) == 6:
+ self.__createByCoordinates(*args)
+ elif len(args) == 3:
+ self.__createByPoints(*args)
+ else:
+ raise WrongNumberOfArguments(
+ "Arc takes 3 or 6 arguments (%s given)" % len(args)
+ )
+
+ def centerData (self):
+ return self._center
+
+ def startPointData (self):
+ return self._start_point
+
+ def endPointData (self):
+ return self._end_point
+
+ def result (self):
+ return self._feature.lastResult()
+
+ ########
+ #
+ # Private methods
+ #
+ ########
+
+ def __createByCoordinates(self,
+ center_x, center_y,
+ start_x, start_y,
+ end_x, end_y):
+ """Create an arc by point coordinates."""
+ self._center.setValue(center_x, center_y)
+ self._start_point.setValue(start_x, start_y)
+ self._end_point.setValue(end_x, end_y)
+ self._feature.execute()
+
+ def __createByPoints(self, center, start, end):
+ """Create an arc with point objects."""
+ self._center.setValue(center.x(), center.y())
+ self._start_point.setValue(start.x(), start.y())
+ self._end_point.setValue(end.x(), end.y())
+ self._feature.execute()
+
+
+
+
+
--- /dev/null
+"""Sketch circle feature interface."""
+
+from GeomDataAPI import geomDataAPI_Point2D
+
+class Circle():
+ def __init__(self, circle_feature, x, y, r):
+ self._feature = circle_feature
+ self._center = geomDataAPI_Point2D(
+ self._feature.data().attribute("CircleCenter")
+ )
+ self._radius = self._feature.data().real("CircleRadius")
+ self._center.setValue(x, y)
+ self._radius.setValue(r)
+ self._feature.execute()
+
+ def centerData (self):
+ return self._center
+
+ def radiusData (self):
+ return self._radius
+
+ def result (self):
+ return self._feature.lastResult() # Returns the circular line attribute
--- /dev/null
+from GeomDataAPI import geomDataAPI_Point2D
+
+class Line():
+ """Interface for editing of a sketch line feature."""
+ def __init__(self, line_feature, *args):
+ self._feature = line_feature
+ self._start_point = geomDataAPI_Point2D(
+ self._feature.data().attribute("StartPoint")
+ )
+ self._end_point = geomDataAPI_Point2D(
+ self._feature.data().attribute("EndPoint")
+ )
+ if len(args) == 4:
+ self.__createByCoordinates(*args)
+ elif len(args) == 2:
+ self.__createByPoints(*args)
+ elif len(args) == 1:
+ self.__createByName(sketch, *args)
+ else:
+ raise Exception("cannot create the Line")
+
+ def __createByCoordinates(self, x1, y1, x2, y2):
+ self._start_point.setValue(x1, y1)
+ self._end_point.setValue(x2, y2)
+ self._feature.execute()
+
+ def __createByPoints(self, p1, p2):
+ self._start_point.setValue(p1.x(), p1.y())
+ self._end_point.setValue(p2.x(), p2.y())
+ self._feature.execute()
+
+ def __createByName(self, sketch, name):
+ self._feature.data().selection("External").selectSubShape("EDGE", name)
+ self._feature.execute()
+ rigid = sketch.addFeature("SketchConstraintRigid")
+ rigid.refattr("ConstraintEntityA").setObject( self._feature.firstResult() )
+
+ def startPointData (self):
+ return self._start_point
+
+ def endPointData (self):
+ return self._end_point
+
+ def result (self):
+ return self._feature.firstResult()
\ No newline at end of file
--- /dev/null
+"""Sketch point feature interface."""
+
+from GeomDataAPI import geomDataAPI_Point2D
+
+class Point():
+ """Interface on point feature for data manipulation."""
+ def __init__(self, point_feature, x, y):
+ self._point_feature = point_feature
+ self._point_data = geomDataAPI_Point2D(
+ self._point_feature.data().attribute("PointCoordinates")
+ )
+ self._point_data.setValue(x, y)
+ self._point_feature.execute()
+
+ def pointData (self):
+ """Return the point data."""
+ return self._point_data
+
+ def result (self):
+ """Return the feature result."""
+ return self._point_feature.firstResult()
--- /dev/null
+"""Sketch Feature Interface
+Author: Daniel Brunier-Coulin with contribution by Mikhail Ponikarov
+Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+"""
+
+from ModelAPI import *
+from GeomDataAPI import *
+from GeomAlgoAPI import *
+from model.sketcher.point import Point
+from model.sketcher.line import Line
+from model.sketcher.circle import Circle
+from model.sketcher.arc import Arc
+
+def addSketch(doc, plane):
+ """Add a Sketch feature to the Part or PartSet and return an interface
+ on it.
+
+ A Sketch object is instanciated with a feature as input parameter
+ it provides an interface for manipulation of the feature data.
+ :return: interface on the feature
+ :rtype: Sketch object"""
+ feature = featureToCompositeFeature(doc.addFeature("Sketch"))
+ return Sketch(feature, plane)
+
+class Sketch():
+ """Interface on a Sketch feature."""
+ def __init__(self, feature, plane):
+ """Initialize a 2D Sketch on the given plane
+ The plane can be defined either by:
+ - a 3D axis system (geom.Ax3),
+ - an existing face identified by its topological name.
+ """
+ self._feature = feature
+ self._selection = None # Entities used for building the result shape
+ # self.resultype ="Face" # Type of Sketch result
+ if isinstance(plane, str):
+ self.__sketchOnFace(plane)
+ else:
+ self.__sketchOnPlane(plane)
+
+ def __sketchOnPlane (self, plane):
+ o = plane.location()
+ d = plane.direction()
+ dx = plane.xDirection()
+ geomDataAPI_Point(
+ self._feature.data().attribute("Origin")
+ ).setValue( o.x(), o.y(), o.z() )
+ geomDataAPI_Dir(
+ self._feature.data().attribute("DirX")
+ ).setValue( dx.x(), dx.y(), dx.z() )
+ geomDataAPI_Dir(
+ self._feature.data().attribute("Norm")
+ ).setValue( d.x(), d.y(), d.z() )
+
+ def __sketchOnFace (self, plane):
+ self._feature.data().selection("External").selectSubShape("FACE", plane)
+
+
+# Creation of Geometries
+
+ def addPoint (self, *args):
+ """Add a point to this Sketch."""
+ point_feature = self._feature.addFeature("SketchPoint")
+ return Point(point_feature, *args)
+
+ def addLine (self, *args):
+ """Add a line to this Sketch."""
+ line_feature = self._feature.addFeature("SketchLine")
+ return Line(line_feature, *args)
+
+ def addCircle (self, *args):
+ """Add a circle to this Sketch."""
+ circle_feature = self._feature.addFeature("SketchCircle")
+ return Circle(circle_feature, *args)
+
+ def addArc (self, *args):
+ """Add an arc to this Sketch."""
+ arc_feature = self._feature.addFeature("SketchArc")
+ return Arc(arc_feature, *args)
+
+ def addPolyline (self, *coords):
+ """Adds a poly-line to this Sketch.
+
+ The end of consecutive segments are defined as coincident.
+ """
+ c0 = coords[0]
+ c1 = coords[1]
+ polyline = []
+ line_1 = self.addLine(c0, c1)
+ polyline.append(line_1)
+ # Adding and connecting next lines
+ for c2 in coords[2:]:
+ line_2 = self.addLine(c1, c2)
+ self.setCoincident(line_1.endPointData(), line_2.startPointData())
+ polyline.append(line_2)
+ c1 = c2
+ line_1 = line_2
+ return polyline
+
+ def addPolygon (self, *coords):
+ """Add a polygon to this Sketch.
+
+ The end of consecutive segments are defined as coincident.
+ """
+ pg = self.addPolyline(*coords)
+ # Closing the poly-line supposed being defined by at least 3 points
+ c0 = coords[0]
+ cn = coords[len(coords) - 1]
+ ln = self.addLine(cn, c0)
+ self.setCoincident(
+ pg[len(coords) - 2].endPointData(), ln.startPointData()
+ )
+ self.setCoincident(
+ ln.endPointData(), pg[0].startPointData()
+ )
+ pg.append(ln)
+ return pg
+
+
+ # Creation of Geometrical and Dimensional Constraints
+
+ def setCoincident (self, p1, p2):
+ """Set coincident the two given points and add the corresponding
+ constraint to this Sketch."""
+ constraint = self._feature.addFeature("SketchConstraintCoincidence")
+ constraint.data().refattr("ConstraintEntityA").setAttr(p1)
+ constraint.data().refattr("ConstraintEntityB").setAttr(p2)
+ return constraint
+
+ def setParallel (self, l1, l2):
+ """Set parallel the two given lines and add the corresponding
+ constraint to this Sketch."""
+ constraint = self._feature.addFeature("SketchConstraintParallel")
+ constraint.data().refattr("ConstraintEntityA").setObject(l1)
+ constraint.data().refattr("ConstraintEntityB").setObject(l2)
+ return constraint
+
+ def setPerpendicular (self, l1, l2):
+ """Set perpendicular the two given lines and add the corresponding
+ constraint to this Sketch."""
+ constraint = self._feature.addFeature("SketchConstraintPerpendicular")
+ constraint.data().refattr("ConstraintEntityA").setObject(l1)
+ constraint.data().refattr("ConstraintEntityB").setObject(l2)
+ return constraint
+
+ def setDistance (self, point, line, length):
+ """Set the distance between the given point and line, and add
+ the corresponding constraint to this Sketch."""
+ constraint = self._feature.addFeature("SketchConstraintDistance")
+ if isinstance(line, str):
+ # Add the edge identified by the given topological name
+ # to this Sketch
+ line = self.addLine(line).result()
+ constraint.data().refattr("ConstraintEntityA").setAttr(point)
+ constraint.data().refattr("ConstraintEntityB").setObject(line)
+ constraint.data().real("ConstraintValue").setValue(length)
+ self._feature.execute()
+ return constraint
+
+ def setLength (self, line, length):
+ """Set the length of the given line and add the corresponding
+ constraint to this Sketch."""
+ constraint = self._feature.addFeature("SketchConstraintLength")
+ constraint.data().refattr("ConstraintEntityA").setObject(line)
+ constraint.data().real("ConstraintValue").setValue(length)
+ self._feature.execute()
+ return constraint
+
+ def setRadius (self, circle, radius):
+ """Set the radius of the given circle and add the corresponding
+ constraint to this Sketch."""
+ constraint = self._feature.addFeature("SketchConstraintRadius")
+ constraint.data().refattr("ConstraintEntityA").setObject(circle)
+ constraint.data().real("ConstraintValue").setValue(radius)
+ return constraint
+
+
+ # Edition of Dimensional Constraints
+
+ def setValue (self, constraint, value):
+ """Modify the value of the given dimensional constraint."""
+ constraint.data().real("ConstraintValue").setValue(value)
+
+
+# Getters
+
+ def selectFace (self, *args):
+ """Select the geometrical entities of this Sketch on which
+ the result Face must be built.
+
+ When no entity is given, the face is based on all existing
+ geometry of this Sketch.
+ """
+ #self.resultype ="Face"
+ if len(args) == 0:
+ self._selection = modelAPI_ResultConstruction(
+ self._feature.firstResult()).shape()
+ elif len(args) == 1:
+ self._selection = args[0].shape()
+ else:
+ raise Exception("not yet implemented")
+ return self
+
+ def buildShape (self):
+ """Builds the result Shape of this Sketch according to the selected geometrical entities."""
+ o = geomDataAPI_Point( self._feature.data().attribute("Origin") ).pnt()
+ dx = geomDataAPI_Dir( self._feature.data().attribute("DirX") ).dir()
+ n = geomDataAPI_Dir( self._feature.data().attribute("Norm") ).dir()
+
+ faces = ShapeList() # The faces are kept otherwise they are destroyed at exit
+ GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
+ #TODO: Deal with several faces
+ return faces[0]
+
+ def result (self):
+ """Returns the result data of this Feature."""
+ return self._feature.firstResult()
+++ /dev/null
-"""This package defines the Parametric Geometry API of the Modeler.
-"""
-
-# General purpose functions and abstract root classes
-
-from services import *
-from roots import *
-
-# Built-in features
-
-from part import Part as addPart
-from sketcher.sketch import addSketch
-from extrusion import Extrusion as addExtrusion
-from boolean import Addition as addAddition
-from boolean import Subtraction as addSubtraction
-from boolean import Intersection as addIntersection
-
-# Custom exceptions
-
-from errors import WrongNumberOfArguments
\ No newline at end of file
+++ /dev/null
-"""Boolean operations Interface
-Author: Daniel Brunier-Coulin
-Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-"""
-
-from ModelAPI import *
-from GeomAlgoAPI import *
-
-
-class Boolean():
- """Abstract root class of Boolean Features."""
- def __init__(self, part, object, tool, type):
- self.my = part.addFeature("Boolean")
- self.my.data().reference("main_object").setValue(object)
- self.my.data().reference("tool_object").setValue(tool)
- self.my.data().integer("bool_type").setValue(type)
-
- if ModelAPI_Session.get().validators().validate(self.my):
- self.my.execute()
- else:
- raise Exception("cannot make the Boolean")
-
-
-class Addition(Boolean):
-
- def __init__(self, part, object, tool):
- """Inserts an addition to the given Part and executes the operation.
- This operation adds tool to the given object.
- """
- Boolean.__init__(self, part, object, tool, GeomAlgoAPI_Boolean.BOOL_FUSE)
-
-
-class Subtraction(Boolean):
-
- def __init__(self, part, object, tool):
- """Inserts a subtraction to the given Part and executes the operation.
- This operation subtracts tool to the given object.
- """
- Boolean.__init__(self, part, object, tool, GeomAlgoAPI_Boolean.BOOL_CUT)
-
-
-class Intersection(Boolean):
-
- def __init__(self, part, object, tool):
- """Inserts an intersection to the given Part and executes the operation.
- This operation intersects tool to the given object.
- """
- Boolean.__init__(self, part, object, tool, GeomAlgoAPI_Boolean.BOOL_COMMON)
\ No newline at end of file
+++ /dev/null
-# Package exceptions
-
-class ModelerError(Exception):
- """Base class for exceptions in this package."""
- pass
-
-class WrongNumberOfArguments(ModelerError):
- """Exception raised when a wrong number of arguments is given."""
- pass
-
- #Attributes:
- #expr -- input expression in which the error occurred
- #msg -- explanation of the error
- #"""
-
- #def __init__(self, expr, msg):
- #self.expr = expr
- #self.msg = msg
+++ /dev/null
-"""Extrusion Interface
-Author: Daniel Brunier-Coulin with contribution by Mikhail Ponikarov
-Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-"""
-
-from ModelAPI import *
-
-
-class Extrusion():
-
- def __init__ (self, part, sketch, size):
- """Inserts an extrusion of the given Sketch to the given Part and executes the operation."""
- self.my = part.addFeature("Extrusion")
- self.my.string("CreationMethod").setValue("BySizes")
- self.my.data().selectionList("base").append(sketch.result(), sketch.buildShape())
- if size < 0:
- self.my.data().real("from_size").setValue(-size)
- self.my.data().real("to_size").setValue(0)
- else:
- self.my.data().real("to_size").setValue(size)
- self.my.data().real("from_size").setValue(0)
-
-
- if ModelAPI_Session.get().validators().validate(self.my):
- self.my.execute()
- else:
- raise Exception("cannot make the Extrusion")
-
-
- def setSize (self, size):
- """Modifies the size of this extrusion according to the given size."""
- if size < 0:
- self.my.data().real("from_size").setValue(-size)
- self.my.data().real("to_size").setValue(0)
- else:
- self.my.data().real("to_size").setValue(size)
- self.my.data().real("from_size").setValue(0)
-
- self.my.execute()
-
- def result (self):
- """Returns the result data of this Feature."""
- return self.my.firstResult()
+++ /dev/null
-"""Part Feature Interface
-Author: Daniel Brunier-Coulin
-Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-"""
-
-import modeler # Required by the temporary implementation of result member function
-
-
-class Part():
-
- def __init__ (self, partset):
- """Adds a new Part to the given Partset and activates the Part."""
- self.my = partset.addFeature("Part")
- self.my.execute()
-
- def document (self):
- """Returns the Part document created by this feature."""
- #TODO: Get the document referenced by this feature
- return modeler.activeDocument()
\ No newline at end of file
+++ /dev/null
-"""Abstract root classes of user-defined Python features producing a Body
-Author: Daniel Brunier-Coulin
-Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-"""
-
-from ModelAPI import *
-
-
-class Feature(ModelAPI_Feature):
- """Base class of user-defined Python features."""
-
- def __init__(self):
- ModelAPI_Feature.__init__(self)
-
- def addRealInput (self, inputid):
- self.data().addAttribute(inputid, ModelAPI_AttributeDouble_typeId())
-
- def getRealInput (self, inputid):
- return self.data().real(inputid).value()
-
- def addResult (self, result):
- shape = result.shape()
- body = self.document().createBody( self.data() )
- body.store(shape)
- self.setResult(body)
-
-
-class Interface():
- """Base class of hight level Python interfaces to features."""
-
- def __init__(self, container, fid):
- self.my = container.addFeature(fid)
-
- def setRealInput (self, inputid, value):
- self.my.data().real(inputid).setValue(value)
-
- def areInputValid (self):
- return ModelAPI_Session.get().validators().validate(self.my)
-
- def execute (self):
- self.my.execute()
\ No newline at end of file
+++ /dev/null
-"""General purpose Interface
-Author: Daniel Brunier-Coulin
-Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-"""
-
-from ModelAPI import *
-from GeomAPI import *
-import geom # To be removed when gp_Ax3 will be Pythonized
-
-
-def moduleDocument ():
- """Returns the main document (the Partset) created or open from the Modeler.
- This document is unique in the application session.
- """
- return ModelAPI_Session.get().moduleDocument()
-
-
-def activeDocument ():
- """Returns the active document.
- This document can be either the main application document (i.e. the Partset) or one of documents
- referred to by the main document (a Part).
- """
- return ModelAPI_Session.get().activeDocument()
-
-
-def defaultPlane (name):
- """Returns one of the three planes defined by the global coordinate system.
- These planes are respectively referred to by name "XOY" (Z=0), "XOZ" (Y=0) or "YOZ" (X=0).
- """
-# Temporary implementation before the availability of default planes.
-
- o = GeomAPI_Pnt( 0, 0, 0 )
- if name == "XOY":
- n = GeomAPI_Dir( 0, 0, 1)
- x = GeomAPI_Dir( 1, 0, 0)
- elif name == "XOZ":
- n = GeomAPI_Dir( 0, 1, 0)
- x = GeomAPI_Dir( 1, 0, 0)
- elif name == "YOZ":
- n = GeomAPI_Dir( 1, 0, 0)
- x = GeomAPI_Dir( 0, 1, 0)
-
- return geom.Ax3( o, n, x )
-
-
-def begin ():
- """Starts a data structure transaction, as such making a control point for being able to discard or undo
- all operations done during this transaction.
- """
- ModelAPI_Session.get().startOperation()
-
-
-def end ():
- """Commits the data structure transaction and makes all operations done since the last control point undo-able."""
- ModelAPI_Session.get().finishOperation()
-
-
-def do ():
- """Commits the data structure transaction and makes all operations done since the last control point undo-able."""
- session = ModelAPI_Session.get()
- session.finishOperation()
- session.startOperation()
-
-
-def undo ():
- """Rolls-back the data structure to the previous control point."""
- ModelAPI_Session.get().undo()
-
-
-def redo ():
- """Restore the data structure rolled-back by the last undo."""
- ModelAPI_Session.get().redo()
+++ /dev/null
-"""Sketch circle feature interface."""
-
-from GeomDataAPI import geomDataAPI_Point2D
-from modeler.errors import WrongNumberOfArguments
-
-class Arc():
- def __init__(self, arc_feature, *args):
- self._feature = arc_feature
- self._center = geomDataAPI_Point2D(
- self._feature.data().attribute("ArcCenter")
- )
- self._start_point = geomDataAPI_Point2D(
- self._feature.data().attribute("ArcStartPoint")
- )
- self._end_point = geomDataAPI_Point2D(
- self._feature.data().attribute("ArcEndPoint")
- )
- if len(args) == 6:
- self.__createByCoordinates(*args)
- elif len(args) == 3:
- self.__createByPoints(*args)
- else:
- raise WrongNumberOfArguments(
- "Arc takes 3 or 6 arguments (%s given)" % len(args)
- )
-
- def centerData (self):
- return self._center
-
- def startPointData (self):
- return self._start_point
-
- def endPointData (self):
- return self._end_point
-
- def result (self):
- return self._feature.lastResult()
-
- ########
- #
- # Private methods
- #
- ########
-
- def __createByCoordinates(self,
- center_x, center_y,
- start_x, start_y,
- end_x, end_y):
- """Create an arc by point coordinates."""
- self._center.setValue(center_x, center_y)
- self._start_point.setValue(start_x, start_y)
- self._end_point.setValue(end_x, end_y)
- self._feature.execute()
-
- def __createByPoints(self, center, start, end):
- """Create an arc with point objects."""
- self._center.setValue(center.x(), center.y())
- self._start_point.setValue(start.x(), start.y())
- self._end_point.setValue(end.x(), end.y())
- self._feature.execute()
-
-
-
-
-
+++ /dev/null
-"""Sketch circle feature interface."""
-
-from GeomDataAPI import geomDataAPI_Point2D
-
-class Circle():
- def __init__(self, circle_feature, x, y, r):
- self._feature = circle_feature
- self._center = geomDataAPI_Point2D(
- self._feature.data().attribute("CircleCenter")
- )
- self._radius = self._feature.data().real("CircleRadius")
- self._center.setValue(x, y)
- self._radius.setValue(r)
- self._feature.execute()
-
- def centerData (self):
- return self._center
-
- def radiusData (self):
- return self._radius
-
- def result (self):
- return self._feature.lastResult() # Returns the circular line attribute
+++ /dev/null
-from GeomDataAPI import geomDataAPI_Point2D
-
-class Line():
- """Interface for editing of a sketch line feature."""
- def __init__(self, line_feature, *args):
- self._feature = line_feature
- self._start_point = geomDataAPI_Point2D(
- self._feature.data().attribute("StartPoint")
- )
- self._end_point = geomDataAPI_Point2D(
- self._feature.data().attribute("EndPoint")
- )
- if len(args) == 4:
- self.__createByCoordinates(*args)
- elif len(args) == 2:
- self.__createByPoints(*args)
- elif len(args) == 1:
- self.__createByName(sketch, *args)
- else:
- raise Exception("cannot create the Line")
-
- def __createByCoordinates(self, x1, y1, x2, y2):
- self._start_point.setValue(x1, y1)
- self._end_point.setValue(x2, y2)
- self._feature.execute()
-
- def __createByPoints(self, p1, p2):
- self._start_point.setValue(p1.x(), p1.y())
- self._end_point.setValue(p2.x(), p2.y())
- self._feature.execute()
-
- def __createByName(self, sketch, name):
- self._feature.data().selection("External").selectSubShape("EDGE", name)
- self._feature.execute()
- rigid = sketch.addFeature("SketchConstraintRigid")
- rigid.refattr("ConstraintEntityA").setObject( self._feature.firstResult() )
-
- def startPointData (self):
- return self._start_point
-
- def endPointData (self):
- return self._end_point
-
- def result (self):
- return self._feature.firstResult()
\ No newline at end of file
+++ /dev/null
-"""Sketch point feature interface."""
-
-from GeomDataAPI import geomDataAPI_Point2D
-
-class Point():
- """Interface on point feature for data manipulation."""
- def __init__(self, point_feature, x, y):
- self._point_feature = point_feature
- self._point_data = geomDataAPI_Point2D(
- self._point_feature.data().attribute("PointCoordinates")
- )
- self._point_data.setValue(x, y)
- self._point_feature.execute()
-
- def pointData (self):
- """Return the point data."""
- return self._point_data
-
- def result (self):
- """Return the feature result."""
- return self._point_feature.firstResult()
+++ /dev/null
-"""Sketch Feature Interface
-Author: Daniel Brunier-Coulin with contribution by Mikhail Ponikarov
-Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-"""
-
-from ModelAPI import *
-from GeomDataAPI import *
-from GeomAlgoAPI import *
-from modeler.sketcher.point import Point
-from modeler.sketcher.line import Line
-from modeler.sketcher.circle import Circle
-from modeler.sketcher.arc import Arc
-
-def addSketch(doc, plane):
- """Add a Sketch feature to the Part or PartSet and return an interface
- on it.
-
- A Sketch object is instanciated with a feature as input parameter
- it provides an interface for manipulation of the feature data.
- :return: interface on the feature
- :rtype: Sketch object"""
- feature = featureToCompositeFeature(doc.addFeature("Sketch"))
- return Sketch(feature, plane)
-
-class Sketch():
- """Interface on a Sketch feature."""
- def __init__(self, feature, plane):
- """Initialize a 2D Sketch on the given plane
- The plane can be defined either by:
- - a 3D axis system (geom.Ax3),
- - an existing face identified by its topological name.
- """
- self._feature = feature
- self._selection = None # Entities used for building the result shape
- # self.resultype ="Face" # Type of Sketch result
- if isinstance(plane, str):
- self.__sketchOnFace(plane)
- else:
- self.__sketchOnPlane(plane)
-
- def __sketchOnPlane (self, plane):
- o = plane.location()
- d = plane.direction()
- dx = plane.xDirection()
- geomDataAPI_Point(
- self._feature.data().attribute("Origin")
- ).setValue( o.x(), o.y(), o.z() )
- geomDataAPI_Dir(
- self._feature.data().attribute("DirX")
- ).setValue( dx.x(), dx.y(), dx.z() )
- geomDataAPI_Dir(
- self._feature.data().attribute("Norm")
- ).setValue( d.x(), d.y(), d.z() )
-
- def __sketchOnFace (self, plane):
- self._feature.data().selection("External").selectSubShape("FACE", plane)
-
-
-# Creation of Geometries
-
- def addPoint (self, *args):
- """Add a point to this Sketch."""
- point_feature = self._feature.addFeature("SketchPoint")
- return Point(point_feature, *args)
-
- def addLine (self, *args):
- """Add a line to this Sketch."""
- line_feature = self._feature.addFeature("SketchLine")
- return Line(line_feature, *args)
-
- def addCircle (self, *args):
- """Add a circle to this Sketch."""
- circle_feature = self._feature.addFeature("SketchCircle")
- return Circle(circle_feature, *args)
-
- def addArc (self, *args):
- """Add an arc to this Sketch."""
- arc_feature = self._feature.addFeature("SketchArc")
- return Arc(arc_feature, *args)
-
- def addPolyline (self, *coords):
- """Adds a poly-line to this Sketch.
-
- The end of consecutive segments are defined as coincident.
- """
- c0 = coords[0]
- c1 = coords[1]
- polyline = []
- line_1 = self.addLine(c0, c1)
- polyline.append(line_1)
- # Adding and connecting next lines
- for c2 in coords[2:]:
- line_2 = self.addLine(c1, c2)
- self.setCoincident(line_1.endPointData(), line_2.startPointData())
- polyline.append(line_2)
- c1 = c2
- line_1 = line_2
- return polyline
-
- def addPolygon (self, *coords):
- """Add a polygon to this Sketch.
-
- The end of consecutive segments are defined as coincident.
- """
- pg = self.addPolyline(*coords)
- # Closing the poly-line supposed being defined by at least 3 points
- c0 = coords[0]
- cn = coords[len(coords) - 1]
- ln = self.addLine(cn, c0)
- self.setCoincident(
- pg[len(coords) - 2].endPointData(), ln.startPointData()
- )
- self.setCoincident(
- ln.endPointData(), pg[0].startPointData()
- )
- pg.append(ln)
- return pg
-
-
- # Creation of Geometrical and Dimensional Constraints
-
- def setCoincident (self, p1, p2):
- """Set coincident the two given points and add the corresponding
- constraint to this Sketch."""
- constraint = self._feature.addFeature("SketchConstraintCoincidence")
- constraint.data().refattr("ConstraintEntityA").setAttr(p1)
- constraint.data().refattr("ConstraintEntityB").setAttr(p2)
- return constraint
-
- def setParallel (self, l1, l2):
- """Set parallel the two given lines and add the corresponding
- constraint to this Sketch."""
- constraint = self._feature.addFeature("SketchConstraintParallel")
- constraint.data().refattr("ConstraintEntityA").setObject(l1)
- constraint.data().refattr("ConstraintEntityB").setObject(l2)
- return constraint
-
- def setPerpendicular (self, l1, l2):
- """Set perpendicular the two given lines and add the corresponding
- constraint to this Sketch."""
- constraint = self._feature.addFeature("SketchConstraintPerpendicular")
- constraint.data().refattr("ConstraintEntityA").setObject(l1)
- constraint.data().refattr("ConstraintEntityB").setObject(l2)
- return constraint
-
- def setDistance (self, point, line, length):
- """Set the distance between the given point and line, and add
- the corresponding constraint to this Sketch."""
- constraint = self._feature.addFeature("SketchConstraintDistance")
- if isinstance(line, str):
- # Add the edge identified by the given topological name
- # to this Sketch
- line = self.addLine(line).result()
- constraint.data().refattr("ConstraintEntityA").setAttr(point)
- constraint.data().refattr("ConstraintEntityB").setObject(line)
- constraint.data().real("ConstraintValue").setValue(length)
- self._feature.execute()
- return constraint
-
- def setLength (self, line, length):
- """Set the length of the given line and add the corresponding
- constraint to this Sketch."""
- constraint = self._feature.addFeature("SketchConstraintLength")
- constraint.data().refattr("ConstraintEntityA").setObject(line)
- constraint.data().real("ConstraintValue").setValue(length)
- self._feature.execute()
- return constraint
-
- def setRadius (self, circle, radius):
- """Set the radius of the given circle and add the corresponding
- constraint to this Sketch."""
- constraint = self._feature.addFeature("SketchConstraintRadius")
- constraint.data().refattr("ConstraintEntityA").setObject(circle)
- constraint.data().real("ConstraintValue").setValue(radius)
- return constraint
-
-
- # Edition of Dimensional Constraints
-
- def setValue (self, constraint, value):
- """Modify the value of the given dimensional constraint."""
- constraint.data().real("ConstraintValue").setValue(value)
-
-
-# Getters
-
- def selectFace (self, *args):
- """Select the geometrical entities of this Sketch on which
- the result Face must be built.
-
- When no entity is given, the face is based on all existing
- geometry of this Sketch.
- """
- #self.resultype ="Face"
- if len(args) == 0:
- self._selection = modelAPI_ResultConstruction(
- self._feature.firstResult()).shape()
- elif len(args) == 1:
- self._selection = args[0].shape()
- else:
- raise Exception("not yet implemented")
- return self
-
- def buildShape (self):
- """Builds the result Shape of this Sketch according to the selected geometrical entities."""
- o = geomDataAPI_Point( self._feature.data().attribute("Origin") ).pnt()
- dx = geomDataAPI_Dir( self._feature.data().attribute("DirX") ).dir()
- n = geomDataAPI_Dir( self._feature.data().attribute("Norm") ).dir()
-
- faces = ShapeList() # The faces are kept otherwise they are destroyed at exit
- GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
- #TODO: Deal with several faces
- return faces[0]
-
- def result (self):
- """Returns the result data of this Feature."""
- return self._feature.firstResult()