ADD_SUBDIRECTORY (src/PartSetPlugin)
ADD_SUBDIRECTORY (src/ConstructionPlugin)
ADD_SUBDIRECTORY (src/FeaturesPlugin)
+ADD_SUBDIRECTORY (src/PythonFeaturesPlugin)
ADD_SUBDIRECTORY (src/SketchPlugin)
ADD_SUBDIRECTORY (src/SketchSolver)
ADD_SUBDIRECTORY (src/ModuleBase)
#------ 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:${PYTHONPATH}
+export PYTHONPATH=${NEWGEOM_ROOT_DIR}/swig:${NEWGEOM_ROOT_DIR}/plugins:${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
+
@SET NEW_GEOM_CONFIG_FILE=%ROOT_DIR%\install\plugins
@SET PATH=%ROOT_DIR%\install\plugins;%ROOT_DIR%\install\bin;%PATH%
-@SET PYTHONPATH=%ROOT_DIR%\install\swig;%PYTHONPATH%
+@SET PYTHONPATH=%ROOT_DIR%\install\swig;%ROOT_DIR%\install\plugins;%PYTHONPATH%
@REM -------------------------
@REM PTHREAD
INCLUDE(Common)
INCLUDE(XMLProcessing)
-INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Events)
+INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Events
+ ${PYTHON_INCLUDE_DIRS})
SET(PROJECT_HEADERS
Config_def.h
SET(PROJECT_LIBRARIES
Events
${LIBXML2_LIBRARIES}
+ ${PYTHON_LIBRARIES}
)
SOURCE_GROUP ("Resource Files" FILES ${XML_RESOURCES})
/*
* Hardcoded xml entities of plugins.xml
*/
+
+const static char* PLUGIN_FILE = "plugins.xml";
const static char* NODE_PLUGIN = "plugin";
const static char* NODE_PLUGINS = "plugins";
const static char* PLUGINS_MODULE = "module";
const static char* PLUGIN_CONFIG = "configuration";
const static char* PLUGIN_LIBRARY = "library";
+const static char* PLUGIN_SCRIPT = "script";
#endif /* CONFIG_KEYWORDS_H_ */
#include <libxml/parser.h>
#include <libxml/tree.h>
+// Have to be included before std headers
+#include <Python.h>
+
//Necessary for cerr
#include <iostream>
#include <dlfcn.h>
#endif
+std::map<std::string, Config_ModuleReader::PluginType> Config_ModuleReader::myPluginTypes;
+
Config_ModuleReader::Config_ModuleReader(const char* theEventGenerated)
- : Config_XMLReader("plugins.xml"),
+ : Config_XMLReader(PLUGIN_FILE),
myEventGenerated(theEventGenerated)
{
}
if (isNode(theNode, NODE_PLUGIN, NULL)) {
std::string aPluginConf = getProperty(theNode, PLUGIN_CONFIG);
std::string aPluginLibrary = getProperty(theNode, PLUGIN_LIBRARY);
- std::list<std::string> aFeatures = importPlugin(aPluginLibrary, aPluginConf);
+ std::string aPluginScript = getProperty(theNode, PLUGIN_SCRIPT);
+ std::string aPluginName = addPlugin(aPluginLibrary, aPluginScript, aPluginConf);
+
+ std::list<std::string> aFeatures = importPlugin(aPluginName, aPluginConf);
std::list<std::string>::iterator it = aFeatures.begin();
for (; it != aFeatures.end(); it++) {
myFeaturesInFiles[*it] = aPluginConf;
}
std::list<std::string> Config_ModuleReader::importPlugin(const std::string& thePluginLibrary,
- const std::string& thePluginFile)
+ const std::string& thePluginXmlConf)
{
- if (thePluginFile.empty()) { //probably a third party library
+ if (thePluginXmlConf.empty()) { //probably a third party library
loadLibrary(thePluginLibrary);
return std::list<std::string>();
}
- Config_FeatureReader aReader = Config_FeatureReader(thePluginFile, thePluginLibrary,
+ Config_FeatureReader aReader = Config_FeatureReader(thePluginXmlConf,
+ thePluginLibrary,
myEventGenerated);
aReader.readAll();
return aReader.features();
}
+std::string Config_ModuleReader::addPlugin(const std::string& aPluginLibrary,
+ const std::string& aPluginScript,
+ const std::string& aPluginConf)
+{
+ PluginType aType = PluginType::Binary;
+ std::string aPluginName;
+ if (!aPluginLibrary.empty()) {
+ aPluginName = aPluginLibrary;
+ if (aPluginConf.empty()) {
+ aType = PluginType::Intrenal;
+ }
+ } else if (!aPluginScript.empty()) {
+ aPluginName = aPluginScript;
+ aType = PluginType::Python;
+ }
+ if(!aPluginName.empty()) {
+ myPluginTypes[aPluginName] = aType;
+
+ }
+ return aPluginName;
+}
+
+void Config_ModuleReader::loadPlugin(const std::string thePluginName)
+{
+ PluginType aType = PluginType::Binary;
+ if(myPluginTypes.find(thePluginName) != myPluginTypes.end()) {
+ aType = myPluginTypes.at(thePluginName);
+ }
+ switch (aType) {
+ case PluginType::Python:
+ loadScript(thePluginName);
+ break;
+ case PluginType::Binary:
+ case PluginType::Intrenal:
+ default:
+ loadLibrary(thePluginName);
+ break;
+ }
+}
+
+void Config_ModuleReader::loadScript(const std::string theFileName)
+{
+ std::string aPythonFile = theFileName + ".py";
+ /* aquire python thread */
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ PyObject* module = PyImport_ImportModule(aPythonFile.c_str());
+ /* release python thread */
+ PyGILState_Release(gstate);
+}
+
void Config_ModuleReader::loadLibrary(const std::string theLibName)
{
std::string aFileName = library(theLibName);
#ifdef WIN32
HINSTANCE aModLib = ::LoadLibrary(aFileName.c_str());
- if (!aModLib && theLibName != "DFBrowser") { // don't shor error for internal debugging tool
- std::string errorMsg = "Failed to load " + aFileName;
- std::cerr << errorMsg << std::endl;
- Events_Error::send(errorMsg);
- }
#else
void* aModLib = dlopen( aFileName.c_str(), RTLD_LAZY | RTLD_GLOBAL );
- if ( !aModLib && theLibName != "DFBrowser") { // don't shor error for internal debugging tool
- std::cerr << "Failed to load " << aFileName.c_str() << std::endl;
- }
#endif
+ if(!aModLib && theLibName != "DFBrowser") { // don't show error for internal debugging tool
+ std::string anErrorMsg = "Failed to load " + aFileName;
+ #ifndef WIN32
+ anErrorMsg += ": " + std::string(dlerror());
+ #endif
+ Events_Error::send(anErrorMsg);
+ }
}
class Config_ModuleReader : public Config_XMLReader
{
+ enum PluginType {
+ Binary = 0,
+ Intrenal = 1,
+ Python = 2
+ };
public:
- CONFIG_EXPORT Config_ModuleReader(const char* theEventGenerated = 0);CONFIG_EXPORT virtual ~Config_ModuleReader();
+ CONFIG_EXPORT Config_ModuleReader(const char* theEventGenerated = 0);
+ CONFIG_EXPORT virtual ~Config_ModuleReader();
CONFIG_EXPORT const std::map<std::string, std::string>& featuresInFiles() const;
CONFIG_EXPORT std::string getModuleName();
+ CONFIG_EXPORT static void loadPlugin(const std::string thePluginName);
/// loads the library with specific name, appends "lib*.dll" or "*.so" depending on the platform
CONFIG_EXPORT static void loadLibrary(const std::string theLibName);
+ /// loads the python module with specified name
+ CONFIG_EXPORT static void loadScript(const std::string theFileName);
protected:
void processNode(xmlNodePtr aNode);
std::list<std::string> importPlugin(const std::string& thePluginLibrary,
const std::string& thePluginFile);
+ std::string addPlugin(const std::string& aPluginLibrary,
+ const std::string& aPluginScript,
+ const std::string& aPluginConf);
private:
std::map<std::string, std::string> myFeaturesInFiles;
+ static std::map<std::string, PluginType> myPluginTypes;
const char* myEventGenerated;
};
<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 library="SketchSolver"/>
<plugin library="GeomValidators"/>
- <plugin library="DFBrowser"/>
+ <plugin library="DFBrowser" internal="true"/>
</plugins>
virtual FeaturePtr createFeature(std::string theFeatureID);
public:
- /// Is needed for python wrapping by swig
ConstructionPlugin_Plugin();
};
std::shared_ptr<Events_Message> aGroup = aMyGroup->second;
myGroups.erase(aMyGroup);
send(aGroup, false);
- myFlushed.erase(myFlushed.find(theID.myID));
+ std::set<char*>::iterator anIt = myFlushed.find(theID.myID);
+ if (anIt != myFlushed.end())
+ myFlushed.erase(myFlushed.find(theID.myID));
}
}
virtual FeaturePtr createFeature(std::string theFeatureID);
public:
- /// Is needed for python wrapping by swig
ExchangePlugin_Plugin();
};
virtual FeaturePtr createFeature(std::string theFeatureID);
public:
- /// Is needed for python wrapping by swig
FeaturesPlugin_Plugin();
};
ADD_DEFINITIONS(-DGEOMAPI_EXPORTS ${CAS_DEFINITIONS})
ADD_LIBRARY(GeomAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
-SET(CMAKE_SWIG_FLAGS "")
+SET(CMAKE_SWIG_FLAGS -threads -Wall)
SET_SOURCE_FILES_PROPERTIES(GeomAPI.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(GeomAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow")
ADD_DEFINITIONS(-DGEOMALGOAPI_EXPORTS ${CAS_DEFINITIONS})
ADD_LIBRARY(GeomAlgoAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
-SET(CMAKE_SWIG_FLAGS "")
+SET(CMAKE_SWIG_FLAGS "-Wall")
SET_SOURCE_FILES_PROPERTIES(GeomAlgoAPI.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(GeomAlgoAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow")
GeomDataAPI_Point2D.h
)
-SET(CMAKE_SWIG_FLAGS "")
+SET(CMAKE_SWIG_FLAGS "-Wall")
SET_SOURCE_FILES_PROPERTIES(GeomDataAPI.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(GeomDataAPI.i PROPERTIES SWIG_DEFINITIONS "-shadow")
FeaturePtr Model_Session::createFeature(string theFeatureID)
{
- if (this != myImpl)
+ if (this != myImpl) {
return myImpl->createFeature(theFeatureID);
+ }
// load all information about plugins, features and attributes
LoadPluginsInfo();
myCurrentPluginName = aPlugin.first;
if (myPluginObjs.find(myCurrentPluginName) == myPluginObjs.end()) {
// load plugin library if not yet done
- Config_ModuleReader::loadLibrary(myCurrentPluginName);
+ Config_ModuleReader::loadPlugin(myCurrentPluginName);
}
if (myPluginObjs.find(myCurrentPluginName) != myPluginObjs.end()) {
FeaturePtr aCreated = myPluginObjs[myCurrentPluginName]->createFeature(theFeatureID);
SET(PROJECT_LIBRARIES
Config
)
+SET(CMAKE_SWIG_FLAGS -threads -Wall)
+ADD_DEFINITIONS(-DMODELAPI_EXPORTS -DSWIG_TYPE_TABLE=ModelAPI)
-ADD_DEFINITIONS(-DMODELAPI_EXPORTS)
ADD_LIBRARY(ModelAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
SET_TARGET_PROPERTIES(ModelAPI PROPERTIES LINKER_LANGUAGE CXX)
TARGET_LINK_LIBRARIES(ModelAPI ${PROJECT_LIBRARIES})
../GeomAlgoAPI
)
-SET(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(ModelAPI.i PROPERTIES CPLUSPLUS ON)
# "-includeall" is not needed: it starts to follow the standard inludes (like "string") without success
/* ModelAPI.i */
-%module ModelAPI
+%module(directors="1") ModelAPI
+%feature("director:except") {
+ if ($error != NULL) {
+ PyErr_Print();
+ std::cerr << std::endl;
+ throw Swig::DirectorMethodException();
+ }
+}
+
%{
#include "GeomAPI_Interface.h"
#include "GeomAPI_Shape.h"
#include "ModelAPI_Session.h"
#include "ModelAPI_Object.h"
#include "ModelAPI_Feature.h"
+ #include "ModelAPI_Plugin.h"
#include "ModelAPI_CompositeFeature.h"
#include "ModelAPI_Data.h"
#include "ModelAPI_Attribute.h"
%include "std_list.i"
%include "std_shared_ptr.i"
+// directors
+%feature("director") ModelAPI_Plugin;
+%feature("director") ModelAPI_Object;
+%feature("director") ModelAPI_Feature;
+
// shared pointers
// For ModelAPI_ResultConstruction.shape()
%shared_ptr(GeomAPI_Interface)
%shared_ptr(GeomAPI_Shape)
%shared_ptr(ModelAPI_Document)
%shared_ptr(ModelAPI_Session)
+%shared_ptr(ModelAPI_Plugin)
%shared_ptr(ModelAPI_Object)
%shared_ptr(ModelAPI_Feature)
%shared_ptr(ModelAPI_CompositeFeature)
%include "GeomAPI_Shape.h"
%include "ModelAPI_Document.h"
%include "ModelAPI_Session.h"
+%include "ModelAPI_Plugin.h"
%include "ModelAPI_Object.h"
%include "ModelAPI_Feature.h"
%include "ModelAPI_CompositeFeature.h"
%template(ObjectList) std::list<std::shared_ptr<ModelAPI_Object> >;
%template(ResultList) std::list<std::shared_ptr<ModelAPI_Result> >;
+template<class T1, class T2> boost::shared_ptr<T1> boost_cast(boost::shared_ptr<T2> theObject);
+
+// Feature casts
+%template(modelAPI_Feature) shared_ptr_cast<ModelAPI_Feature, ModelAPI_Object>;
+%template(modelAPI_CompositeFeature) shared_ptr_cast<ModelAPI_CompositeFeature, ModelAPI_Feature>;
template<class T1, class T2> std::shared_ptr<T1> shared_ptr_cast(std::shared_ptr<T2> theObject);
%template(modelAPI_CompositeFeature) shared_ptr_cast<ModelAPI_CompositeFeature, ModelAPI_Feature>;
%template(modelAPI_ResultConstruction) shared_ptr_cast<ModelAPI_ResultConstruction, ModelAPI_Result>;
%template(modelAPI_ResultBody) shared_ptr_cast<ModelAPI_ResultBody, ModelAPI_Result>;
%template(modelAPI_ResultPart) shared_ptr_cast<ModelAPI_ResultPart, ModelAPI_Result>;
+// Result casts
+%template(modelAPI_ResultConstruction) boost_cast<ModelAPI_ResultConstruction, ModelAPI_Result>;
+%template(modelAPI_ResultBody) boost_cast<ModelAPI_ResultBody, ModelAPI_Result>;
+%template(modelAPI_ResultPart) boost_cast<ModelAPI_ResultPart, ModelAPI_Result>;
+// Attribute casts
+%template(modelAPI_AttributeDocRef) boost_cast<ModelAPI_AttributeDocRef, ModelAPI_Attribute>;
+%template(modelAPI_AttributeDouble) boost_cast<ModelAPI_AttributeDouble, ModelAPI_Attribute>;
+%template(modelAPI_AttributeInteger) boost_cast<ModelAPI_AttributeInteger, ModelAPI_Attribute>;
+%template(modelAPI_AttributeString) boost_cast<ModelAPI_AttributeString, ModelAPI_Attribute>;
+%template(modelAPI_AttributeReference) boost_cast<ModelAPI_AttributeReference, ModelAPI_Attribute>;
+%template(modelAPI_AttributeRefAttr) boost_cast<ModelAPI_AttributeRefAttr, ModelAPI_Attribute>;
+%template(modelAPI_AttributeBoolean) boost_cast<ModelAPI_AttributeBoolean, ModelAPI_Attribute>;
+%template(modelAPI_AttributeSelection) boost_cast<ModelAPI_AttributeSelection, ModelAPI_Attribute>;
+%template(modelAPI_AttributeSelectionList) boost_cast<ModelAPI_AttributeSelectionList, ModelAPI_Attribute>;
+%template(modelAPI_AttributeRefList) boost_cast<ModelAPI_AttributeRefList, ModelAPI_Attribute>;
virtual ~ModelAPI_Plugin()
{
}
-
- protected:
- /// Is needed for python wrapping by swig
- ModelAPI_Plugin()
- {
- }
- ;
};
#endif
/// Manager that will be initialized from Model package, one per application
std::shared_ptr<ModelAPI_Session> MY_MANAGER;
-ModelAPI_Session::ModelAPI_Session()
-{
-}
-
void ModelAPI_Session::setSession(std::shared_ptr<ModelAPI_Session> theManager)
{
MY_MANAGER = theManager;
/// Returns the validators factory: the only one instance per application
virtual ModelAPI_ValidatorsFactory* validators() = 0;
- /// Is needed for python wrapping by swig, call Get to get an instance
- ModelAPI_Session();
-
/// To virtually destroy the fields of successors
virtual ~ModelAPI_Session()
{
virtual FeaturePtr createFeature(std::string theFeatureID);
public:
- /// Is needed for python wrapping by swig
PartSetPlugin_Plugin();
};
--- /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)
+ pass
+
+ def createFeature(self, theFeatureID):
+ if theFeatureID == PythonFeaturesPlugin_Box.ID():
+ return PythonFeaturesPlugin_Box().__disown__()
+ else:
+ raise StandardError("No such feature %s" % theFeatureID)
+
+plugin = PythonFeaturesPlugin()
+aSession = ModelAPI.ModelAPI_Session.get()
+print "Module loaded. Session", aSession
+aSession.registerPlugin(plugin)
--- /dev/null
+import ModelAPI
+import examples
+
+
+class PythonFeaturesPlugin_Box(ModelAPI.ModelAPI_Feature):
+
+ "Feature to create a box by drawing a sketch and extruding it"
+
+ def __init__(self):
+ ModelAPI.ModelAPI_Feature.__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"
+
+ 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(PythonFeaturesPlugin_Box.WIDTH_ID(),
+ ModelAPI.ModelAPI_AttributeDouble_type())
+ self.data().addAttribute(PythonFeaturesPlugin_Box.LENGTH_ID(),
+ ModelAPI.ModelAPI_AttributeDouble_type())
+ self.data().addAttribute(PythonFeaturesPlugin_Box.HEIGHT_ID(),
+ ModelAPI.ModelAPI_AttributeDouble_type())
+
+ def execute(self):
+ aWidth = self.real(PythonFeaturesPlugin_Box.WIDTH_ID()).value()
+ aLength = self.real(PythonFeaturesPlugin_Box.LENGTH_ID()).value()
+ aHeight = self.real(PythonFeaturesPlugin_Box.HEIGHT_ID()).value()
+ print ("Box W:{0} L:{1} H:{2}".format(aWidth, aLength, aHeight))
+ aResultBody = self.document().createBody(self.data())
+ aResult = examples.makeBox(aLength, aWidth, aHeight)
+ #aShape = modelAPI_ResultConstruction(aResult).shape()
+ # aResultBody.store(aShape)
+ self.setResult(aResultBody)
+
+# 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="10" 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="10" 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="10" 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
+ # NOTE : the following lines are currently not working in BR_PYTHON_PLUGIN
+ # branch
+ # 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))
+ # sketch.makeParallel(sketch.getGeometry(l2), sketch.getGeometry(l4))
+ #
+ # sketch.makePerpendicular(sketch.getGeometry(l1), sketch.getGeometry(l4))
+
+ # Finalisation of the operation
+ builder = SketchResult(base)
+
+ # Creating a feature Extrusion
+ box = extrusion.addNew(builder, 50, 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())
+ feature.real("extrusion_size").setValue(length)
+ feature.boolean("extrusion_reverse").setValue(reverse)
+ feature.execute()
+ return feature
+
+
+def getBody(extrusion):
+ return 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 modelAPI_CompositeFeature(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)
+
+
+def makeParallel(l1, l2, sketch):
+ constraint = sketch.addFeature("SketchConstraintParallel")
+ constraint.refattr("ConstraintEntityA").setObject(l1)
+ constraint.refattr("ConstraintEntityB").setObject(l2)
+
+
+def makePerpendicular(l1, l2, sketch):
+ constraint = sketch.addFeature("SketchConstraintPerpendicular")
+ constraint.refattr("ConstraintEntityA").setObject(l1)
+ constraint.refattr("ConstraintEntityB").setObject(l2)
+
+
+def makeConstantLength(line, length, sketch):
+ constraint = sketch.addFeature("SketchConstraintLength")
+ constraint.refattr("ConstraintEntityA").setObject(line)
+ constraint.real("ConstraintValue").setValue(length)
virtual FeaturePtr createFeature(std::string theFeatureID);
public:
- /// Is needed for python wrapping by swig
SketchPlugin_Plugin();
};