ADD_SUBDIRECTORY (src/ConstructionPlugin)
ADD_SUBDIRECTORY (src/FeaturesPlugin)
ADD_SUBDIRECTORY (src/SketcherPrs)
-ADD_SUBDIRECTORY (src/PythonFeaturesPlugin)
ADD_SUBDIRECTORY (src/SketchPlugin)
ADD_SUBDIRECTORY (src/SketchSolver)
ADD_SUBDIRECTORY (src/ModuleBase)
ADD_SUBDIRECTORY (src/GeomValidators)
ADD_SUBDIRECTORY (src/InitializationPlugin)
ADD_SUBDIRECTORY (src/ParametersPlugin)
+ADD_SUBDIRECTORY (src/PythonAddons)
+ADD_SUBDIRECTORY (src/PythonAPI)
IF(${HAVE_SALOME})
ADD_SUBDIRECTORY (src/NewGeom)
)
@SET NEW_GEOM_CONFIG_FILE=%ROOT_DIR%\install\plugins
-@SET PATH=%ROOT_DIR%\install\swig;%ROOT_DIR%\install\plugins;%ROOT_DIR%\install\bin;%PATH%
-@SET PYTHONPATH=%ROOT_DIR%\install\swig;%ROOT_DIR%\install\plugins;%PYTHONPATH%
+@SET NEWGEOM_ROOT_DIR=%ROOT_DIR%\install
+@SET PATH=%NEWGEOM_ROOT_DIR%\swig;%NEWGEOM_ROOT_DIR%\plugins;%NEWGEOM_ROOT_DIR%\bin;%PATH%
+@SET PYTHONPATH=%NEWGEOM_ROOT_DIR%\swig;%NEWGEOM_ROOT_DIR%\plugins;%NEWGEOM_ROOT_DIR%\addons;%NEWGEOM_ROOT_DIR%\pythonAPI;%PYTHONPATH%
-@SET LightAppConfig=%ROOT_DIR%\install\share\salome\resources\newgeom;%GUI_ROOT_DIR%\share\salome\resources\gui
-@SET NewGeomResources=%ROOT_DIR%\install\resources
+@SET LightAppConfig=%%NEWGEOM_ROOT_DIR%\share\salome\resources\newgeom;%GUI_ROOT_DIR%\share\salome\resources\gui
+@SET NewGeomResources=%NEWGEOM_ROOT_DIR%\resources
#------ NewGEOM ------
export NEWGEOM_ROOT_DIR=${ROOT_DIR}/install
export PATH=${NEWGEOM_ROOT_DIR}/bin:${NEWGEOM_ROOT_DIR}/plugins:${PATH}
-export PYTHONPATH=${NEWGEOM_ROOT_DIR}/swig:${NEWGEOM_ROOT_DIR}/plugins:${PYTHONPATH}
+export PYTHONPATH=${NEWGEOM_ROOT_DIR}/swig:${NEWGEOM_ROOT_DIR}/plugins:${NEWGEOM_ROOT_DIR}/addons:${NEWGEOM_ROOT_DIR}/pythonAPI:${PYTHONPATH}
export LD_LIBRARY_PATH=${NEWGEOM_ROOT_DIR}/bin:${NEWGEOM_ROOT_DIR}/swig:${NEWGEOM_ROOT_DIR}/plugins:${LD_LIBRARY_PATH}
export NEW_GEOM_CONFIG_FILE=${NEWGEOM_ROOT_DIR}/plugins
export NewGeomResources=${NEWGEOM_ROOT_DIR}/resources
@REM -------------------------
@REM OPENPARTS
-@SET NEW_GEOM_CONFIG_FILE=%ROOT_DIR%\install\plugins
-@SET PATH=%ROOT_DIR%\install\swig;%ROOT_DIR%\install\plugins;%ROOT_DIR%\install\bin;%PATH%
-@SET PYTHONPATH=%ROOT_DIR%\install\swig;%ROOT_DIR%\install\plugins;%PYTHONPATH%
-@SET NewGeomResources=%ROOT_DIR%\install\resources
-@REM -------------------------
+@SET NEWGEOM_ROOT_DIR=%ROOT_DIR%\install
+@SET NEW_GEOM_CONFIG_FILE=%NEWGEOM_ROOT_DIR%\plugins
+@SET PATH=%NEWGEOM_ROOT_DIR%\swig;%NEWGEOM_ROOT_DIR%\plugins;%NEWGEOM_ROOT_DIR%\bin;%PATH%
+@SET PYTHONPATH=%NEWGEOM_ROOT_DIR%\swig;%NEWGEOM_ROOT_DIR%\plugins;%NEWGEOM_ROOT_DIR%\addons;%NEWGEOM_ROOT_DIR%\pythonAPI;%PYTHONPATH%
+@SET NewGeomResources=%NEWGEOM_ROOT_DIR%\resources
rem -------- Visual Studio --------------------
rem Detect Visual Studio (either commercial or Express edition)
call env_Salome.bat
@SET NEWGEOM_ROOT_DIR=%ROOT_DIR%\install
-@SET SalomeAppConfig=%ROOT_DIR%\install\share\salome\resources\newgeom;%GUI_ROOT_DIR%\share\salome\resources\gui
+@SET SalomeAppConfig=%NEWGEOM_ROOT_DIR%\share\salome\resources\newgeom;%GUI_ROOT_DIR%\share\salome\resources\gui
start %PYTHONBIN% "%KERNEL_ROOT_DIR%\bin\salome\envSalome.py" "%PYTHONBIN%" "%KERNEL_ROOT_DIR%\bin\salome\runSalome.py" %*
<plugin library="ConstructionPlugin" configuration="plugin-Construction.xml"/>
<plugin library="FeaturesPlugin" configuration="plugin-Features.xml"/>
<plugin library="ExchangePlugin" configuration="plugin-Exchange.xml"/>
- <plugin script="PythonFeaturesPlugin" configuration="plugin-PythonFeatures.xml"/>
+ <plugin script="addons_Features" configuration="addons_Features.xml"/>
<plugin script="ConnectorPlugin" configuration="plugin-Connector.xml" dependency="Geometry"/>
<plugin library="ParametersPlugin" configuration="plugin-Parameters.xml"/>
<plugin library="SketchSolver"/>
void GeomAlgoAPI_SketchBuilder::createFaces(
- const std::shared_ptr<GeomAPI_Pnt>& theOrigin, const std::shared_ptr<GeomAPI_Dir>& theDirX,
- const std::shared_ptr<GeomAPI_Dir>& theDirY, const std::shared_ptr<GeomAPI_Dir>& theNorm,
+ const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ const std::shared_ptr<GeomAPI_Dir>& theDirX,
+ const std::shared_ptr<GeomAPI_Dir>& theNorm,
const std::list<std::shared_ptr<GeomAPI_Shape> >& theFeatures,
std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces,
std::list<std::shared_ptr<GeomAPI_Shape> >& theResultWires)
return;
gp_Dir aDirX = theDirX->impl<gp_Dir>();
- gp_Dir aDirY = theDirY->impl<gp_Dir>();
gp_Dir aNorm = theNorm->impl<gp_Dir>();
+ gp_Dir aDirY = aNorm.Crossed(aDirX);
gp_Pln aPlane(theOrigin->impl<gp_Pnt>(), aNorm);
void GeomAlgoAPI_SketchBuilder::createFaces(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
const std::shared_ptr<GeomAPI_Dir>& theDirX,
- const std::shared_ptr<GeomAPI_Dir>& theDirY,
const std::shared_ptr<GeomAPI_Dir>& theNorm,
const std::shared_ptr<GeomAPI_Shape>& theWire,
std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces)
return;
// Filter wires, return only faces.
std::list<std::shared_ptr<GeomAPI_Shape> > aFilteredWires;
- createFaces(theOrigin, theDirX, theDirY, theNorm,
+ createFaces(theOrigin, theDirX, theNorm,
aWire->getEdges(), theResultFaces, aFilteredWires);
}
*/
static void createFaces(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
const std::shared_ptr<GeomAPI_Dir>& theDirX,
- const std::shared_ptr<GeomAPI_Dir>& theDirY,
const std::shared_ptr<GeomAPI_Dir>& theNorm,
const std::list<std::shared_ptr<GeomAPI_Shape> >& theFeatures,
std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces,
*/
static void createFaces(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
const std::shared_ptr<GeomAPI_Dir>& theDirX,
- const std::shared_ptr<GeomAPI_Dir>& theDirY,
const std::shared_ptr<GeomAPI_Dir>& theNorm,
const std::shared_ptr<GeomAPI_Shape>& theWire,
std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces);
std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(myShape);
std::list<std::shared_ptr<GeomAPI_Shape> > aFaces;
GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(),
- aWirePtr->dirY(), aWirePtr->norm(), aWirePtr, aFaces);
+ aWirePtr->norm(), aWirePtr, aFaces);
std::list<std::shared_ptr<GeomAPI_Shape> >::iterator aFIter = aFaces.begin();
for(; aFIter != aFaces.end(); aFIter++) {
std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(*aFIter));
if (!data()->name().empty())
PartSetPlugin_Part::execute();
}
+
+const std::string& PartSetPlugin_Duplicate::documentToAdd()
+{
+ // part must be added only to the module document
+ return ModelAPI_Session::get()->moduleDocument()->kind();
+}
/// Makes a new part, copy of active
PartSetPlugin_Duplicate();
+ /// Part must be added only to PartSet
+ PARTSETPLUGIN_EXPORT virtual const std::string& documentToAdd();
+
/// Request for initialization of data model of the feature: adding all attributes
PARTSETPLUGIN_EXPORT virtual void initAttributes();
/// Request for initialization of data model of the feature: adding all attributes
PARTSETPLUGIN_EXPORT virtual void initAttributes();
+ /// Part must be added only to PartSet
PARTSETPLUGIN_EXPORT virtual const std::string& documentToAdd();
/// Returns true if this feature must be displayed in the history (top level of Part tree)
--- /dev/null
+## Copyright (C) 2014-20xx OPEN CASCADE
+
+
+SET(CMAKE_AUTOMOC ON)
+
+INSTALL(DIRECTORY extension geom modeler DESTINATION pythonAPI)
--- /dev/null
+# Creation of a box using the end-user API
+# Author: Daniel Brunier-Coulin
+# -----------------------------
+
+import modeler
+
+
+# Initialisation
+
+modeler.begin()
+mypartset = modeler.moduleDocument()
+
+
+# Creating a new Part
+
+mypart = modeler.addPart(mypartset).document()
+
+
+# Creating the base of the box
+
+mybase = modeler.addSketch( mypart, modeler.defaultPlane("XOY") )
+
+l1 = mybase.addLine( 0, 0, 0, 1 )
+l2 = mybase.addLine( 0, 1, 1, 1 )
+l3 = mybase.addLine( 1, 1, 1, 0 )
+l4 = mybase.addLine( 1, 0, 0, 0 )
+
+mybase.setCoincident( l1.endPointData(), l2.startPointData() )
+mybase.setCoincident( l2.endPointData(), l3.startPointData() )
+mybase.setCoincident( l3.endPointData(), l4.startPointData() )
+mybase.setCoincident( l4.endPointData(), l1.startPointData() )
+
+mybase.setParallel( l1.result(), l3.result() )
+mybase.setParallel( l2.result(), l4.result() )
+
+mybase.setPerpendicular( l1.result(), l4.result() )
+
+mywidth = mybase.setLength( l1.result(), 50 )
+mylength = mybase.setDistance( l1.startPointData(), l3.result(), 50 )
+
+
+# Creating the extrusion
+
+mybox = modeler.addExtrusion( mypart, mybase.selectFace(), 50 )
+
+
+# Creating a cylinder on a face of the box
+
+thisface = "Extrusion_1/LateralFace_2"
+thisxmin = "Extrusion_1/LateralFace_3|Extrusion_1/LateralFace_2"
+thisxmax = "Extrusion_1/LateralFace_2|Extrusion_1/LateralFace_1"
+thiszmin = "Sketch_1/Edge5_1"
+thiszmax = "Extrusion_1/LateralFace_2|Extrusion_1/TopFace_1"
+
+mystand = modeler.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 )
+
+
+# Subtracting the cylinder to the box
+
+modeler.addSubtraction( mypart, mybox.result(), myboss.result() )
+modeler.end()
+
+
+# Editing the box
+
+modeler.begin()
+mybase.setValue( mylength, 100 )
+mybox.setSize( 20 )
+modeler.end()
--- /dev/null
+# Creation of a box using the end-user API
+# Author: Daniel Brunier-Coulin
+# -----------------------------
+
+import modeler
+import geom
+
+
+# Initialisation
+
+modeler.begin()
+mypartset = modeler.moduleDocument()
+
+
+# Creating a new Part
+
+mypart = modeler.addPart(mypartset).document()
+
+
+# Creating the base of the box
+
+mybase = modeler.addSketch( mypart, modeler.defaultPlane("XOY") )
+
+p1 = geom.Pnt2d( 0, 0 )
+p2 = geom.Pnt2d( 0, 1 )
+p3 = geom.Pnt2d( 1, 1 )
+p4 = geom.Pnt2d( 1, 0 )
+
+line = mybase.addPolygon(p1, p2, p3, p4)
+
+mybase.setParallel( line[0].result(), line[2].result() )
+mybase.setParallel( line[1].result(), line[3].result() )
+mybase.setPerpendicular( line[0].result(), line[3].result() )
+
+mywidth = mybase.setLength( line[0].result(), 50 )
+mylength = mybase.setDistance( line[0].startPointData(),line[2].result(), 50 )
+
+
+# Creating the extrusion
+
+mybox = modeler.addExtrusion( mypart, mybase.selectFace(), 50 )
+
+
+# Creating a cylinder on a face of the box
+
+thisface = "Extrusion_1/LateralFace_2"
+thisxmin = "Extrusion_1/LateralFace_3|Extrusion_1/LateralFace_2"
+thiszmax = "Extrusion_1/LateralFace_2|Extrusion_1/TopFace_1"
+
+mystand = modeler.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 )
+
+
+# Subtracting the cylinder to the box
+
+modeler.addSubtraction( mypart, mybox.result(), myboss.result() )
+modeler.end()
+
+
+# Editing the box
+
+modeler.begin()
+mybase.setValue( mylength, 100 )
+mybox.setSize( 20 )
+modeler.end()
--- /dev/null
+# Creation of a box using the end-user API
+# Author: Daniel Brunier-Coulin
+# -----------------------------
+
+import modeler
+import extension
+
+
+# Initialisation
+
+modeler.begin()
+mypartset = modeler.moduleDocument()
+
+
+# Creating a new Part
+
+mypart = modeler.addPart(mypartset).document()
+
+
+# Creating the base of the box
+
+extension.addBox( mypart, 10, 20, 30 )
+modeler.end()
+
--- /dev/null
+"""User-defined features.
+"""
+
+from box import Box as addBox
\ No newline at end of file
--- /dev/null
+"""Box macro-feature Interface
+Author: Daniel Brunier-Coulin
+Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+"""
+
+import modeler
+from macros.box.feature import BoxFeature as MY
+
+
+class Box(modeler.Interface):
+ """Executes the macro-feature Box.
+ """
+ def __init__(self, part, dx, dy, dz):
+ modeler.Interface.__init__(self, part, MY.ID())
+
+ self.setRealInput( MY.WIDTH_ID(), dx )
+ self.setRealInput( MY.LENGTH_ID(), dy )
+ self.setRealInput( MY.HEIGHT_ID(), dz )
+
+ if self.areInputValid():
+ self.execute()
+ else:
+ raise Exception("cannot make the Box")
\ No newline at end of file
--- /dev/null
+"""This package defines the Direct Geometry API of the Modeler.
+"""
+
+# Swigged interfaces to Modeling Data
+
+from GeomAPI import GeomAPI_Circ as Circ
+from GeomAPI import GeomAPI_Circ2d as Circ2d
+from GeomAPI import GeomAPI_Dir as Dir
+from GeomAPI import GeomAPI_Lin as Lin
+from GeomAPI import GeomAPI_Lin2d as Lin2d
+from GeomAPI import GeomAPI_Pnt as Pnt
+from GeomAPI import GeomAPI_Pnt2d as Pnt2d
+from GeomAPI import GeomAPI_XY as XY
+from GeomAPI import GeomAPI_XYZ as XYZ
+
+from GeomAPI import GeomAPI_Shape as Shape
+
+
+# Swigged interfaces to Modeling Algorithms
+
+from GeomAlgoAPI import GeomAlgoAPI_Boolean as Boolean
+from GeomAlgoAPI import GeomAlgoAPI_Extrusion as Extrusion
+
+
+# Emulation of interfaces not yet swigged
+
+from missed import *
\ No newline at end of file
--- /dev/null
+# Direct Geometry API not yet swigged
+# Author: Daniel Brunier-Coulin
+# -----------------------------
+
+from GeomAPI import *
+
+
+class Ax3:
+
+ def __init__(self, origin, normal, dirx):
+ self.o = origin
+ self.n = normal
+ self.dx = dirx
+
+ def location (self):
+ return self.o
+
+ def direction (self):
+ return self.n
+
+ def xDirection (self):
+ return self.dx
+
+ def yDirection (self):
+ return self.n.cross(self.dx)
--- /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 import Sketch as 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
\ 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
+"""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.data().selectionList("base").append(sketch.result(), sketch.buildShape())
+ if size < 0:
+ self.my.data().boolean("reverse").setValue(True)
+ size = -size
+ else:
+ self.my.data().boolean("reverse").setValue(False)
+
+ self.my.data().real("size").setValue(size)
+
+ 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().boolean("reverse").setValue(True)
+ size = -size
+ else:
+ self.my.data().boolean("reverse").setValue(False)
+
+ self.my.data().real("size").setValue(size)
+ 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 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 *
+
+
+class Sketch():
+
+ def __init__(self, doc, plane):
+ """Initializes a 2D Sketch on the given plane and adds the Sketch to the given Part or Partset.
+ The plane can be defined either by:
+ - a 3D axis system (geom.Ax3),
+ - an existing face identified by its topological name.
+ """
+ self.my = featureToCompositeFeature( doc.addFeature("Sketch") )
+ self.selection = None # Entities used for building the result shape
+# self.resultype ="Face" # Type of Sketch result
+ if isinstance(plane, str):
+ self.__sketchOnFace(doc, plane)
+ else:
+ self.__sketchOnPlane(doc, plane)
+
+ def __sketchOnPlane (self, doc, plane):
+ o = plane.location()
+ d = plane.direction()
+ dx = plane.xDirection()
+ geomDataAPI_Point( self.my.data().attribute("Origin") ).setValue( o.x(), o.y(), o.z() )
+ geomDataAPI_Dir( self.my.data().attribute("DirX") ).setValue( dx.x(), dx.y(), dx.z() )
+ geomDataAPI_Dir( self.my.data().attribute("Norm") ).setValue( d.x(), d.y(), d.z() )
+
+ def __sketchOnFace (self, doc, plane):
+ self.my.data().selection("External").selectSubShape("FACE", plane)
+
+
+# Creation of Geometries
+
+ def addPoint (self, *args):
+ """Adds a point to this Sketch."""
+ return Point(self.my, *args)
+
+ def addLine (self, *args):
+ """Adds a line to this Sketch."""
+ return Line(self.my, *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]
+ pl = []
+ l1 = self.addLine(c0, c1)
+ pl.append(l1)
+ # Adding and connecting next lines
+ for c2 in coords[2:]:
+ l2 = self.addLine(c1, c2)
+ self.setCoincident( l1.endPointData(), l2.startPointData() )
+ pl.append(l2)
+ c1 = c2
+ l1 = l2
+ return pl
+
+ def addPolygon (self, *coords):
+ """Adds 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
+
+ def addCircle (self, *args):
+ """Adds a circle to this Sketch."""
+ return Circle(self.my, *args)
+
+
+# Creation of Geometrical and Dimensional Constraints
+
+ def setCoincident (self, p1, p2):
+ """Sets coincident the two given points and adds the corresponding constraint to this Sketch."""
+ constraint = self.my.addFeature("SketchConstraintCoincidence")
+ constraint.data().refattr("ConstraintEntityA").setAttr(p1)
+ constraint.data().refattr("ConstraintEntityB").setAttr(p2)
+ return constraint
+
+ def setParallel (self, l1, l2):
+ """Sets parallel the two given lines and adds the corresponding constraint to this Sketch."""
+ constraint = self.my.addFeature("SketchConstraintParallel")
+ constraint.data().refattr("ConstraintEntityA").setObject(l1)
+ constraint.data().refattr("ConstraintEntityB").setObject(l2)
+ return constraint
+
+ def setPerpendicular (self, l1, l2):
+ """Sets perpendicular the two given lines and adds the corresponding constraint to this Sketch."""
+ constraint = self.my.addFeature("SketchConstraintPerpendicular")
+ constraint.data().refattr("ConstraintEntityA").setObject(l1)
+ constraint.data().refattr("ConstraintEntityB").setObject(l2)
+ return constraint
+
+ def setDistance (self, point, line, length):
+ """Sets the distance between the given point and line, and adds the corresponding constraint to this Sketch."""
+ constraint = self.my.addFeature("SketchConstraintDistance")
+ if isinstance(line, str):
+ line = self.addLine(line).result() # Adds the edge identified by the given topological name to this Sketch
+ constraint.data().refattr("ConstraintEntityA").setAttr(point)
+ constraint.data().refattr("ConstraintEntityB").setObject(line)
+ constraint.data().real("ConstraintValue").setValue(length)
+ self.my.execute()
+ return constraint
+
+ def setLength (self, line, length):
+ """Sets the length of the given line and adds the corresponding constraint to this Sketch."""
+ constraint = self.my.addFeature("SketchConstraintLength")
+ constraint.data().refattr("ConstraintEntityA").setObject(line)
+ constraint.data().real("ConstraintValue").setValue(length)
+ return constraint
+
+ def setRadius (self, circle, radius):
+ """Sets the radius of the given circle and adds the corresponding constraint to this Sketch."""
+ constraint = self.my.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):
+ """Modifies the value of the given dimensional constraint."""
+ constraint.data().real("ConstraintValue").setValue(value)
+
+
+# Getters
+
+ def selectFace (self, *args):
+ """Selects 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.my.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.my.data().attribute("Origin") ).pnt()
+ dx = geomDataAPI_Dir( self.my.data().attribute("DirX") ).dir()
+ n = geomDataAPI_Dir( self.my.data().attribute("Norm") ).dir()
+
+ self.faces = ShapeList() # The faces are kept otherwise they are destroyed at exit
+ GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self.selection, self.faces)
+#TODO: Deal with several faces
+ return self.faces[0]
+
+ def result (self):
+ """Returns the result data of this Feature."""
+ return self.my.firstResult()
+
+
+# Class definitions of Sketch features
+
+class Point():
+
+ def __init__(self, sketch, x, y):
+ self.my = sketch.addFeature("SketchPoint")
+ geomDataAPI_Point2D( self.my.data().attribute("PointCoordindates") ).setValue(x, y)
+ self.my.execute()
+
+ def pointData (self):
+ return geomDataAPI_Point2D( self.my.data().attribute("PointCoordindates") )
+
+ def result (self):
+ return self.my.firstResult()
+
+
+class Line():
+
+ def __init__(self, sketch, *args):
+ self.my = sketch.addFeature("SketchLine")
+ 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):
+ geomDataAPI_Point2D( self.my.data().attribute("StartPoint") ).setValue(x1, y1)
+ geomDataAPI_Point2D( self.my.data().attribute("EndPoint") ).setValue(x2, y2)
+ self.my.execute()
+
+ def __createByPoints(self, p1, p2):
+ geomDataAPI_Point2D( self.my.data().attribute("StartPoint") ).setValue(p1.x(), p1.y())
+ geomDataAPI_Point2D( self.my.data().attribute("EndPoint") ).setValue(p2.x(), p2.y())
+ self.my.execute()
+
+ def __createByName(self, sketch, name):
+ self.my.data().selection("External").selectSubShape("EDGE", name)
+ self.my.execute()
+ rigid = sketch.addFeature("SketchConstraintRigid")
+ rigid.refattr("ConstraintEntityA").setObject( self.my.firstResult() )
+
+ def startPointData (self):
+ return geomDataAPI_Point2D( self.my.data().attribute("StartPoint") )
+
+ def endPointData (self):
+ return geomDataAPI_Point2D( self.my.data().attribute("EndPoint") )
+
+ def result (self):
+ return self.my.firstResult()
+
+
+class Circle():
+
+ def __init__(self, sketch, x, y, r):
+ self.my = sketch.addFeature("SketchCircle")
+ geomDataAPI_Point2D( self.my.data().attribute("CircleCenter") ).setValue(x, y)
+ self.my.data().real("CircleRadius").setValue(r)
+ self.my.execute()
+
+ def centerData (self):
+ return geomDataAPI_Point2D( self.my.data().attribute("CircleCenter") )
+
+ def result (self):
+ return self.my.lastResult() # Returns the circular line attribute
+
+
--- /dev/null
+## Copyright (C) 2014-20xx OPEN CASCADE
+
+
+SET(CMAKE_AUTOMOC ON)
+
+INSTALL(FILES addons_Features.py addons_Features.xml DESTINATION plugins)
+
+
+INSTALL(FILES __init__.py DESTINATION addons)
+INSTALL(DIRECTORY macros DESTINATION addons)
--- /dev/null
+"""User-defined features"""
\ No newline at end of file
--- /dev/null
+"""Registration of all user-defined Python features
+"""
+
+import ModelAPI
+from macros.box.feature import BoxFeature
+from macros.cylinder.feature import CylinderFeature
+
+
+class PythonFeaturesPlugin(ModelAPI.ModelAPI_Plugin):
+
+ def __init__(self):
+ ModelAPI.ModelAPI_Plugin.__init__(self)
+ aSession = ModelAPI.ModelAPI_Session.get()
+ aSession.registerPlugin(self)
+ pass
+
+ def createFeature(self, theFeatureID):
+ aFeature = None
+
+ if theFeatureID == BoxFeature.ID():
+ aFeature = BoxFeature().__disown__()
+
+ elif theFeatureID == CylinderFeature.ID():
+ aFeature = CylinderFeature().__disown__()
+
+ else:
+ raise StandardError("No such feature %s" % theFeatureID)
+
+ return aFeature
+
+
+plugin = PythonFeaturesPlugin()
+plugin.__disown__()
--- /dev/null
+<plugin>
+ <source path="../addons/macros/box/widget.xml"/>
+ <source path="../addons/macros/cylinder/widget.xml"/>
+</plugin>
--- /dev/null
+"""Python macro-features package
+A macro-feature is a feature which executes a sequence of user actions.
+Such feature is not registered in the application history. Instead,
+only the operations it encapsulates are registered.
+For editing the result of such feature, the user edits the operations
+used in the macro-feature.
+"""
\ No newline at end of file
--- /dev/null
+"""Box macro-feature
+Authors: Renaud Nedelec - Daniel Brunier-Coulin
+Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+"""
+
+import modeler
+import geom
+
+
+class BoxFeature(modeler.Feature):
+
+
+# Initializations
+
+ def __init__(self):
+ modeler.Feature.__init__(self)
+
+ @staticmethod
+ def ID():
+ return "Box"
+
+ @staticmethod
+ def WIDTH_ID():
+ return "width"
+
+ @staticmethod
+ def LENGTH_ID():
+ return "length"
+
+ @staticmethod
+ def HEIGHT_ID():
+ return "height"
+
+ def getKind(self):
+ return BoxFeature.ID()
+
+
+# Creation of the box at default size
+
+ def initAttributes(self):
+
+ # Creating the input arguments of the feature
+ self.addRealInput( self.WIDTH_ID() )
+ self.addRealInput( self.LENGTH_ID() )
+ self.addRealInput( self.HEIGHT_ID() )
+
+ # Creating the base of the box with unit values
+ mypart = modeler.activeDocument()
+ xoy = modeler.defaultPlane("XOY")
+
+ self.base = modeler.addSketch( mypart, xoy )
+
+ p1 = geom.Pnt2d( 0, 0 )
+ p2 = geom.Pnt2d( 0, 1 )
+ p3 = geom.Pnt2d( 1, 1 )
+ p4 = geom.Pnt2d( 1, 0 )
+
+ line = self.base.addPolygon(p1, p2, p3, p4)
+
+ self.base.setParallel( line[0].result(), line[2].result() )
+ self.base.setParallel( line[1].result(), line[3].result() )
+ self.base.setPerpendicular( line[0].result(), line[3].result() )
+
+ # Setting the size of the base with default values
+ self.width = self.base.setLength( line[0].result(), 50 ) # Keeps the constraint for edition
+ self.length = self.base.setLength( line[3].result(), 50 ) # Keeps the constraint for edition
+
+ # Creating the extrusion (the box) at default size
+ self.box = modeler.addExtrusion( mypart, self.base.selectFace(), 50 )
+
+
+# Edition of the box at user size
+
+ def execute(self):
+ # Retrieving the user inputs
+ width = self.getRealInput( self.WIDTH_ID() )
+ length = self.getRealInput( self.LENGTH_ID() )
+ height = self.getRealInput( self.HEIGHT_ID() )
+
+ # Editing the box
+ self.base.setValue( self.width, width )
+ self.base.setValue( self.length, length )
+ self.box.setSize( height )
+
+ # Publishing the result
+ self.addResult( self.box.result() )
+
+
+
--- /dev/null
+<source>
+ <workbench id="Macros" document="Part">
+ <group id="Samples">
+
+ <feature id="Box" title="Box" tooltip="Creates a box parallel to XYZ by extruding a rectangle" icon=":pictures/part_ico.png">
+ <doublevalue id="width" label="dx: " min="0" step="1.0" default="50" tooltip="Sets the box width">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ <doublevalue id="length" label="dy: " min="0" step="1.0" default="50" tooltip="Sets the box length">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ <doublevalue id="height" label="dz: " min="0" step="1.0" default="50" tooltip="Sets the box height">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </feature>
+
+ </group>
+ </workbench>
+</source>
--- /dev/null
+"""Cylinder macro-feature
+Authors: Daniel Brunier-Coulin
+Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+"""
+
+import modeler
+import geom
+
+
+class CylinderFeature(modeler.Feature):
+
+
+# Initializations
+
+ def __init__(self):
+ modeler.Feature.__init__(self)
+
+ @staticmethod
+ def ID():
+ return "Cylinder"
+
+ @staticmethod
+ def RADIUS_ID():
+ return "radius"
+
+ @staticmethod
+ def LENGTH_ID():
+ return "length"
+
+ def getKind(self):
+ return CylinderFeature.ID()
+
+
+# Creation of the cylinder at default size
+
+ def initAttributes(self):
+
+ # Creating the input arguments of the feature
+ self.addRealInput( self.RADIUS_ID() )
+ self.addRealInput( self.LENGTH_ID() )
+
+ # Creating the base of the cylinder with unit values
+ mypart = modeler.activeDocument()
+ xoy = modeler.defaultPlane("XOY")
+
+ self.base = modeler.addSketch( mypart, xoy )
+ circle = self.base.addCircle( 0, 0, 1)
+
+ # Setting the radius of the base with default values
+ self.radius = self.base.setRadius( circle.result(), 10 ) # Keeps the constraint for edition
+
+ # Creating the extrusion (the cylinder) at default size
+ self.cyl = modeler.addExtrusion( mypart, self.base.selectFace(), 50 )
+
+
+# Edition of the cylinder at user size
+
+ def execute(self):
+ # Retrieving the user inputs
+ radius = self.getRealInput( self.RADIUS_ID() )
+ length = self.getRealInput( self.LENGTH_ID() )
+
+ # Editing the cylinder
+ self.base.setValue( self.radius, radius )
+ self.cyl.setSize( length )
+
+ # Publishing the result
+ self.addResult( self.cyl.result() )
\ No newline at end of file
--- /dev/null
+<source>
+ <workbench id="Macros" document="Part">
+ <group id="Samples">
+
+ <feature id="Cylinder" title="Cylinder" tooltip="Creates a cylinder on the Z axis by extruding a circle" icon=":pictures/part_ico.png">
+ <doublevalue id="radius" label="Radius: " min="0" step="1.0" default="10" tooltip="Sets the cylinder radius">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ <doublevalue id="length" label="Length: " min="0" step="1.0" default="50" tooltip="Sets the cylinder length">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </feature>
+
+ </group>
+ </workbench>
+</source>
+++ /dev/null
-INCLUDE(Common)
-
-SET(PYTHON_FILES
- PythonFeaturesPlugin_Box.py
- PythonFeaturesPlugin.py
- sketch.py
- extrusion.py
- examples.py
- SketchResult.py
-)
-
-SET(XML_RESSOURCES
- plugin-PythonFeatures.xml
- box_widget.xml
-)
-
-INSTALL(FILES ${PYTHON_FILES} ${XML_RESSOURCES} DESTINATION plugins)
+++ /dev/null
-from ModelAPI import *
-from GeomDataAPI import *
-from GeomAlgoAPI import *
-
-# NOTE : I think this style should be chosen
-# for function as recommended by Python programming
-# standards
-
-
-def build_face_from_sketch(sketch, edges=None):
- # If no edges have been selected, get the whole sketch
- # edges
- if edges == None:
- result = sketch.firstResult()
- edges = modelAPI_ResultConstruction(result).shape()
-
- # Build the face
- origin = geomDataAPI_Point(sketch.attribute("Origin")).pnt()
- dirX = geomDataAPI_Dir(sketch.attribute("DirX")).dir()
- dirY = geomDataAPI_Dir(sketch.attribute("DirY")).dir()
- normal = geomDataAPI_Dir(sketch.attribute("Norm")).dir()
- faces = ShapeList()
- GeomAlgoAPI_SketchBuilder.createFaces(
- origin, dirX, dirY, normal, edges, faces)
- return faces[0]
-
-# NOTE : with an optional argument it is not
-# a so good idea to put part as last argument
-# it would result in a mandatory argument
-# put after an optionnal one
-
-
-def addExtrusion(part, sketch, size, reverse=False, subshapes=None):
- feature = part.addFeature("Extrusion")
-
- # Build apropriate face
- face = build_face_from_sketch(sketch, subshapes)
- # Get sketch result
- sketchResult = sketch.firstResult()
-
- # Set attributes and execute the feature
- feature.selection("extrusion_face").setValue(sketchResult, face)
- feature.real("extrusion_size").setValue(size)
- feature.boolean("extrusion_reverse").setValue(False)
- feature.execute()
-
- return feature
+++ /dev/null
-"""
-"""
-
-import ModelAPI
-from PythonFeaturesPlugin_Box import PythonFeaturesPlugin_Box
-
-
-class PythonFeaturesPlugin(ModelAPI.ModelAPI_Plugin):
-
- def __init__(self):
- ModelAPI.ModelAPI_Plugin.__init__(self)
- aSession = ModelAPI.ModelAPI_Session.get()
- aSession.registerPlugin(self)
- pass
-
- def createFeature(self, theFeatureID):
- aFeature = None
- if theFeatureID == PythonFeaturesPlugin_Box.ID():
- aCompositeFeature = PythonFeaturesPlugin_Box().__disown__()
- aFeature = ModelAPI.compositeFeatureToFeature(aCompositeFeature)
- else:
- raise StandardError("No such feature %s" % theFeatureID)
- return aFeature
-
-
-plugin = PythonFeaturesPlugin()
-plugin.__disown__()
+++ /dev/null
-import ModelAPI
-
-from SketchResult import SketchResult
-import extrusion
-import sketch
-
-
-class PythonFeaturesPlugin_Box(ModelAPI.ModelAPI_CompositeFeature):
- """Feature to create a box by drawing a sketch and extruding it
- """
-
- def __init__(self):
- ModelAPI.ModelAPI_CompositeFeature.__init__(self)
-
- @staticmethod
- def ID():
- return "Box"
-
- @staticmethod
- def WIDTH_ID():
- return "box_width"
-
- @staticmethod
- def LENGTH_ID():
- return "box_length"
-
- @staticmethod
- def HEIGHT_ID():
- return "box_height"
-
- @staticmethod
- def WIDTH_REF_ID():
- return "box_ref_width"
-
- @staticmethod
- def LENGTH_REF_ID():
- return "box_ref_length"
-
- @staticmethod
- def HEIGHT_REF_ID():
- return "box_ref_height"
-
- def getKind(self):
- return PythonFeaturesPlugin_Box.ID()
-
- def initAttributes(self):
- # C++ static methods (in example "type()" of the ModelAPI_AttributeDouble
- # should be called like this: moduleName.ClassName_staticMethod()
- self.data().addAttribute(self.WIDTH_ID(), ModelAPI.ModelAPI_AttributeDouble_typeId())
- self.data().addAttribute(self.LENGTH_ID(), ModelAPI.ModelAPI_AttributeDouble_typeId())
- self.data().addAttribute(self.HEIGHT_ID(), ModelAPI.ModelAPI_AttributeDouble_typeId())
- self.data().addAttribute(self.WIDTH_REF_ID(), ModelAPI.ModelAPI_AttributeReference_typeId())
- self.data().addAttribute(self.LENGTH_REF_ID(), ModelAPI.ModelAPI_AttributeReference_typeId())
- self.data().addAttribute(self.HEIGHT_REF_ID(), ModelAPI.ModelAPI_AttributeReference_typeId())
- aSession = ModelAPI.ModelAPI_Session.get()
- aSession.validators().registerNotObligatory(self.getKind(), self.WIDTH_REF_ID())
- aSession.validators().registerNotObligatory(self.getKind(), self.LENGTH_REF_ID())
- aSession.validators().registerNotObligatory(self.getKind(), self.HEIGHT_REF_ID())
- aSession.validators().registerConcealment(self.getKind(), self.HEIGHT_REF_ID())
- self.mySketch = None # not yet initialized
- self.myExtrusion = None # not yet initialized
-
- def execute(self):
- aWidth = self.real(self.WIDTH_ID()).value()
- aLength = self.real(self.LENGTH_ID()).value()
- aHeight = self.real(self.HEIGHT_ID()).value()
- aWidthRefValue = self.reference(self.WIDTH_REF_ID()).value()
- aLengthRefValue = self.reference(self.LENGTH_REF_ID()).value()
- aHeightRefValue = self.reference(self.HEIGHT_REF_ID()).value()
- aResult = None
- if not all((aWidthRefValue, aLengthRefValue, aHeightRefValue)):
- aResult = extrusion.getBody(self.makeBox(aLength, aWidth, aHeight))
- else:
- aHeightProxyResult = ModelAPI.modelAPI_Result(aHeightRefValue)
- aWidthFeature = ModelAPI.objectToFeature(aWidthRefValue)
- aLengthFeature = ModelAPI.objectToFeature(aLengthRefValue)
- aHeightResult = ModelAPI.modelAPI_ResultBody(aHeightProxyResult)
- aWidthFeature.real("ConstraintValue").setValue(aWidth)
- aLengthFeature.real("ConstraintValue").setValue(aLength)
- if aHeightResult is not None:
- aHeightFeature = aHeightResult.document().feature(aHeightResult)
- aHeightFeature.real("extrusion_size").setValue(aHeight)
- aResult = extrusion.getBody(aHeightFeature)
- # create a new result with copied shape from extrusion
- aResultBody = self.document().createBody(self.data())
- if not aResult is None:
- aResultBody.store(aResult.shape())
- self.setResult(aResultBody)
- pass
-
- def makeBox(self, aWidth, aLength, aHeight):
- aSession = ModelAPI.ModelAPI_Session.get()
- aPart = aSession.activeDocument()
- # Starting the Sketch
- aSketch = sketch.addTo(aPart)
- self.mySketch = aSketch
- sketch.setXOYPlane(aSketch)
- # Creating the lines
- l1 = sketch.addLine(10, 10, 10, 60, aSketch)
- l2 = sketch.addLine(10, 60, 60, 60, aSketch)
- l3 = sketch.addLine(60, 60, 60, 10, aSketch)
- l4 = sketch.addLine(60, 10, 10, 10, aSketch)
- aSketch.execute()
- # Creating the constraints
- sketch.makeCoincident(sketch.getEndPoint(l1), sketch.getStartPoint(l2), aSketch)
- sketch.makeCoincident(sketch.getEndPoint(l2), sketch.getStartPoint(l3), aSketch)
- sketch.makeCoincident(sketch.getEndPoint(l3), sketch.getStartPoint(l4), aSketch)
- sketch.makeCoincident(sketch.getEndPoint(l4), sketch.getStartPoint(l1), aSketch)
- sketch.makeParallel(sketch.getGeometry(l1), sketch.getGeometry(l3), aSketch)
- sketch.makeParallel(sketch.getGeometry(l2), sketch.getGeometry(l4), aSketch)
- sketch.makePerpendicular(sketch.getGeometry(l1), sketch.getGeometry(l4), aSketch)
- # Set to 0X and 0Y lines defined length
- aWidthFeature = sketch.makeConstantLength(sketch.getGeometry(l4), aWidth, aSketch)
- aLengthFeature = sketch.makeConstantLength(sketch.getGeometry(l1), aLength, aSketch)
- # Finalisation of the operation
- builder = SketchResult(aSketch)
- # Creating a feature Extrusion
- aHeightFeature = extrusion.addNew(builder, aHeight, aPart)
- self.myExtrusion = aHeightFeature
- # Store features...
- self.reference(self.WIDTH_REF_ID()).setValue(aWidthFeature)
- self.reference(self.LENGTH_REF_ID()).setValue(aLengthFeature)
- self.reference(self.HEIGHT_REF_ID()).setValue(aHeightFeature.firstResult())
- return aHeightFeature
-
- def addFeature(self, theID):
- pass
-
- def numberOfSubs(self):
- subsCount = 0
- if not self.mySketch is None:
- subsCount += 1
- if not self.myExtrusion is None:
- subsCount += 1
- # extrusion and sketch
- return subsCount
-
- def subFeature(self, theIndex):
- if theIndex == 0: # sketch
- return ModelAPI.compositeFeatureToFeature(self.mySketch)
- return self.myExtrusion
-
- def subFeatureId(self, theIndex):
- return 0
-
- def isSub(self, theFeature):
- return theFeature == self.mySketch or theFeature == self.myExtrusion
-
- def attributeChanged(self, theAttrID):
- # on update of attributes values, transfer them to sub-features immideately to see good preview
- # otherwise these features will be executed before execute of "Box" and with old parameters
- aWidthRefValue = self.reference(self.WIDTH_REF_ID()).value()
- aLengthRefValue = self.reference(self.LENGTH_REF_ID()).value()
- aHeightRefValue = self.reference(self.HEIGHT_REF_ID()).value()
- if all((aWidthRefValue, aLengthRefValue, aHeightRefValue)):
- self.execute()
-
-# TEST
-"""
-if __name__=='__main__':
- session = ModelAPI.ModelAPI_Session.get()
- part = session.activeDocument()
- session.startOperation()
- feature = part.addFeature('Box')
- feature.real('box_width').setValue(10)
- feature.real('box_length').setValue(10)
- feature.real('box_height').setValue(10)
- feature.execute()
- session.finishOperation()
-"""
+++ /dev/null
-from ModelAPI import *
-from GeomDataAPI import *
-from GeomAlgoAPI import *
-
-
-class SketchResult:
-
- def __init__(self, sketch):
- self.geom = sketch.firstResult()
- self.faces = ShapeList()
- self.edges = modelAPI_ResultConstruction(self.geom).shape()
- self.origin = geomDataAPI_Point(sketch.attribute("Origin")).pnt()
- self.dirX = geomDataAPI_Dir(sketch.attribute("DirX")).dir()
- self.dirY = geomDataAPI_Dir(sketch.attribute("DirY")).dir()
- self.normal = geomDataAPI_Dir(sketch.attribute("Norm")).dir()
-
- def setEdges(self, edges):
- self.edges = edges
-
- def geometry(self):
- return self.geom
-
- def face(self):
- GeomAlgoAPI_SketchBuilder.createFaces(
- self.origin, self.dirX, self.dirY, self.normal, self.edges, self.faces)
- return self.faces[0]
+++ /dev/null
-<source>
- <doublevalue id="box_width" label="Width" min="0" step="1.0" default="50" icon=":icons/dimension_v.png" tooltip="Set width of the box">
- <validator id="GeomValidators_Positive"/>
- </doublevalue>
- <doublevalue id="box_length" label="Length" min="0" step="1.0" default="50" icon=":icons/dimension_v.png" tooltip="Set length of the box">
- <validator id="GeomValidators_Positive"/>
- </doublevalue>
- <doublevalue id="box_height" label="Height" min="0" step="1.0" default="50" icon=":icons/dimension_v.png" tooltip="Set height of the box">
- <validator id="GeomValidators_Positive"/>
- </doublevalue>
-</source>
+++ /dev/null
-from ModelAPI import *
-from SketchResult import *
-import sketch
-import extrusion
-# reload(sketch) # Pour tester plus facilement
-# reload(extrusion) # Pour tester plus facilement
-
-
-def makeBox(aLength, aWidth, aHeight):
- # Getting the active document
- session = ModelAPI_Session.get()
- part = session.activeDocument()
-
- # Starting the Sketch
- base = sketch.addTo(part)
- sketch.setXOYPlane(base)
-
- # Creating the lines
- l1 = sketch.addLine(10, 10, 10, 50, base)
- l2 = sketch.addLine(10, 50, 60, 60, base)
- l3 = sketch.addLine(60, 60, 50, 10, base)
- l4 = sketch.addLine(50, 10, 10, 10, base)
- base.execute()
-
- # Creating the constraints
- sketch.makeCoincident(sketch.getEndPoint(l1),
- sketch.getStartPoint(l2), base)
- sketch.makeCoincident(sketch.getEndPoint(l2),
- sketch.getStartPoint(l3), base)
- sketch.makeCoincident(sketch.getEndPoint(l3),
- sketch.getStartPoint(l4), base)
- sketch.makeCoincident(sketch.getEndPoint(l4),
- sketch.getStartPoint(l1), base)
-
- sketch.makeParallel(sketch.getGeometry(l1), sketch.getGeometry(l3), base)
- sketch.makeParallel(sketch.getGeometry(l2), sketch.getGeometry(l4), base)
-
- sketch.makePerpendicular(sketch.getGeometry(l1),
- sketch.getGeometry(l4), base)
- # Set to 0X and 0Y lines defined length
- sketch.makeConstantLength(sketch.getGeometry(l1), aLength, base)
- sketch.makeConstantLength(sketch.getGeometry(l4), aWidth, base)
-
- # Finalisation of the operation
- builder = SketchResult(base)
-
- # Creating a feature Extrusion
- box = extrusion.addNew(builder, aHeight, part)
-
- # return base.lastResult()
- return extrusion.getBody(box)
+++ /dev/null
-from ModelAPI import *
-
-
-def addNew(builder, length, part, edges=None, reverse=False):
- feature = part.addFeature("Extrusion")
- feature.selection("extrusion_face").setValue(builder.geometry(),
- builder.face())
- if length < 0.0000001:
- length = 50
- feature.real("extrusion_size").setValue(length)
- feature.boolean("extrusion_reverse").setValue(reverse)
- feature.execute()
- return feature
-
-
-def getBody(extrusion):
- return modelAPI_ResultBody(extrusion.firstResult())
+++ /dev/null
-<plugin>
- <workbench id="Features" document="Part">
- <group id="Basic">
- <feature id="Box" title="Box" tooltip="Create a box" icon=":pictures/part_ico.png">
- <source path="box_widget.xml"/>
- </feature>
- </group>
- </workbench>
-</plugin>
+++ /dev/null
-from ModelAPI import *
-from GeomDataAPI import *
-
-
-# Initialization of the Sketch
-# ----------------------------
-
-def addTo(doc):
- return featureToCompositeFeature(doc.addFeature("Sketch"))
-
-
-def setXOYPlane(sketch):
- geomDataAPI_Point(sketch.attribute("Origin")).setValue(0, 0, 0)
- geomDataAPI_Dir(sketch.attribute("DirX")).setValue(1, 0, 0)
- geomDataAPI_Dir(sketch.attribute("DirY")).setValue(0, 1, 0)
- geomDataAPI_Dir(sketch.attribute("Norm")).setValue(0, 0, 1)
-
-
-# Point geometry
-# --------------
-
-def addPoint(x, y, sketch):
- point = sketch.addFeature("SketchPoint")
- geomDataAPI_Point2D(point.attribute("PointCoordindates")).setValue(x, y)
- # Required to get the result, if needed for creating constraints
- point.execute()
- return point
-
-
-def getGeometry(point):
- return geomDataAPI_Point2D(point.attribute("PointCoordindates"))
-
-
-# Line geometry
-# -------------
-
-def addClosedBrokenLine(coords, sketch):
- c0 = coords[0]
- c1 = coords[1]
- bl = []
- l1 = sketch.addFeature("SketchLine")
- geomDataAPI_Point2D(l1.attribute("StartPoint")).setValue(c0.x(), c0.y())
- geomDataAPI_Point2D(l1.attribute("EndPoint")).setValue(c1.x(), c1.y())
- l1.execute()
- bl.append(l1)
- l0 = l1
-
- for c2 in coords[2:]:
- l2 = sketch.addFeature("SketchLine")
- geomDataAPI_Point2D(
- l2.attribute("StartPoint")).setValue(c1.x(), c1.y())
- geomDataAPI_Point2D(l2.attribute("EndPoint")).setValue(c2.x(), c2.y())
- l2.execute()
- bl.append(l2)
- constraint = sketch.addFeature("SketchConstraintCoincidence")
- constraint.refattr("ConstraintEntityA").setAttr(
- l1.attribute("EndPoint"))
- constraint.refattr("ConstraintEntityB").setAttr(
- l2.attribute("StartPoint"))
- c1 = c2
- l1 = l2
-
- if len(coords) > 2:
- l2 = sketch.addFeature("SketchLine")
- geomDataAPI_Point2D(
- l2.attribute("StartPoint")).setValue(c1.x(), c1.y())
- geomDataAPI_Point2D(l2.attribute("EndPoint")).setValue(c0.x(), c0.y())
- l2.execute()
- bl.append(l2)
- constraint = sketch.addFeature("SketchConstraintCoincidence")
- constraint.refattr("ConstraintEntityA").setAttr(
- l1.attribute("EndPoint"))
- constraint.refattr("ConstraintEntityB").setAttr(
- l2.attribute("StartPoint"))
-
- constraint = sketch.addFeature("SketchConstraintCoincidence")
- constraint.refattr("ConstraintEntityA").setAttr(
- l2.attribute("EndPoint"))
- constraint.refattr("ConstraintEntityB").setAttr(
- l0.attribute("StartPoint"))
-
- return bl
-
-
-def addLine(x1, y1, x2, y2, sketch):
- line = sketch.addFeature("SketchLine")
- geomDataAPI_Point2D(line.attribute("StartPoint")).setValue(x1, y1)
- geomDataAPI_Point2D(line.attribute("EndPoint")).setValue(x2, y2)
- # Required to get the result, if needed for creating constraints
- line.execute()
- return line
-
-
-def getGeometry(line):
- return modelAPI_ResultConstruction(line.firstResult())
-
-
-def getStartPoint(line):
- return geomDataAPI_Point2D(line.attribute("StartPoint"))
-
-
-def getEndPoint(line):
- return geomDataAPI_Point2D(line.attribute("EndPoint"))
-
-
-# Constraints
-# -----------
-
-def makeCoincident(p1, p2, sketch):
- constraint = sketch.addFeature("SketchConstraintCoincidence")
- constraint.refattr("ConstraintEntityA").setAttr(p1)
- constraint.refattr("ConstraintEntityB").setAttr(p2)
- return constraint
-
-
-def makeParallel(l1, l2, sketch):
- constraint = sketch.addFeature("SketchConstraintParallel")
- constraint.refattr("ConstraintEntityA").setObject(l1)
- constraint.refattr("ConstraintEntityB").setObject(l2)
- return constraint
-
-
-def makePerpendicular(l1, l2, sketch):
- constraint = sketch.addFeature("SketchConstraintPerpendicular")
- constraint.refattr("ConstraintEntityA").setObject(l1)
- constraint.refattr("ConstraintEntityB").setObject(l2)
- return constraint
-
-
-def makeConstantLength(line, length, sketch):
- constraint = sketch.addFeature("SketchConstraintLength")
- constraint.refattr("ConstraintEntityA").setObject(line)
- constraint.real("ConstraintValue").setValue(length)
- return constraint