Assembly: Introduce core functionality of assembly workbench.
This commit is contained in:
63
src/Mod/Assembly/App/AppAssembly.cpp
Normal file
63
src/Mod/Assembly/App/AppAssembly.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <development@ondsel.com> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/PyObjectBase.h>
|
||||
|
||||
#include "AssemblyObject.h"
|
||||
#include "JointGroup.h"
|
||||
|
||||
|
||||
namespace Assembly
|
||||
{
|
||||
extern PyObject* initModule();
|
||||
}
|
||||
|
||||
/* Python entry */
|
||||
PyMOD_INIT_FUNC(AssemblyApp)
|
||||
{
|
||||
// load dependent module
|
||||
try {
|
||||
Base::Interpreter().runString("import Part");
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
PyErr_SetString(PyExc_ImportError, e.what());
|
||||
PyMOD_Return(nullptr);
|
||||
}
|
||||
|
||||
PyObject* mod = Assembly::initModule();
|
||||
Base::Console().Log("Loading Assembly module... done\n");
|
||||
|
||||
|
||||
// NOTE: To finish the initialization of our own type objects we must
|
||||
// call PyType_Ready, otherwise we run into a segmentation fault, later on.
|
||||
// This function is responsible for adding inherited slots from a type's base class.
|
||||
|
||||
Assembly::AssemblyObject ::init();
|
||||
Assembly::JointGroup ::init();
|
||||
|
||||
PyMOD_Return(mod);
|
||||
}
|
||||
47
src/Mod/Assembly/App/AppAssemblyPy.cpp
Normal file
47
src/Mod/Assembly/App/AppAssemblyPy.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <development@ondsel.com> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/Tools.h>
|
||||
|
||||
|
||||
namespace Assembly
|
||||
{
|
||||
class Module: public Py::ExtensionModule<Module>
|
||||
{
|
||||
public:
|
||||
Module()
|
||||
: Py::ExtensionModule<Module>("AssemblyApp")
|
||||
{
|
||||
initialize("This module is the Assembly module."); // register with Python
|
||||
}
|
||||
};
|
||||
|
||||
PyObject* initModule()
|
||||
{
|
||||
return Base::Interpreter().addModule(new Module);
|
||||
}
|
||||
|
||||
} // namespace Assembly
|
||||
516
src/Mod/Assembly/App/AssemblyObject.cpp
Normal file
516
src/Mod/Assembly/App/AssemblyObject.cpp
Normal file
@@ -0,0 +1,516 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <development@ondsel.com> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObjectGroup.h>
|
||||
#include <App/FeaturePythonPyImp.h>
|
||||
#include <App/PropertyPythonObject.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Placement.h>
|
||||
#include <Base/Rotation.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Interpreter.h>
|
||||
|
||||
#include <OndselSolver/CREATE.h>
|
||||
#include <OndselSolver/ASMTSimulationParameters.h>
|
||||
#include <OndselSolver/ASMTAssembly.h>
|
||||
#include <OndselSolver/ASMTMarker.h>
|
||||
#include <OndselSolver/ASMTPart.h>
|
||||
#include <OndselSolver/ASMTJoint.h>
|
||||
#include <OndselSolver/ASMTFixedJoint.h>
|
||||
#include <OndselSolver/ASMTRevoluteJoint.h>
|
||||
#include <OndselSolver/ASMTCylindricalJoint.h>
|
||||
#include <OndselSolver/ASMTTranslationalJoint.h>
|
||||
#include <OndselSolver/ASMTSphericalJoint.h>
|
||||
#include <OndselSolver/ASMTPointInPlaneJoint.h>
|
||||
#include <OndselSolver/ASMTTime.h>
|
||||
#include <OndselSolver/ASMTConstantGravity.h>
|
||||
|
||||
#include "AssemblyObject.h"
|
||||
#include "AssemblyObjectPy.h"
|
||||
#include "JointGroup.h"
|
||||
|
||||
using namespace App;
|
||||
using namespace Assembly;
|
||||
using namespace MbD;
|
||||
|
||||
|
||||
PROPERTY_SOURCE(Assembly::AssemblyObject, App::Part)
|
||||
|
||||
AssemblyObject::AssemblyObject()
|
||||
: mbdAssembly(std::make_shared<ASMTAssembly>())
|
||||
{}
|
||||
|
||||
AssemblyObject::~AssemblyObject() = default;
|
||||
|
||||
PyObject* AssemblyObject::getPyObject()
|
||||
{
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new AssemblyObjectPy(this), true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
|
||||
std::vector<App::DocumentObject*> AssemblyObject::getJoints()
|
||||
{
|
||||
std::vector<App::DocumentObject*> joints = {};
|
||||
|
||||
App::Document* doc = getDocument();
|
||||
|
||||
std::vector<DocumentObject*> jointGroups =
|
||||
doc->getObjectsOfType(Assembly::JointGroup::getClassTypeId());
|
||||
|
||||
Base::PyGILStateLocker lock;
|
||||
if (jointGroups.size() > 0) {
|
||||
for (auto* obj : static_cast<App::DocumentObjectGroup*>(jointGroups[0])->getObjects()) {
|
||||
App::PropertyPythonObject* proxy = obj
|
||||
? dynamic_cast<App::PropertyPythonObject*>(obj->getPropertyByName("Proxy"))
|
||||
: nullptr;
|
||||
if (proxy) {
|
||||
Py::Object joint = proxy->getValue();
|
||||
if (joint.hasAttr("setJointConnectors")) {
|
||||
joints.push_back(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the joints are up to date.
|
||||
recomputeJointPlacements(joints);
|
||||
|
||||
return joints;
|
||||
}
|
||||
|
||||
bool AssemblyObject::fixGroundedParts()
|
||||
{
|
||||
App::Document* doc = getDocument();
|
||||
App::DocumentObject* jointsGroup = doc->getObject("Joints");
|
||||
|
||||
bool onePartFixed = false;
|
||||
|
||||
Base::PyGILStateLocker lock;
|
||||
if (jointsGroup && jointsGroup->isDerivedFrom(App::DocumentObjectGroup::getClassTypeId())) {
|
||||
for (auto* obj : static_cast<App::DocumentObjectGroup*>(jointsGroup)->getObjects()) {
|
||||
auto* propObj =
|
||||
dynamic_cast<App::PropertyLink*>(obj->getPropertyByName("ObjectToGround"));
|
||||
if (propObj) {
|
||||
App::DocumentObject* objToGround = propObj->getValue();
|
||||
|
||||
Base::Placement plc = getPlacementFromProp(obj, "Placement");
|
||||
std::string str = obj->getFullName();
|
||||
fixGroundedPart(objToGround, plc, str);
|
||||
onePartFixed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return onePartFixed;
|
||||
}
|
||||
|
||||
void AssemblyObject::fixGroundedPart(App::DocumentObject* obj,
|
||||
Base::Placement& plc,
|
||||
std::string& name)
|
||||
{
|
||||
std::string markerName1 = "marker-" + obj->getFullName();
|
||||
auto mbdMarker1 = makeMbdMarker(markerName1, plc);
|
||||
mbdAssembly->addMarker(mbdMarker1);
|
||||
|
||||
std::shared_ptr<ASMTPart> mbdPart = getMbDPart(obj);
|
||||
|
||||
std::string markerName2 = "FixingMarker";
|
||||
auto mbdMarker2 = makeMbdMarker(markerName2, plc);
|
||||
mbdPart->addMarker(mbdMarker2);
|
||||
|
||||
markerName1 = "/OndselAssembly/" + mbdMarker1->name;
|
||||
markerName2 = "/OndselAssembly/" + mbdPart->name + "/" + mbdMarker2->name;
|
||||
|
||||
auto mbdJoint = CREATE<ASMTFixedJoint>::With();
|
||||
mbdJoint->setName(name);
|
||||
mbdJoint->setMarkerI(markerName1);
|
||||
mbdJoint->setMarkerJ(markerName2);
|
||||
|
||||
mbdAssembly->addJoint(mbdJoint);
|
||||
}
|
||||
|
||||
void AssemblyObject::jointParts(std::vector<App::DocumentObject*> joints)
|
||||
{
|
||||
for (auto* joint : joints) {
|
||||
std::shared_ptr<ASMTJoint> mbdJoint = makeMbdJoint(joint);
|
||||
mbdAssembly->addJoint(mbdJoint);
|
||||
}
|
||||
}
|
||||
|
||||
Base::Placement AssemblyObject::getPlacementFromProp(App::DocumentObject* obj, const char* propName)
|
||||
{
|
||||
Base::Placement plc = Base::Placement();
|
||||
auto* propPlacement = dynamic_cast<App::PropertyPlacement*>(obj->getPropertyByName(propName));
|
||||
if (propPlacement) {
|
||||
plc = propPlacement->getValue();
|
||||
}
|
||||
return plc;
|
||||
}
|
||||
|
||||
int AssemblyObject::solve()
|
||||
{
|
||||
// Base::Console().Warning("solve\n");
|
||||
mbdAssembly = makeMbdAssembly();
|
||||
objectPartMap.clear();
|
||||
|
||||
if (!fixGroundedParts()) {
|
||||
// If no part fixed we can't solve.
|
||||
return -6;
|
||||
}
|
||||
|
||||
std::vector<App::DocumentObject*> joints = getJoints();
|
||||
|
||||
jointParts(joints);
|
||||
|
||||
try {
|
||||
mbdAssembly->solve();
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Error("Solve failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
setNewPlacements();
|
||||
|
||||
// The Placement1 and Placement2 of each joint needs to be updated as the parts moved.
|
||||
// Note calling only recomputeJointPlacements makes a weird illegal storage access
|
||||
// When solving while moving part. Happens in Py::Callable(attr).apply();
|
||||
// it apparantly can't access the JointObject 'updateJCSPlacements' function.
|
||||
getJoints();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AssemblyObject::exportAsASMT(std::string fileName)
|
||||
{
|
||||
Base::Console().Warning("hello 1\n");
|
||||
mbdAssembly = makeMbdAssembly();
|
||||
objectPartMap.clear();
|
||||
Base::Console().Warning("hello 2\n");
|
||||
fixGroundedParts();
|
||||
|
||||
std::vector<App::DocumentObject*> joints = getJoints();
|
||||
|
||||
Base::Console().Warning("hello 3\n");
|
||||
jointParts(joints);
|
||||
|
||||
Base::Console().Warning("hello 4\n");
|
||||
Base::Console().Warning("%s\n", fileName.c_str());
|
||||
mbdAssembly->outputFile(fileName);
|
||||
Base::Console().Warning("hello 5\n");
|
||||
}
|
||||
|
||||
std::shared_ptr<ASMTJoint> AssemblyObject::makeMbdJointOfType(JointType jointType)
|
||||
{
|
||||
std::shared_ptr<ASMTJoint> mbdJoint;
|
||||
|
||||
if (jointType == JointType::Fixed) {
|
||||
mbdJoint = CREATE<ASMTFixedJoint>::With();
|
||||
}
|
||||
else if (jointType == JointType::Revolute) {
|
||||
mbdJoint = CREATE<ASMTRevoluteJoint>::With();
|
||||
}
|
||||
else if (jointType == JointType::Cylindrical) {
|
||||
mbdJoint = CREATE<ASMTCylindricalJoint>::With();
|
||||
}
|
||||
else if (jointType == JointType::Slider) {
|
||||
mbdJoint = CREATE<ASMTTranslationalJoint>::With();
|
||||
}
|
||||
else if (jointType == JointType::Ball) {
|
||||
mbdJoint = CREATE<ASMTSphericalJoint>::With();
|
||||
}
|
||||
else if (jointType == JointType::Planar) {
|
||||
mbdJoint = CREATE<ASMTPointInPlaneJoint>::With();
|
||||
}
|
||||
else if (jointType == JointType::Parallel) {
|
||||
// TODO
|
||||
mbdJoint = CREATE<ASMTFixedJoint>::With();
|
||||
}
|
||||
else if (jointType == JointType::Tangent) {
|
||||
// TODO
|
||||
mbdJoint = CREATE<ASMTFixedJoint>::With();
|
||||
}
|
||||
|
||||
return mbdJoint;
|
||||
}
|
||||
|
||||
std::shared_ptr<ASMTJoint> AssemblyObject::makeMbdJoint(App::DocumentObject* joint)
|
||||
{
|
||||
JointType jointType = JointType::Fixed;
|
||||
|
||||
auto* prop = joint
|
||||
? dynamic_cast<App::PropertyEnumeration*>(joint->getPropertyByName("JointType"))
|
||||
: nullptr;
|
||||
if (prop) {
|
||||
jointType = static_cast<JointType>(prop->getValue());
|
||||
}
|
||||
|
||||
std::shared_ptr<ASMTJoint> mbdJoint = makeMbdJointOfType(jointType);
|
||||
|
||||
std::string fullMarkerName1 = handleOneSideOfJoint(joint, "Object1", "Placement1");
|
||||
std::string fullMarkerName2 = handleOneSideOfJoint(joint, "Object2", "Placement2");
|
||||
|
||||
mbdJoint->setMarkerI(fullMarkerName1);
|
||||
mbdJoint->setMarkerJ(fullMarkerName2);
|
||||
|
||||
return mbdJoint;
|
||||
}
|
||||
|
||||
std::shared_ptr<ASMTPart> AssemblyObject::getMbDPart(App::DocumentObject* obj)
|
||||
{
|
||||
std::shared_ptr<ASMTPart> mbdPart;
|
||||
|
||||
Base::Placement plc = getPlacementFromProp(obj, "Placement");
|
||||
|
||||
auto it = objectPartMap.find(obj);
|
||||
if (it != objectPartMap.end()) {
|
||||
// obj has been associated with an ASMTPart before
|
||||
mbdPart = it->second;
|
||||
}
|
||||
else {
|
||||
// obj has not been associated with an ASMTPart before
|
||||
std::string str = obj->getFullName();
|
||||
mbdPart = makeMbdPart(str, plc);
|
||||
mbdAssembly->addPart(mbdPart);
|
||||
objectPartMap[obj] = mbdPart; // Store the association
|
||||
}
|
||||
|
||||
return mbdPart;
|
||||
}
|
||||
|
||||
std::string AssemblyObject::handleOneSideOfJoint(App::DocumentObject* joint,
|
||||
const char* propLinkName,
|
||||
const char* propPlcName)
|
||||
{
|
||||
auto* propObj = dynamic_cast<App::PropertyLink*>(joint->getPropertyByName(propLinkName));
|
||||
if (!propObj) {
|
||||
return nullptr;
|
||||
}
|
||||
App::DocumentObject* obj = propObj->getValue();
|
||||
|
||||
std::shared_ptr<ASMTPart> mbdPart = getMbDPart(obj);
|
||||
Base::Placement objPlc = getPlacementFromProp(obj, "Placement");
|
||||
Base::Placement plc = getPlacementFromProp(joint, propPlcName);
|
||||
// Now we have plc which is the JCS placement, but its relative to the doc origin, not to the
|
||||
// obj.
|
||||
|
||||
plc = objPlc.inverse() * plc;
|
||||
|
||||
std::string markerName = joint->getFullName();
|
||||
auto mbdMarker = makeMbdMarker(markerName, plc);
|
||||
mbdPart->addMarker(mbdMarker);
|
||||
|
||||
return "/OndselAssembly/" + mbdPart->name + "/" + markerName;
|
||||
}
|
||||
|
||||
std::shared_ptr<ASMTMarker> AssemblyObject::makeMbdMarker(std::string& name, Base::Placement& plc)
|
||||
{
|
||||
auto mbdMarker = CREATE<ASMTMarker>::With();
|
||||
mbdMarker->setName(name);
|
||||
|
||||
Base::Vector3d pos = plc.getPosition();
|
||||
mbdMarker->setPosition3D(pos.x, pos.y, pos.z);
|
||||
|
||||
// TODO : replace with quaternion to simplify
|
||||
Base::Rotation rot = plc.getRotation();
|
||||
Base::Matrix4D mat;
|
||||
rot.getValue(mat);
|
||||
Base::Vector3d r0 = mat.getRow(0);
|
||||
Base::Vector3d r1 = mat.getRow(1);
|
||||
Base::Vector3d r2 = mat.getRow(2);
|
||||
mbdMarker->setRotationMatrix(r0.x, r0.y, r0.z, r1.x, r1.y, r1.z, r2.x, r2.y, r2.z);
|
||||
/*double q0, q1, q2, q3;
|
||||
rot.getValue(q0, q1, q2, q3);
|
||||
mbdMarker->setQuarternions(q0, q1, q2, q3);*/
|
||||
return mbdMarker;
|
||||
}
|
||||
|
||||
std::shared_ptr<ASMTPart>
|
||||
AssemblyObject::makeMbdPart(std::string& name, Base::Placement plc, double mass)
|
||||
{
|
||||
auto mdbPart = CREATE<ASMTPart>::With();
|
||||
mdbPart->setName(name);
|
||||
|
||||
auto massMarker = CREATE<ASMTPrincipalMassMarker>::With();
|
||||
massMarker->setMass(mass);
|
||||
massMarker->setDensity(1.0);
|
||||
massMarker->setMomentOfInertias(1.0, 1.0, 1.0);
|
||||
mdbPart->setPrincipalMassMarker(massMarker);
|
||||
|
||||
Base::Vector3d pos = plc.getPosition();
|
||||
mdbPart->setPosition3D(pos.x, pos.y, pos.z);
|
||||
// Base::Console().Warning("MbD Part placement : (%f, %f, %f)\n", pos.x, pos.y, pos.z);
|
||||
|
||||
// TODO : replace with quaternion to simplify
|
||||
Base::Rotation rot = plc.getRotation();
|
||||
Base::Matrix4D mat;
|
||||
rot.getValue(mat);
|
||||
Base::Vector3d r0 = mat.getRow(0);
|
||||
Base::Vector3d r1 = mat.getRow(1);
|
||||
Base::Vector3d r2 = mat.getRow(2);
|
||||
mdbPart->setRotationMatrix(r0.x, r0.y, r0.z, r1.x, r1.y, r1.z, r2.x, r2.y, r2.z);
|
||||
/*double q0, q1, q2, q3;
|
||||
rot.getValue(q0, q1, q2, q3);
|
||||
mdbPart->setQuarternions(q0, q1, q2, q3);*/
|
||||
|
||||
return mdbPart;
|
||||
}
|
||||
|
||||
std::shared_ptr<ASMTAssembly> AssemblyObject::makeMbdAssembly()
|
||||
{
|
||||
auto assembly = CREATE<ASMTAssembly>::With();
|
||||
assembly->setName("OndselAssembly");
|
||||
|
||||
return assembly;
|
||||
}
|
||||
|
||||
void AssemblyObject::setNewPlacements()
|
||||
{
|
||||
for (auto& pair : objectPartMap) {
|
||||
App::DocumentObject* obj = pair.first;
|
||||
std::shared_ptr<ASMTPart> mbdPart = pair.second;
|
||||
|
||||
if (!obj || !mbdPart) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the object has a "Placement" property
|
||||
auto* propPlacement =
|
||||
dynamic_cast<App::PropertyPlacement*>(obj->getPropertyByName("Placement"));
|
||||
if (propPlacement) {
|
||||
|
||||
double x, y, z;
|
||||
mbdPart->getPosition3D(x, y, z);
|
||||
// Base::Console().Warning("in set placement : (%f, %f, %f)\n", x, y, z);
|
||||
Base::Vector3d pos = Base::Vector3d(x, y, z);
|
||||
|
||||
// TODO : replace with quaternion to simplify
|
||||
auto& r0 = mbdPart->rotationMatrix->at(0);
|
||||
auto& r1 = mbdPart->rotationMatrix->at(1);
|
||||
auto& r2 = mbdPart->rotationMatrix->at(2);
|
||||
Base::Vector3d row0 = Base::Vector3d(r0->at(0), r0->at(1), r0->at(2));
|
||||
Base::Vector3d row1 = Base::Vector3d(r1->at(0), r1->at(1), r1->at(2));
|
||||
Base::Vector3d row2 = Base::Vector3d(r2->at(0), r2->at(1), r2->at(2));
|
||||
Base::Matrix4D mat;
|
||||
mat.setRow(0, row0);
|
||||
mat.setRow(1, row1);
|
||||
mat.setRow(2, row2);
|
||||
Base::Rotation rot = Base::Rotation(mat);
|
||||
|
||||
/*double q0, q1, q2, q3;
|
||||
mbdPart->getQuarternions(q0, q1, q2, q3);
|
||||
Base::Rotation rot = Base::Rotation(q0, q1, q2, q3);*/
|
||||
|
||||
Base::Placement newPlacement = Base::Placement(pos, rot);
|
||||
|
||||
propPlacement->setValue(newPlacement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblyObject::recomputeJointPlacements(std::vector<App::DocumentObject*> joints)
|
||||
{
|
||||
// The Placement1 and Placement2 of each joint needs to be updated as the parts moved.
|
||||
for (auto* joint : joints) {
|
||||
|
||||
App::PropertyPythonObject* proxy = joint
|
||||
? dynamic_cast<App::PropertyPythonObject*>(joint->getPropertyByName("Proxy"))
|
||||
: nullptr;
|
||||
|
||||
if (!proxy) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Py::Object jointPy = proxy->getValue();
|
||||
|
||||
if (!jointPy.hasAttr("updateJCSPlacements")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Py::Object attr = jointPy.getAttr("updateJCSPlacements");
|
||||
if (attr.ptr() && attr.isCallable()) {
|
||||
Py::Tuple args(1);
|
||||
args.setItem(0, Py::asObject(joint->getPyObject()));
|
||||
Py::Callable(attr).apply(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double AssemblyObject::getObjMass(App::DocumentObject* obj)
|
||||
{
|
||||
for (auto& pair : objMasses) {
|
||||
if (pair.first == obj) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void AssemblyObject::setObjMasses(std::vector<std::pair<App::DocumentObject*, double>> objectMasses)
|
||||
{
|
||||
objMasses = objectMasses;
|
||||
}
|
||||
|
||||
/*void Part::handleChangedPropertyType(Base::XMLReader& reader, const char* TypeName, App::Property*
|
||||
prop)
|
||||
{
|
||||
App::Part::handleChangedPropertyType(reader, TypeName, prop);
|
||||
}*/
|
||||
|
||||
/* Apparantly not necessary as App::Part doesn't have this.
|
||||
// Python Assembly feature ---------------------------------------------------------
|
||||
|
||||
namespace App
|
||||
{
|
||||
/// @cond DOXERR
|
||||
PROPERTY_SOURCE_TEMPLATE(Assembly::AssemblyObjectPython, Assembly::AssemblyObject)
|
||||
template<>
|
||||
const char* Assembly::AssemblyObjectPython::getViewProviderName() const
|
||||
{
|
||||
return "AssemblyGui::ViewProviderAssembly";
|
||||
}
|
||||
template<>
|
||||
PyObject* Assembly::AssemblyObjectPython::getPyObject()
|
||||
{
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new FeaturePythonPyT<AssemblyObjectPy>(this), true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
// explicit template instantiation
|
||||
template class AssemblyExport FeaturePythonT<Assembly::AssemblyObject>;
|
||||
}// namespace App*/
|
||||
119
src/Mod/Assembly/App/AssemblyObject.h
Normal file
119
src/Mod/Assembly/App/AssemblyObject.h
Normal file
@@ -0,0 +1,119 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <development@ondsel.com> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef ASSEMBLY_AssemblyObject_H
|
||||
#define ASSEMBLY_AssemblyObject_H
|
||||
|
||||
#include <Mod/Assembly/AssemblyGlobal.h>
|
||||
|
||||
#include <App/FeaturePython.h>
|
||||
#include <App/Part.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
|
||||
namespace MbD
|
||||
{
|
||||
class ASMTPart;
|
||||
class ASMTAssembly;
|
||||
class ASMTJoint;
|
||||
class ASMTMarker;
|
||||
class ASMTPart;
|
||||
} // namespace MbD
|
||||
|
||||
namespace Base
|
||||
{
|
||||
class Placement;
|
||||
class Rotation;
|
||||
} // namespace Base
|
||||
|
||||
namespace Assembly
|
||||
{
|
||||
|
||||
// This enum has to be the same as the one in JointObject.py
|
||||
enum class JointType
|
||||
{
|
||||
Fixed,
|
||||
Revolute,
|
||||
Cylindrical,
|
||||
Slider,
|
||||
Ball,
|
||||
Planar,
|
||||
Parallel,
|
||||
Tangent
|
||||
};
|
||||
|
||||
class AssemblyExport AssemblyObject: public App::Part
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Assembly::AssemblyObject);
|
||||
|
||||
public:
|
||||
AssemblyObject();
|
||||
~AssemblyObject() override;
|
||||
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "AssemblyGui::ViewProviderAssembly";
|
||||
}
|
||||
|
||||
int solve();
|
||||
void exportAsASMT(std::string fileName);
|
||||
std::shared_ptr<MbD::ASMTAssembly> makeMbdAssembly();
|
||||
std::shared_ptr<MbD::ASMTPart>
|
||||
makeMbdPart(std::string& name, Base::Placement plc = Base::Placement(), double mass = 1.0);
|
||||
std::shared_ptr<MbD::ASMTPart> getMbDPart(App::DocumentObject* obj);
|
||||
std::shared_ptr<MbD::ASMTMarker> makeMbdMarker(std::string& name, Base::Placement& plc);
|
||||
std::shared_ptr<MbD::ASMTJoint> makeMbdJoint(App::DocumentObject* joint);
|
||||
std::shared_ptr<MbD::ASMTJoint> makeMbdJointOfType(JointType jointType);
|
||||
std::string handleOneSideOfJoint(App::DocumentObject* joint,
|
||||
const char* propObjLinkName,
|
||||
const char* propPlcName);
|
||||
void fixGroundedPart(App::DocumentObject* obj, Base::Placement& plc, std::string& jointName);
|
||||
bool fixGroundedParts();
|
||||
void jointParts(std::vector<App::DocumentObject*> joints);
|
||||
std::vector<App::DocumentObject*> getJoints();
|
||||
Base::Placement getPlacementFromProp(App::DocumentObject* obj, const char* propName);
|
||||
void setNewPlacements();
|
||||
void recomputeJointPlacements(std::vector<App::DocumentObject*> joints);
|
||||
|
||||
double getObjMass(App::DocumentObject* obj);
|
||||
void setObjMasses(std::vector<std::pair<App::DocumentObject*, double>> objectMasses);
|
||||
|
||||
private:
|
||||
std::shared_ptr<MbD::ASMTAssembly> mbdAssembly;
|
||||
|
||||
std::unordered_map<App::DocumentObject*, std::shared_ptr<MbD::ASMTPart>> objectPartMap;
|
||||
std::vector<std::pair<App::DocumentObject*, double>> objMasses;
|
||||
|
||||
// void handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property
|
||||
// *prop) override;
|
||||
};
|
||||
|
||||
// using AssemblyObjectPython = App::FeaturePythonT<AssemblyObject>;
|
||||
|
||||
} // namespace Assembly
|
||||
|
||||
|
||||
#endif // ASSEMBLY_AssemblyObject_H
|
||||
50
src/Mod/Assembly/App/AssemblyObjectPy.xml
Normal file
50
src/Mod/Assembly/App/AssemblyObjectPy.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="PartPy"
|
||||
Name="AssemblyObjectPy"
|
||||
Twin="AssemblyObject"
|
||||
TwinPointer="AssemblyObject"
|
||||
Include="Mod/Assembly/App/AssemblyObject.h"
|
||||
Namespace="Assembly"
|
||||
FatherInclude="App/PartPy.h"
|
||||
FatherNamespace="App">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Ondsel" EMail="development@ondsel.com" />
|
||||
<UserDocu>This class handles document objects in Assembly</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="solve">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Solve the assembly and update part placements.
|
||||
|
||||
solve()
|
||||
|
||||
Returns:
|
||||
0 in case of success, otherwise the following codes in this order of
|
||||
priority:
|
||||
-6 if no parts are fixed.
|
||||
-4 if over-constrained,
|
||||
-3 if conflicting constraints,
|
||||
-5 if malformed constraints
|
||||
-1 if solver error,
|
||||
-2 if redundant constraints.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="exportAsASMT">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Export the assembly in a text format called ASMT.
|
||||
|
||||
exportAsASMT(fileName:str)
|
||||
|
||||
Args:
|
||||
fileName: The name of the file where the ASMT will be exported.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
|
||||
<CustomAttributes />
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
75
src/Mod/Assembly/App/AssemblyObjectPyImp.cpp
Normal file
75
src/Mod/Assembly/App/AssemblyObjectPyImp.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2014 Jürgen Riegel <juergen.riegel@web.de> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
// inclusion of the generated files (generated out of AssemblyObject.xml)
|
||||
#include "AssemblyObjectPy.h"
|
||||
#include "AssemblyObjectPy.cpp"
|
||||
|
||||
using namespace Assembly;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string AssemblyObjectPy::representation() const
|
||||
{
|
||||
return {"<Assembly object>"};
|
||||
}
|
||||
|
||||
PyObject* AssemblyObjectPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int AssemblyObjectPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject* AssemblyObjectPy::solve(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
return nullptr;
|
||||
}
|
||||
int ret = this->getAssemblyObjectPtr()->solve();
|
||||
return Py_BuildValue("i", ret);
|
||||
}
|
||||
|
||||
PyObject* AssemblyObjectPy::exportAsASMT(PyObject* args)
|
||||
{
|
||||
char* utf8Name;
|
||||
if (!PyArg_ParseTuple(args, "et", "utf-8", &utf8Name)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string fileName = utf8Name;
|
||||
PyMem_Free(utf8Name);
|
||||
|
||||
if (fileName.empty()) {
|
||||
PyErr_SetString(PyExc_ValueError, "Passed string is empty");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
this->getAssemblyObjectPtr()->exportAsASMT(fileName);
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
include_directories(
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
${CMAKE_SOURCE_DIR}/src/3rdParty/OndselSolver
|
||||
${CMAKE_BINARY_DIR}/src
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${OCC_INCLUDE_DIR}
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
)
|
||||
link_directories(${OCC_LIBRARY_DIR})
|
||||
|
||||
set(Assembly_LIBS
|
||||
Part
|
||||
FreeCADApp
|
||||
OndselSolver
|
||||
)
|
||||
|
||||
generate_from_xml(AssemblyObjectPy)
|
||||
generate_from_xml(JointGroupPy)
|
||||
|
||||
SET(Python_SRCS
|
||||
AssemblyObjectPy.xml
|
||||
AssemblyObjectPyImp.cpp
|
||||
JointGroupPy.xml
|
||||
JointGroupPyImp.cpp
|
||||
)
|
||||
SOURCE_GROUP("Python" FILES ${Python_SRCS})
|
||||
|
||||
SET(Module_SRCS
|
||||
AppAssembly.cpp
|
||||
AppAssemblyPy.cpp
|
||||
PreCompiled.cpp
|
||||
PreCompiled.h
|
||||
)
|
||||
SOURCE_GROUP("Module" FILES ${Module_SRCS})
|
||||
|
||||
SET(Assembly_SRCS
|
||||
AssemblyObject.cpp
|
||||
AssemblyObject.h
|
||||
JointGroup.cpp
|
||||
JointGroup.h
|
||||
${Module_SRCS}
|
||||
${Python_SRCS}
|
||||
)
|
||||
|
||||
add_library(Assembly SHARED ${Assembly_SRCS})
|
||||
target_link_libraries(Assembly ${Assembly_LIBS})
|
||||
|
||||
if(FREECAD_USE_PCH)
|
||||
add_definitions(-D_PreComp_)
|
||||
GET_MSVC_PRECOMPILED_SOURCE("PreCompiled.cpp" PCH_SRCS ${Assembly_SRCS})
|
||||
ADD_MSVC_PRECOMPILED_HEADER(Assembly PreCompiled.h PreCompiled.cpp PCH_SRCS)
|
||||
endif(FREECAD_USE_PCH)
|
||||
|
||||
SET_BIN_DIR(Assembly AssemblyApp /Mod/Assembly)
|
||||
SET_PYTHON_PREFIX_SUFFIX(Assembly)
|
||||
|
||||
INSTALL(TARGETS Assembly DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
55
src/Mod/Assembly/App/JointGroup.cpp
Normal file
55
src/Mod/Assembly/App/JointGroup.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <development@ondsel.com> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/FeaturePythonPyImp.h>
|
||||
#include <App/PropertyPythonObject.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Tools.h>
|
||||
|
||||
#include "JointGroup.h"
|
||||
#include "JointGroupPy.h"
|
||||
|
||||
using namespace Assembly;
|
||||
|
||||
|
||||
PROPERTY_SOURCE(Assembly::JointGroup, App::DocumentObjectGroup)
|
||||
|
||||
JointGroup::JointGroup()
|
||||
{}
|
||||
|
||||
JointGroup::~JointGroup() = default;
|
||||
|
||||
PyObject* JointGroup::getPyObject()
|
||||
{
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new JointGroupPy(this), true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
58
src/Mod/Assembly/App/JointGroup.h
Normal file
58
src/Mod/Assembly/App/JointGroup.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <development@ondsel.com> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef ASSEMBLY_JointGroup_H
|
||||
#define ASSEMBLY_JointGroup_H
|
||||
|
||||
#include <Mod/Assembly/AssemblyGlobal.h>
|
||||
|
||||
#include <App/DocumentObjectGroup.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
|
||||
|
||||
namespace Assembly
|
||||
{
|
||||
|
||||
class AssemblyExport JointGroup: public App::DocumentObjectGroup
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Assembly::JointGroup);
|
||||
|
||||
public:
|
||||
JointGroup();
|
||||
~JointGroup() override;
|
||||
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "AssemblyGui::ViewProviderJointGroup";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace Assembly
|
||||
|
||||
|
||||
#endif // ASSEMBLY_JointGroup_H
|
||||
19
src/Mod/Assembly/App/JointGroupPy.xml
Normal file
19
src/Mod/Assembly/App/JointGroupPy.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="DocumentObjectGroupPy"
|
||||
Name="JointGroupPy"
|
||||
Twin="JointGroup"
|
||||
TwinPointer="JointGroup"
|
||||
Include="Mod/Assembly/App/JointGroup.h"
|
||||
Namespace="Assembly"
|
||||
FatherInclude="App/DocumentObjectGroupPy.h"
|
||||
FatherNamespace="App">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Ondsel" EMail="development@ondsel.com" />
|
||||
<UserDocu>This class is a group subclass for joints.</UserDocu>
|
||||
</Documentation>
|
||||
|
||||
<CustomAttributes />
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
46
src/Mod/Assembly/App/JointGroupPyImp.cpp
Normal file
46
src/Mod/Assembly/App/JointGroupPyImp.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2014 Jürgen Riegel <juergen.riegel@web.de> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
// inclusion of the generated files (generated out of JointGroup.xml)
|
||||
#include "JointGroupPy.h"
|
||||
#include "JointGroupPy.cpp"
|
||||
|
||||
using namespace Assembly;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string JointGroupPy::representation() const
|
||||
{
|
||||
return {"<Joint Group>"};
|
||||
}
|
||||
|
||||
PyObject* JointGroupPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int JointGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
25
src/Mod/Assembly/App/PreCompiled.cpp
Normal file
25
src/Mod/Assembly/App/PreCompiled.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <development@ondsel.com> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
46
src/Mod/Assembly/App/PreCompiled.h
Normal file
46
src/Mod/Assembly/App/PreCompiled.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <development@ondsel.com> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef ASSEMBLY_PRECOMPILED_H
|
||||
#define ASSEMBLY_PRECOMPILED_H
|
||||
|
||||
#include <FCConfig.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 5208)
|
||||
#endif
|
||||
|
||||
#ifdef _PreComp_
|
||||
|
||||
// standard
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#endif // _PreComp_
|
||||
#endif // ASSEMBLY_PRECOMPILED_H
|
||||
Reference in New Issue
Block a user