Sketcher: App - Clang-format
This commit is contained in:
committed by
abdullahtahiriyo
parent
c33cdcd68a
commit
987b4bda2a
@@ -29,15 +29,17 @@
|
||||
#include "Constraint.h"
|
||||
|
||||
|
||||
namespace Sketcher {
|
||||
namespace Sketcher
|
||||
{
|
||||
|
||||
struct ConstraintIds {
|
||||
Base::Vector3d v;
|
||||
int First;
|
||||
int Second;
|
||||
Sketcher::PointPos FirstPos;
|
||||
Sketcher::PointPos SecondPos;
|
||||
Sketcher::ConstraintType Type;
|
||||
struct ConstraintIds
|
||||
{
|
||||
Base::Vector3d v;
|
||||
int First;
|
||||
int Second;
|
||||
Sketcher::PointPos FirstPos;
|
||||
Sketcher::PointPos SecondPos;
|
||||
Sketcher::ConstraintType Type;
|
||||
};
|
||||
|
||||
struct Constraint_Equal
|
||||
@@ -45,21 +47,21 @@ struct Constraint_Equal
|
||||
using argument_type = ConstraintIds;
|
||||
using result_type = bool;
|
||||
struct Sketcher::ConstraintIds c;
|
||||
explicit Constraint_Equal(const ConstraintIds& c) : c(c)
|
||||
{
|
||||
}
|
||||
explicit Constraint_Equal(const ConstraintIds& c)
|
||||
: c(c)
|
||||
{}
|
||||
bool operator()(const ConstraintIds& x) const
|
||||
{
|
||||
if (c.First == x.First && c.FirstPos == x.FirstPos &&
|
||||
c.Second == x.Second && c.SecondPos == x.SecondPos)
|
||||
if (c.First == x.First && c.FirstPos == x.FirstPos && c.Second == x.Second
|
||||
&& c.SecondPos == x.SecondPos)
|
||||
return true;
|
||||
if (c.Second == x.First && c.SecondPos == x.FirstPos &&
|
||||
c.First == x.Second && c.FirstPos == x.SecondPos)
|
||||
if (c.Second == x.First && c.SecondPos == x.FirstPos && c.First == x.Second
|
||||
&& c.FirstPos == x.SecondPos)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
#endif // SKETCHER_ANALYSE_H
|
||||
#endif// SKETCHER_ANALYSE_H
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
#include "SolverGeometryExtension.h"
|
||||
|
||||
|
||||
namespace Sketcher {
|
||||
namespace Sketcher
|
||||
{
|
||||
extern PyObject* initModule();
|
||||
}
|
||||
|
||||
@@ -54,7 +55,7 @@ PyMOD_INIT_FUNC(Sketcher)
|
||||
try {
|
||||
Base::Interpreter().runString("import Part");
|
||||
}
|
||||
catch(const Base::Exception& e) {
|
||||
catch (const Base::Exception& e) {
|
||||
PyErr_SetString(PyExc_ImportError, e.what());
|
||||
PyMOD_Return(nullptr);
|
||||
}
|
||||
@@ -62,29 +63,33 @@ PyMOD_INIT_FUNC(Sketcher)
|
||||
PyObject* sketcherModule = Sketcher::initModule();
|
||||
|
||||
// Add Types to module
|
||||
Base::Interpreter().addType(&Sketcher::ConstraintPy ::Type,sketcherModule,"Constraint");
|
||||
Base::Interpreter().addType(&Sketcher::SketchPy ::Type,sketcherModule,"Sketch");
|
||||
Base::Interpreter().addType(&Sketcher::ExternalGeometryExtensionPy ::Type,sketcherModule,"ExternalGeometryExtension");
|
||||
Base::Interpreter().addType(&Sketcher::SketchGeometryExtensionPy ::Type,sketcherModule,"SketchGeometryExtension");
|
||||
Base::Interpreter().addType(&Sketcher::GeometryFacadePy ::Type,sketcherModule,"GeometryFacade");
|
||||
Base::Interpreter().addType(&Sketcher::ExternalGeometryFacadePy ::Type,sketcherModule,"ExternalGeometryFacade");
|
||||
Base::Interpreter().addType(&Sketcher::ConstraintPy ::Type, sketcherModule, "Constraint");
|
||||
Base::Interpreter().addType(&Sketcher::SketchPy ::Type, sketcherModule, "Sketch");
|
||||
Base::Interpreter().addType(
|
||||
&Sketcher::ExternalGeometryExtensionPy ::Type, sketcherModule, "ExternalGeometryExtension");
|
||||
Base::Interpreter().addType(
|
||||
&Sketcher::SketchGeometryExtensionPy ::Type, sketcherModule, "SketchGeometryExtension");
|
||||
Base::Interpreter().addType(
|
||||
&Sketcher::GeometryFacadePy ::Type, sketcherModule, "GeometryFacade");
|
||||
Base::Interpreter().addType(
|
||||
&Sketcher::ExternalGeometryFacadePy ::Type, sketcherModule, "ExternalGeometryFacade");
|
||||
|
||||
|
||||
// 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.
|
||||
|
||||
Sketcher::SketchGeometryExtension ::init();
|
||||
Sketcher::ExternalGeometryExtension ::init();
|
||||
Sketcher::SolverGeometryExtension ::init();
|
||||
Sketcher::GeometryFacade ::init();
|
||||
Sketcher::ExternalGeometryFacade ::init();
|
||||
Sketcher::SketchObjectSF ::init();
|
||||
Sketcher::SketchObject ::init();
|
||||
Sketcher::SketchObjectPython ::init();
|
||||
Sketcher::Sketch ::init();
|
||||
Sketcher::Constraint ::init();
|
||||
Sketcher::PropertyConstraintList ::init();
|
||||
Sketcher::SketchGeometryExtension ::init();
|
||||
Sketcher::ExternalGeometryExtension ::init();
|
||||
Sketcher::SolverGeometryExtension ::init();
|
||||
Sketcher::GeometryFacade ::init();
|
||||
Sketcher::ExternalGeometryFacade ::init();
|
||||
Sketcher::SketchObjectSF ::init();
|
||||
Sketcher::SketchObject ::init();
|
||||
Sketcher::SketchObjectPython ::init();
|
||||
Sketcher::Sketch ::init();
|
||||
Sketcher::Constraint ::init();
|
||||
Sketcher::PropertyConstraintList ::init();
|
||||
|
||||
Base::Console().Log("Loading Sketcher module... done\n");
|
||||
|
||||
|
||||
@@ -32,31 +32,32 @@
|
||||
#include "SketchObjectSF.h"
|
||||
|
||||
|
||||
namespace Sketcher {
|
||||
class Module : public Py::ExtensionModule<Module>
|
||||
namespace Sketcher
|
||||
{
|
||||
class Module: public Py::ExtensionModule<Module>
|
||||
{
|
||||
public:
|
||||
Module() : Py::ExtensionModule<Module>("Sketcher")
|
||||
Module()
|
||||
: Py::ExtensionModule<Module>("Sketcher")
|
||||
{
|
||||
add_varargs_method("open",&Module::open
|
||||
);
|
||||
add_varargs_method("insert",&Module::insert
|
||||
);
|
||||
initialize("This module is the Sketcher module."); // register with Python
|
||||
add_varargs_method("open", &Module::open);
|
||||
add_varargs_method("insert", &Module::insert);
|
||||
initialize("This module is the Sketcher module.");// register with Python
|
||||
}
|
||||
|
||||
~Module() override {}
|
||||
~Module() override
|
||||
{}
|
||||
|
||||
private:
|
||||
Py::Object open(const Py::Tuple& args)
|
||||
{
|
||||
char* Name;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "et", "utf-8", &Name))
|
||||
throw Py::Exception();
|
||||
std::string EncodedName = std::string(Name);
|
||||
PyMem_Free(Name);
|
||||
|
||||
//Base::Console().Log("Open in Part with %s",Name);
|
||||
// Base::Console().Log("Open in Part with %s",Name);
|
||||
Base::FileInfo file(EncodedName.c_str());
|
||||
|
||||
// extract extension
|
||||
@@ -64,33 +65,34 @@ private:
|
||||
throw Py::RuntimeError("No file extension");
|
||||
|
||||
throw Py::RuntimeError("Unknown file extension");
|
||||
//return Py::None();
|
||||
// return Py::None();
|
||||
}
|
||||
|
||||
Py::Object insert(const Py::Tuple& args)
|
||||
{
|
||||
char* Name;
|
||||
const char* DocName;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "ets","utf-8",&Name,&DocName))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "ets", "utf-8", &Name, &DocName))
|
||||
throw Py::Exception();
|
||||
std::string EncodedName = std::string(Name);
|
||||
PyMem_Free(Name);
|
||||
|
||||
try {
|
||||
//Base::Console().Log("Insert in Part with %s",Name);
|
||||
// Base::Console().Log("Insert in Part with %s",Name);
|
||||
Base::FileInfo file(EncodedName.c_str());
|
||||
|
||||
// extract extension
|
||||
if (file.extension().empty())
|
||||
throw Py::RuntimeError("No file extension");
|
||||
|
||||
App::Document *pcDoc = App::GetApplication().getDocument(DocName);
|
||||
App::Document* pcDoc = App::GetApplication().getDocument(DocName);
|
||||
if (!pcDoc) {
|
||||
pcDoc = App::GetApplication().newDocument(DocName);
|
||||
}
|
||||
|
||||
if (file.hasExtension("skf")) {
|
||||
Sketcher::SketchObjectSF *pcFeature = static_cast<Sketcher::SketchObjectSF *>(pcDoc->addObject("Sketcher::SketchObjectSF",file.fileNamePure().c_str()));
|
||||
Sketcher::SketchObjectSF* pcFeature = static_cast<Sketcher::SketchObjectSF*>(
|
||||
pcDoc->addObject("Sketcher::SketchObjectSF", file.fileNamePure().c_str()));
|
||||
pcFeature->SketchFlatFile.setValue(EncodedName.c_str());
|
||||
|
||||
pcDoc->recompute();
|
||||
@@ -113,4 +115,4 @@ PyObject* initModule()
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
} // namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <cmath>
|
||||
# include <QDateTime>
|
||||
#include <QDateTime>
|
||||
#include <cmath>
|
||||
#endif
|
||||
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Writer.h>
|
||||
|
||||
#include "Constraint.h"
|
||||
#include "ConstraintPy.h"
|
||||
@@ -41,21 +41,21 @@ using namespace Base;
|
||||
TYPESYSTEM_SOURCE(Sketcher::Constraint, Base::Persistence)
|
||||
|
||||
Constraint::Constraint()
|
||||
: Value(0.0),
|
||||
Type(None),
|
||||
AlignmentType(Undef),
|
||||
First(GeoEnum::GeoUndef),
|
||||
FirstPos(PointPos::none),
|
||||
Second(GeoEnum::GeoUndef),
|
||||
SecondPos(PointPos::none),
|
||||
Third(GeoEnum::GeoUndef),
|
||||
ThirdPos(PointPos::none),
|
||||
LabelDistance(10.f),
|
||||
LabelPosition(0.f),
|
||||
isDriving(true),
|
||||
InternalAlignmentIndex(-1),
|
||||
isInVirtualSpace(false),
|
||||
isActive(true)
|
||||
: Value(0.0),
|
||||
Type(None),
|
||||
AlignmentType(Undef),
|
||||
First(GeoEnum::GeoUndef),
|
||||
FirstPos(PointPos::none),
|
||||
Second(GeoEnum::GeoUndef),
|
||||
SecondPos(PointPos::none),
|
||||
Third(GeoEnum::GeoUndef),
|
||||
ThirdPos(PointPos::none),
|
||||
LabelDistance(10.f),
|
||||
LabelPosition(0.f),
|
||||
isDriving(true),
|
||||
InternalAlignmentIndex(-1),
|
||||
isInVirtualSpace(false),
|
||||
isActive(true)
|
||||
{
|
||||
// Initialize a random number generator, to avoid Valgrind false positives.
|
||||
static boost::mt19937 ran;
|
||||
@@ -70,14 +70,14 @@ Constraint::Constraint()
|
||||
tag = gen();
|
||||
}
|
||||
|
||||
Constraint *Constraint::clone() const
|
||||
Constraint* Constraint::clone() const
|
||||
{
|
||||
return new Constraint(*this);
|
||||
}
|
||||
|
||||
Constraint *Constraint::copy() const
|
||||
Constraint* Constraint::copy() const
|
||||
{
|
||||
Constraint *temp = new Constraint();
|
||||
Constraint* temp = new Constraint();
|
||||
temp->Value = this->Value;
|
||||
temp->Type = this->Type;
|
||||
temp->AlignmentType = this->AlignmentType;
|
||||
@@ -98,7 +98,7 @@ Constraint *Constraint::copy() const
|
||||
return temp;
|
||||
}
|
||||
|
||||
PyObject *Constraint::getPyObject()
|
||||
PyObject* Constraint::getPyObject()
|
||||
{
|
||||
return new ConstraintPy(new Constraint(*this));
|
||||
}
|
||||
@@ -107,80 +107,79 @@ Quantity Constraint::getPresentationValue() const
|
||||
{
|
||||
Quantity quantity;
|
||||
switch (Type) {
|
||||
case Distance:
|
||||
case Radius:
|
||||
case Diameter:
|
||||
case DistanceX:
|
||||
case DistanceY:
|
||||
quantity.setValue(Value);
|
||||
quantity.setUnit(Unit::Length);
|
||||
break;
|
||||
case Angle:
|
||||
quantity.setValue(toDegrees<double>(Value));
|
||||
quantity.setUnit(Unit::Angle);
|
||||
break;
|
||||
case SnellsLaw:
|
||||
case Weight:
|
||||
quantity.setValue(Value);
|
||||
break;
|
||||
default:
|
||||
quantity.setValue(Value);
|
||||
break;
|
||||
case Distance:
|
||||
case Radius:
|
||||
case Diameter:
|
||||
case DistanceX:
|
||||
case DistanceY:
|
||||
quantity.setValue(Value);
|
||||
quantity.setUnit(Unit::Length);
|
||||
break;
|
||||
case Angle:
|
||||
quantity.setValue(toDegrees<double>(Value));
|
||||
quantity.setUnit(Unit::Angle);
|
||||
break;
|
||||
case SnellsLaw:
|
||||
case Weight:
|
||||
quantity.setValue(Value);
|
||||
break;
|
||||
default:
|
||||
quantity.setValue(Value);
|
||||
break;
|
||||
}
|
||||
|
||||
QuantityFormat format = quantity.getFormat();
|
||||
format.option = QuantityFormat::None;
|
||||
format.format = QuantityFormat::Default;
|
||||
format.precision = 6; // QString's default
|
||||
format.precision = 6;// QString's default
|
||||
quantity.setFormat(format);
|
||||
return quantity;
|
||||
}
|
||||
|
||||
unsigned int Constraint::getMemSize () const
|
||||
unsigned int Constraint::getMemSize() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Constraint::Save (Writer &writer) const
|
||||
void Constraint::Save(Writer& writer) const
|
||||
{
|
||||
std::string encodeName = encodeAttribute(Name);
|
||||
writer.Stream() << writer.ind() << "<Constrain "
|
||||
<< "Name=\"" << encodeName << "\" "
|
||||
<< "Type=\"" << (int)Type << "\" ";
|
||||
if(this->Type==InternalAlignment)
|
||||
writer.Stream()
|
||||
<< "InternalAlignmentType=\"" << (int)AlignmentType << "\" "
|
||||
<< "InternalAlignmentIndex=\"" << InternalAlignmentIndex << "\" ";
|
||||
writer.Stream()
|
||||
<< "Value=\"" << Value << "\" "
|
||||
<< "First=\"" << First << "\" "
|
||||
<< "FirstPos=\"" << (int) FirstPos << "\" "
|
||||
<< "Second=\"" << Second << "\" "
|
||||
<< "SecondPos=\"" << (int) SecondPos << "\" "
|
||||
<< "Third=\"" << Third << "\" "
|
||||
<< "ThirdPos=\"" << (int) ThirdPos << "\" "
|
||||
<< "LabelDistance=\"" << LabelDistance << "\" "
|
||||
<< "LabelPosition=\"" << LabelPosition << "\" "
|
||||
<< "IsDriving=\"" << (int)isDriving << "\" "
|
||||
<< "IsInVirtualSpace=\"" << (int)isInVirtualSpace << "\" "
|
||||
<< "IsActive=\"" << (int)isActive << "\" />"
|
||||
writer.Stream() << writer.ind() << "<Constrain "
|
||||
<< "Name=\"" << encodeName << "\" "
|
||||
<< "Type=\"" << (int)Type << "\" ";
|
||||
if (this->Type == InternalAlignment)
|
||||
writer.Stream() << "InternalAlignmentType=\"" << (int)AlignmentType << "\" "
|
||||
<< "InternalAlignmentIndex=\"" << InternalAlignmentIndex << "\" ";
|
||||
writer.Stream() << "Value=\"" << Value << "\" "
|
||||
<< "First=\"" << First << "\" "
|
||||
<< "FirstPos=\"" << (int)FirstPos << "\" "
|
||||
<< "Second=\"" << Second << "\" "
|
||||
<< "SecondPos=\"" << (int)SecondPos << "\" "
|
||||
<< "Third=\"" << Third << "\" "
|
||||
<< "ThirdPos=\"" << (int)ThirdPos << "\" "
|
||||
<< "LabelDistance=\"" << LabelDistance << "\" "
|
||||
<< "LabelPosition=\"" << LabelPosition << "\" "
|
||||
<< "IsDriving=\"" << (int)isDriving << "\" "
|
||||
<< "IsInVirtualSpace=\"" << (int)isInVirtualSpace << "\" "
|
||||
<< "IsActive=\"" << (int)isActive << "\" />"
|
||||
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void Constraint::Restore(XMLReader &reader)
|
||||
void Constraint::Restore(XMLReader& reader)
|
||||
{
|
||||
reader.readElement("Constrain");
|
||||
Name = reader.getAttribute("Name");
|
||||
Type = static_cast<ConstraintType>(reader.getAttributeAsInteger("Type"));
|
||||
Value = reader.getAttributeAsFloat("Value");
|
||||
First = reader.getAttributeAsInteger("First");
|
||||
FirstPos = static_cast<PointPos>(reader.getAttributeAsInteger("FirstPos"));
|
||||
Second = reader.getAttributeAsInteger("Second");
|
||||
Name = reader.getAttribute("Name");
|
||||
Type = static_cast<ConstraintType>(reader.getAttributeAsInteger("Type"));
|
||||
Value = reader.getAttributeAsFloat("Value");
|
||||
First = reader.getAttributeAsInteger("First");
|
||||
FirstPos = static_cast<PointPos>(reader.getAttributeAsInteger("FirstPos"));
|
||||
Second = reader.getAttributeAsInteger("Second");
|
||||
SecondPos = static_cast<PointPos>(reader.getAttributeAsInteger("SecondPos"));
|
||||
|
||||
if(this->Type==InternalAlignment) {
|
||||
AlignmentType = static_cast<InternalAlignmentType>(reader.getAttributeAsInteger("InternalAlignmentType"));
|
||||
if (this->Type == InternalAlignment) {
|
||||
AlignmentType = static_cast<InternalAlignmentType>(
|
||||
reader.getAttributeAsInteger("InternalAlignmentType"));
|
||||
|
||||
if (reader.hasAttribute("InternalAlignmentIndex"))
|
||||
InternalAlignmentIndex = reader.getAttributeAsInteger("InternalAlignmentIndex");
|
||||
@@ -191,7 +190,7 @@ void Constraint::Restore(XMLReader &reader)
|
||||
|
||||
// read the third geo group if present
|
||||
if (reader.hasAttribute("Third")) {
|
||||
Third = reader.getAttributeAsInteger("Third");
|
||||
Third = reader.getAttributeAsInteger("Third");
|
||||
ThirdPos = static_cast<PointPos>(reader.getAttributeAsInteger("ThirdPos"));
|
||||
}
|
||||
|
||||
|
||||
@@ -36,11 +36,13 @@
|
||||
namespace Sketcher
|
||||
{
|
||||
/*!
|
||||
Important note: New constraint types must be always added at the end but before 'NumConstraintTypes'.
|
||||
This is mandatory in order to keep the handling of constraint types upward compatible which means that
|
||||
this program version ignores later introduced constraint types when reading them from a project file.
|
||||
Important note: New constraint types must be always added at the end but before
|
||||
'NumConstraintTypes'. This is mandatory in order to keep the handling of constraint types upward
|
||||
compatible which means that this program version ignores later introduced constraint types when
|
||||
reading them from a project file.
|
||||
*/
|
||||
enum ConstraintType : int {
|
||||
enum ConstraintType : int
|
||||
{
|
||||
None = 0,
|
||||
Coincident = 1,
|
||||
Horizontal = 2,
|
||||
@@ -61,26 +63,27 @@ enum ConstraintType : int {
|
||||
Block = 17,
|
||||
Diameter = 18,
|
||||
Weight = 19,
|
||||
NumConstraintTypes // must be the last item!
|
||||
NumConstraintTypes// must be the last item!
|
||||
};
|
||||
|
||||
enum InternalAlignmentType {
|
||||
Undef = 0,
|
||||
EllipseMajorDiameter = 1,
|
||||
EllipseMinorDiameter = 2,
|
||||
EllipseFocus1 = 3,
|
||||
EllipseFocus2 = 4,
|
||||
HyperbolaMajor = 5,
|
||||
HyperbolaMinor = 6,
|
||||
HyperbolaFocus = 7,
|
||||
ParabolaFocus = 8,
|
||||
BSplineControlPoint = 9,
|
||||
BSplineKnotPoint = 10,
|
||||
ParabolaFocalAxis = 11,
|
||||
NumInternalAlignmentType // must be the last item!
|
||||
enum InternalAlignmentType
|
||||
{
|
||||
Undef = 0,
|
||||
EllipseMajorDiameter = 1,
|
||||
EllipseMinorDiameter = 2,
|
||||
EllipseFocus1 = 3,
|
||||
EllipseFocus2 = 4,
|
||||
HyperbolaMajor = 5,
|
||||
HyperbolaMinor = 6,
|
||||
HyperbolaFocus = 7,
|
||||
ParabolaFocus = 8,
|
||||
BSplineControlPoint = 9,
|
||||
BSplineKnotPoint = 10,
|
||||
ParabolaFocalAxis = 11,
|
||||
NumInternalAlignmentType// must be the last item!
|
||||
};
|
||||
|
||||
class SketcherExport Constraint : public Base::Persistence
|
||||
class SketcherExport Constraint: public Base::Persistence
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -90,7 +93,7 @@ public:
|
||||
|
||||
// Constraints objects explicitly not copiable with standard methods
|
||||
// Copy constructor is private for internal use only
|
||||
Constraint &operator =(const Constraint &a) = delete;
|
||||
Constraint& operator=(const Constraint& a) = delete;
|
||||
|
||||
// Constraints objects explicitly not movable
|
||||
Constraint(Constraint&&) = delete;
|
||||
@@ -98,55 +101,92 @@ public:
|
||||
|
||||
~Constraint() override = default;
|
||||
|
||||
Constraint *clone() const; // does copy the tag, it will be treated as a rename by the expression engine.
|
||||
Constraint *copy() const; // does not copy the tag, but generates a new one
|
||||
// does copy the tag, it will be treated as a rename by the expression engine.
|
||||
Constraint* clone() const;
|
||||
// does not copy the tag, but generates a new one
|
||||
Constraint* copy() const;
|
||||
|
||||
// from base class
|
||||
unsigned int getMemSize() const override;
|
||||
void Save(Base::Writer &/*writer*/) const override;
|
||||
void Restore(Base::XMLReader &/*reader*/) override;
|
||||
void Save(Base::Writer& /*writer*/) const override;
|
||||
void Restore(Base::XMLReader& /*reader*/) override;
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
Base::Quantity getPresentationValue() const;
|
||||
inline void setValue(double newValue) {
|
||||
inline void setValue(double newValue)
|
||||
{
|
||||
Value = newValue;
|
||||
}
|
||||
inline double getValue() const {
|
||||
inline double getValue() const
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
|
||||
inline bool isDimensional() const {
|
||||
return Type == Distance || Type == DistanceX || Type == DistanceY ||
|
||||
Type == Radius || Type == Diameter || Type == Angle || Type == SnellsLaw || Type == Weight;
|
||||
inline bool isDimensional() const
|
||||
{
|
||||
return Type == Distance || Type == DistanceX || Type == DistanceY || Type == Radius
|
||||
|| Type == Diameter || Type == Angle || Type == SnellsLaw || Type == Weight;
|
||||
}
|
||||
|
||||
/// utility function to swap the index in First/Second/Third of the provided constraint from the fromGeoId GeoId to toGeoId
|
||||
/// utility function to swap the index in First/Second/Third of the provided constraint from the
|
||||
/// fromGeoId GeoId to toGeoId
|
||||
void substituteIndex(int fromGeoId, int toGeoId);
|
||||
|
||||
std::string typeToString() const {return typeToString(Type);}
|
||||
std::string typeToString() const
|
||||
{
|
||||
return typeToString(Type);
|
||||
}
|
||||
static std::string typeToString(ConstraintType type);
|
||||
|
||||
std::string internalAlignmentTypeToString() const {return internalAlignmentTypeToString(AlignmentType);}
|
||||
std::string internalAlignmentTypeToString() const
|
||||
{
|
||||
return internalAlignmentTypeToString(AlignmentType);
|
||||
}
|
||||
static std::string internalAlignmentTypeToString(InternalAlignmentType alignment);
|
||||
|
||||
friend class PropertyConstraintList;
|
||||
|
||||
private:
|
||||
Constraint(const Constraint&) = default; // only for internal use
|
||||
Constraint(const Constraint&) = default;// only for internal use
|
||||
|
||||
private:
|
||||
double Value;
|
||||
|
||||
constexpr static std::array<const char *,ConstraintType::NumConstraintTypes> type2str {
|
||||
{ "None", "Horizontal", "Vertical","Parallel", "Tangent", "Distance", "DistanceX", "DistanceY", "Angle", "Perpendicular", "Radius",
|
||||
"Equal", "PointOnObject", "Symmetric", "InternalAlignment", "SnellsLaw", "Block", "Diameter", "Weight"}
|
||||
};
|
||||
constexpr static std::array<const char*, ConstraintType::NumConstraintTypes> type2str {
|
||||
{"None",
|
||||
"Horizontal",
|
||||
"Vertical",
|
||||
"Parallel",
|
||||
"Tangent",
|
||||
"Distance",
|
||||
"DistanceX",
|
||||
"DistanceY",
|
||||
"Angle",
|
||||
"Perpendicular",
|
||||
"Radius",
|
||||
"Equal",
|
||||
"PointOnObject",
|
||||
"Symmetric",
|
||||
"InternalAlignment",
|
||||
"SnellsLaw",
|
||||
"Block",
|
||||
"Diameter",
|
||||
"Weight"}};
|
||||
|
||||
constexpr static std::array<const char *,InternalAlignmentType::NumInternalAlignmentType> internalAlignmentType2str {
|
||||
{ "Undef", "EllipseMajorDiameter", "EllipseMinorDiameter", "EllipseFocus1", "EllipseFocus2", "HyperbolaMajor", "HyperbolaMinor",
|
||||
"HyperbolaFocus", "ParabolaFocus", "BSplineControlPoint", "BSplineKnotPoint", "ParabolaFocalAxis"}
|
||||
};
|
||||
constexpr static std::array<const char*, InternalAlignmentType::NumInternalAlignmentType>
|
||||
internalAlignmentType2str {{"Undef",
|
||||
"EllipseMajorDiameter",
|
||||
"EllipseMinorDiameter",
|
||||
"EllipseFocus1",
|
||||
"EllipseFocus2",
|
||||
"HyperbolaMajor",
|
||||
"HyperbolaMinor",
|
||||
"HyperbolaFocus",
|
||||
"ParabolaFocus",
|
||||
"BSplineControlPoint",
|
||||
"BSplineKnotPoint",
|
||||
"ParabolaFocalAxis"}};
|
||||
|
||||
public:
|
||||
ConstraintType Type;
|
||||
@@ -161,7 +201,9 @@ public:
|
||||
float LabelDistance;
|
||||
float LabelPosition;
|
||||
bool isDriving;
|
||||
int InternalAlignmentIndex; // Note: for InternalAlignment Type this index indexes equal internal geometry elements (e.g. index of pole in a bspline). It is not a GeoId!!
|
||||
// Note: for InternalAlignment Type this index indexes equal internal geometry elements (e.g.
|
||||
// index of pole in a bspline). It is not a GeoId!!
|
||||
int InternalAlignmentIndex;
|
||||
bool isInVirtualSpace;
|
||||
|
||||
bool isActive;
|
||||
@@ -170,7 +212,7 @@ protected:
|
||||
boost::uuids::uuid tag;
|
||||
};
|
||||
|
||||
} //namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCHER_CONSTRAINT_H
|
||||
#endif// SKETCHER_CONSTRAINT_H
|
||||
|
||||
@@ -22,18 +22,19 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#include <Base/QuantityPy.h>
|
||||
|
||||
#include "ConstraintPy.h"
|
||||
|
||||
#include "ConstraintPy.cpp"
|
||||
|
||||
|
||||
using namespace Sketcher;
|
||||
|
||||
PyObject *ConstraintPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
PyObject* ConstraintPy::PyMake(struct _typeobject*, PyObject*, PyObject*)// Python wrapper
|
||||
{
|
||||
// create a new instance of ConstraintPy and the Twin object
|
||||
return new ConstraintPy(new Constraint);
|
||||
@@ -48,17 +49,17 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
|
||||
PyErr_Clear();
|
||||
|
||||
char *ConstraintType;
|
||||
int FirstIndex = GeoEnum::GeoUndef;
|
||||
int FirstPos = static_cast<int>(PointPos::none);
|
||||
int SecondIndex= GeoEnum::GeoUndef;
|
||||
int SecondPos = static_cast<int>(PointPos::none);
|
||||
int ThirdIndex = GeoEnum::GeoUndef;
|
||||
int ThirdPos = static_cast<int>(PointPos::none);
|
||||
double Value = 0;
|
||||
char* ConstraintType;
|
||||
int FirstIndex = GeoEnum::GeoUndef;
|
||||
int FirstPos = static_cast<int>(PointPos::none);
|
||||
int SecondIndex = GeoEnum::GeoUndef;
|
||||
int SecondPos = static_cast<int>(PointPos::none);
|
||||
int ThirdIndex = GeoEnum::GeoUndef;
|
||||
int ThirdPos = static_cast<int>(PointPos::none);
|
||||
double Value = 0;
|
||||
int intArg1, intArg2, intArg3, intArg4, intArg5;
|
||||
// Note: In Python 2.x PyArg_ParseTuple prints a warning if a float is given but an integer is expected.
|
||||
// This means we must use a PyObject and check afterwards if it's a float or integer.
|
||||
// Note: In Python 2.x PyArg_ParseTuple prints a warning if a float is given but an integer is
|
||||
// expected. This means we must use a PyObject and check afterwards if it's a float or integer.
|
||||
PyObject* index_or_value;
|
||||
PyObject* oNumArg4;
|
||||
PyObject* oNumArg5;
|
||||
@@ -66,17 +67,17 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
|
||||
// ConstraintType, GeoIndex
|
||||
if (PyArg_ParseTuple(args, "si", &ConstraintType, &FirstIndex)) {
|
||||
if (strcmp("Horizontal",ConstraintType) == 0) {
|
||||
if (strcmp("Horizontal", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Horizontal;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp("Vertical",ConstraintType) == 0) {
|
||||
else if (strcmp("Vertical", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Vertical;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp("Block",ConstraintType) == 0) {
|
||||
else if (strcmp("Block", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Block;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
return 0;
|
||||
@@ -89,32 +90,32 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
if (PyLong_Check(index_or_value)) {
|
||||
SecondIndex = PyLong_AsLong(index_or_value);
|
||||
bool valid = false;
|
||||
if (strcmp("Tangent",ConstraintType) == 0) {
|
||||
if (strcmp("Tangent", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Tangent;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("Parallel",ConstraintType) == 0) {
|
||||
else if (strcmp("Parallel", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Parallel;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("Perpendicular",ConstraintType) == 0) {
|
||||
else if (strcmp("Perpendicular", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Perpendicular;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("Equal",ConstraintType) == 0) {
|
||||
else if (strcmp("Equal", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Equal;
|
||||
valid = true;
|
||||
}
|
||||
else if (strstr(ConstraintType,"InternalAlignment")) {
|
||||
else if (strstr(ConstraintType, "InternalAlignment")) {
|
||||
this->getConstraintPtr()->Type = InternalAlignment;
|
||||
|
||||
valid = true;
|
||||
if(strstr(ConstraintType,"EllipseMajorDiameter"))
|
||||
this->getConstraintPtr()->AlignmentType=EllipseMajorDiameter;
|
||||
else if(strstr(ConstraintType,"EllipseMinorDiameter"))
|
||||
this->getConstraintPtr()->AlignmentType=EllipseMinorDiameter;
|
||||
if (strstr(ConstraintType, "EllipseMajorDiameter"))
|
||||
this->getConstraintPtr()->AlignmentType = EllipseMajorDiameter;
|
||||
else if (strstr(ConstraintType, "EllipseMinorDiameter"))
|
||||
this->getConstraintPtr()->AlignmentType = EllipseMinorDiameter;
|
||||
else {
|
||||
this->getConstraintPtr()->AlignmentType=Undef;
|
||||
this->getConstraintPtr()->AlignmentType = Undef;
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
@@ -126,45 +127,46 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
}
|
||||
}
|
||||
// ConstraintType, GeoIndex, Value
|
||||
if (PyNumber_Check(index_or_value)) { // can be float or int
|
||||
if (PyNumber_Check(index_or_value)) {// can be float or int
|
||||
Value = PyFloat_AsDouble(index_or_value);
|
||||
bool valid = false;
|
||||
if (strcmp("Distance",ConstraintType) == 0 ) {
|
||||
if (strcmp("Distance", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Distance;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("Angle",ConstraintType) == 0 ) {
|
||||
else if (strcmp("Angle", ConstraintType) == 0) {
|
||||
if (PyObject_TypeCheck(index_or_value, &(Base::QuantityPy::Type))) {
|
||||
Base::Quantity q = *(static_cast<Base::QuantityPy*>(index_or_value)->getQuantityPtr());
|
||||
Base::Quantity q =
|
||||
*(static_cast<Base::QuantityPy*>(index_or_value)->getQuantityPtr());
|
||||
if (q.getUnit() == Base::Unit::Angle)
|
||||
Value = q.getValueAs(Base::Quantity::Radian);
|
||||
}
|
||||
this->getConstraintPtr()->Type = Angle;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("DistanceX",ConstraintType) == 0) {
|
||||
else if (strcmp("DistanceX", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = DistanceX;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("DistanceY",ConstraintType) == 0) {
|
||||
else if (strcmp("DistanceY", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = DistanceY;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("Radius",ConstraintType) == 0) {
|
||||
else if (strcmp("Radius", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Radius;
|
||||
// set a value that is out of range of result of atan2
|
||||
// this value is handled in ViewProviderSketch
|
||||
this->getConstraintPtr()->LabelPosition = 10;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("Diameter",ConstraintType) == 0) {
|
||||
else if (strcmp("Diameter", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Diameter;
|
||||
// set a value that is out of range of result of atan2
|
||||
// this value is handled in ViewProviderSketch
|
||||
this->getConstraintPtr()->LabelPosition = 10;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("Weight",ConstraintType) == 0) {
|
||||
else if (strcmp("Weight", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Weight;
|
||||
// set a value that is out of range of result of atan2
|
||||
// this value is handled in ViewProviderSketch
|
||||
@@ -172,7 +174,7 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
valid = true;
|
||||
}
|
||||
if (valid) {
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->setValue(Value);
|
||||
return 0;
|
||||
}
|
||||
@@ -198,65 +200,66 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
this->getConstraintPtr()->Type = PointOnObject;
|
||||
valid = true;
|
||||
}
|
||||
else if (strstr(ConstraintType,"InternalAlignment")) {
|
||||
else if (strstr(ConstraintType, "InternalAlignment")) {
|
||||
this->getConstraintPtr()->Type = InternalAlignment;
|
||||
|
||||
valid = true;
|
||||
|
||||
if(strstr(ConstraintType,"EllipseFocus1"))
|
||||
this->getConstraintPtr()->AlignmentType=EllipseFocus1;
|
||||
else if(strstr(ConstraintType,"EllipseFocus2"))
|
||||
this->getConstraintPtr()->AlignmentType=EllipseFocus2;
|
||||
if (strstr(ConstraintType, "EllipseFocus1"))
|
||||
this->getConstraintPtr()->AlignmentType = EllipseFocus1;
|
||||
else if (strstr(ConstraintType, "EllipseFocus2"))
|
||||
this->getConstraintPtr()->AlignmentType = EllipseFocus2;
|
||||
else {
|
||||
this->getConstraintPtr()->AlignmentType=Undef;
|
||||
this->getConstraintPtr()->AlignmentType = Undef;
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
if (valid) {
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(FirstPos);
|
||||
this->getConstraintPtr()->Second = SecondIndex;
|
||||
this->getConstraintPtr()->Second = SecondIndex;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// ConstraintType, GeoIndex1, GeoIndex2, Value
|
||||
// ConstraintType, GeoIndex, PosIndex, Value
|
||||
if (PyNumber_Check(index_or_value)) { // can be float or int
|
||||
if (PyNumber_Check(index_or_value)) {// can be float or int
|
||||
SecondIndex = any_index;
|
||||
Value = PyFloat_AsDouble(index_or_value);
|
||||
if (strcmp("Angle",ConstraintType) == 0) {
|
||||
if (strcmp("Angle", ConstraintType) == 0) {
|
||||
if (PyObject_TypeCheck(index_or_value, &(Base::QuantityPy::Type))) {
|
||||
Base::Quantity q = *(static_cast<Base::QuantityPy*>(index_or_value)->getQuantityPtr());
|
||||
Base::Quantity q =
|
||||
*(static_cast<Base::QuantityPy*>(index_or_value)->getQuantityPtr());
|
||||
if (q.getUnit() == Base::Unit::Angle)
|
||||
Value = q.getValueAs(Base::Quantity::Radian);
|
||||
}
|
||||
this->getConstraintPtr()->Type = Angle;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->Type = Angle;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->Second = SecondIndex;
|
||||
this->getConstraintPtr()->setValue(Value);
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp("Distance",ConstraintType) == 0) {
|
||||
else if (strcmp("Distance", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Distance;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->Second = SecondIndex;
|
||||
this->getConstraintPtr()->setValue(Value);
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp("DistanceX",ConstraintType) == 0) {
|
||||
else if (strcmp("DistanceX", ConstraintType) == 0) {
|
||||
FirstPos = SecondIndex;
|
||||
SecondIndex = -1;
|
||||
this->getConstraintPtr()->Type = DistanceX;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(FirstPos);
|
||||
this->getConstraintPtr()->setValue(Value);
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp("DistanceY",ConstraintType) == 0) {
|
||||
else if (strcmp("DistanceY", ConstraintType) == 0) {
|
||||
FirstPos = SecondIndex;
|
||||
SecondIndex = -1;
|
||||
this->getConstraintPtr()->Type = DistanceY;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(FirstPos);
|
||||
this->getConstraintPtr()->setValue(Value);
|
||||
return 0;
|
||||
@@ -292,68 +295,67 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
}
|
||||
else if (strcmp("TangentViaPoint", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Tangent;
|
||||
//valid = true;//non-standard assignment
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->Second = intArg2;
|
||||
// valid = true;//non-standard assignment
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->Second = intArg2;
|
||||
this->getConstraintPtr()->SecondPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->Third = intArg3;
|
||||
this->getConstraintPtr()->ThirdPos = static_cast<Sketcher::PointPos>(intArg4);
|
||||
this->getConstraintPtr()->Third = intArg3;
|
||||
this->getConstraintPtr()->ThirdPos = static_cast<Sketcher::PointPos>(intArg4);
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp("PerpendicularViaPoint", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Perpendicular;
|
||||
//valid = true;//non-standard assignment
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->Second = intArg2;
|
||||
// valid = true;//non-standard assignment
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->Second = intArg2;
|
||||
this->getConstraintPtr()->SecondPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->Third = intArg3;
|
||||
this->getConstraintPtr()->ThirdPos = static_cast<Sketcher::PointPos>(intArg4);
|
||||
this->getConstraintPtr()->Third = intArg3;
|
||||
this->getConstraintPtr()->ThirdPos = static_cast<Sketcher::PointPos>(intArg4);
|
||||
return 0;
|
||||
}
|
||||
else if (strstr(ConstraintType,"InternalAlignment")) { // InteralAlignment with InternalElementIndex argument
|
||||
else if (strstr(ConstraintType, "InternalAlignment")) {// InteralAlignment with
|
||||
// InternalElementIndex argument
|
||||
this->getConstraintPtr()->Type = InternalAlignment;
|
||||
|
||||
valid = true;
|
||||
|
||||
if (strstr(ConstraintType,"BSplineControlPoint")) {
|
||||
this->getConstraintPtr()->AlignmentType=BSplineControlPoint;
|
||||
if (strstr(ConstraintType, "BSplineControlPoint")) {
|
||||
this->getConstraintPtr()->AlignmentType = BSplineControlPoint;
|
||||
}
|
||||
else if (strstr(ConstraintType,"BSplineKnotPoint")) {
|
||||
this->getConstraintPtr()->AlignmentType=BSplineKnotPoint;
|
||||
else if (strstr(ConstraintType, "BSplineKnotPoint")) {
|
||||
this->getConstraintPtr()->AlignmentType = BSplineKnotPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->getConstraintPtr()->AlignmentType=Undef;
|
||||
else {
|
||||
this->getConstraintPtr()->AlignmentType = Undef;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(intArg2);
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(intArg2);
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->InternalAlignmentIndex = intArg4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
if (valid) {
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(intArg2);
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(intArg2);
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->SecondPos = static_cast<Sketcher::PointPos>(intArg4);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// ConstraintType, GeoIndex1, PosIndex1, GeoIndex2, Value
|
||||
if (PyNumber_Check(oNumArg4)) { // can be float or int
|
||||
if (PyNumber_Check(oNumArg4)) {// can be float or int
|
||||
Value = PyFloat_AsDouble(oNumArg4);
|
||||
if (strcmp("Distance",ConstraintType) == 0 ) {
|
||||
if (strcmp("Distance", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Distance;
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(intArg2);
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->setValue(Value);
|
||||
return 0;
|
||||
}
|
||||
@@ -361,66 +363,69 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
}
|
||||
PyErr_Clear();
|
||||
|
||||
if (PyArg_ParseTuple(args, "siiiiO", &ConstraintType, &intArg1, &intArg2, &intArg3, &intArg4, &oNumArg5)) {
|
||||
if (PyArg_ParseTuple(
|
||||
args, "siiiiO", &ConstraintType, &intArg1, &intArg2, &intArg3, &intArg4, &oNumArg5)) {
|
||||
// ConstraintType, GeoIndex1, PosIndex1, GeoIndex2, PosIndex2, GeoIndex3
|
||||
if (PyLong_Check(oNumArg5)) {
|
||||
intArg5 = PyLong_AsLong(oNumArg5);
|
||||
if (strcmp("Symmetric",ConstraintType) == 0 ) {
|
||||
if (strcmp("Symmetric", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Symmetric;
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(intArg2);
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(intArg2);
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->SecondPos = static_cast<Sketcher::PointPos>(intArg4);
|
||||
this->getConstraintPtr()->Third = intArg5;
|
||||
this->getConstraintPtr()->Third = intArg5;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// ConstraintType, GeoIndex1, PosIndex1, GeoIndex2, PosIndex2, Value
|
||||
if (PyNumber_Check(oNumArg5)) { // can be float or int
|
||||
if (PyNumber_Check(oNumArg5)) {// can be float or int
|
||||
Value = PyFloat_AsDouble(oNumArg5);
|
||||
bool valid=false;
|
||||
if (strcmp("Distance",ConstraintType) == 0 ) {
|
||||
bool valid = false;
|
||||
if (strcmp("Distance", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Distance;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("DistanceX",ConstraintType) == 0) {
|
||||
else if (strcmp("DistanceX", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = DistanceX;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("DistanceY",ConstraintType) == 0) {
|
||||
else if (strcmp("DistanceY", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = DistanceY;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("Angle",ConstraintType) == 0 ) {
|
||||
else if (strcmp("Angle", ConstraintType) == 0) {
|
||||
if (PyObject_TypeCheck(oNumArg5, &(Base::QuantityPy::Type))) {
|
||||
Base::Quantity q = *(static_cast<Base::QuantityPy*>(oNumArg5)->getQuantityPtr());
|
||||
Base::Quantity q =
|
||||
*(static_cast<Base::QuantityPy*>(oNumArg5)->getQuantityPtr());
|
||||
if (q.getUnit() == Base::Unit::Angle)
|
||||
Value = q.getValueAs(Base::Quantity::Radian);
|
||||
}
|
||||
this->getConstraintPtr()->Type = Angle;
|
||||
valid = true;
|
||||
}
|
||||
else if (strcmp("AngleViaPoint",ConstraintType) == 0 ) {
|
||||
else if (strcmp("AngleViaPoint", ConstraintType) == 0) {
|
||||
if (PyObject_TypeCheck(oNumArg5, &(Base::QuantityPy::Type))) {
|
||||
Base::Quantity q = *(static_cast<Base::QuantityPy*>(oNumArg5)->getQuantityPtr());
|
||||
Base::Quantity q =
|
||||
*(static_cast<Base::QuantityPy*>(oNumArg5)->getQuantityPtr());
|
||||
if (q.getUnit() == Base::Unit::Angle)
|
||||
Value = q.getValueAs(Base::Quantity::Radian);
|
||||
}
|
||||
this->getConstraintPtr()->Type = Angle;
|
||||
//valid = true;//non-standard assignment
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->Second = intArg2; //let's goof up all the terminology =)
|
||||
// valid = true;//non-standard assignment
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->Second = intArg2;// let's goof up all the terminology =)
|
||||
this->getConstraintPtr()->SecondPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->Third = intArg3;
|
||||
this->getConstraintPtr()->ThirdPos = static_cast<Sketcher::PointPos>(intArg4);
|
||||
this->getConstraintPtr()->Third = intArg3;
|
||||
this->getConstraintPtr()->ThirdPos = static_cast<Sketcher::PointPos>(intArg4);
|
||||
this->getConstraintPtr()->setValue(Value);
|
||||
return 0;
|
||||
}
|
||||
if (valid) {
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(intArg2);
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(intArg2);
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->SecondPos = static_cast<Sketcher::PointPos>(intArg4);
|
||||
this->getConstraintPtr()->setValue(Value);
|
||||
return 0;
|
||||
@@ -429,31 +434,39 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
}
|
||||
PyErr_Clear();
|
||||
|
||||
if (PyArg_ParseTuple(args, "siiiiiO", &ConstraintType, &FirstIndex, &FirstPos, &SecondIndex, &SecondPos, &ThirdIndex, &index_or_value)) {
|
||||
if (PyArg_ParseTuple(args,
|
||||
"siiiiiO",
|
||||
&ConstraintType,
|
||||
&FirstIndex,
|
||||
&FirstPos,
|
||||
&SecondIndex,
|
||||
&SecondPos,
|
||||
&ThirdIndex,
|
||||
&index_or_value)) {
|
||||
if (PyLong_Check(index_or_value)) {
|
||||
ThirdPos = PyLong_AsLong(index_or_value);
|
||||
// ConstraintType, GeoIndex1, PosIndex1, GeoIndex2, PosIndex2, GeoIndex3, PosIndex3
|
||||
if (strcmp("Symmetric",ConstraintType) == 0 ) {
|
||||
if (strcmp("Symmetric", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = Symmetric;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(FirstPos);
|
||||
this->getConstraintPtr()->Second = SecondIndex;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(FirstPos);
|
||||
this->getConstraintPtr()->Second = SecondIndex;
|
||||
this->getConstraintPtr()->SecondPos = static_cast<Sketcher::PointPos>(SecondPos);
|
||||
this->getConstraintPtr()->Third = ThirdIndex;
|
||||
this->getConstraintPtr()->ThirdPos = static_cast<Sketcher::PointPos>(ThirdPos);
|
||||
this->getConstraintPtr()->Third = ThirdIndex;
|
||||
this->getConstraintPtr()->ThirdPos = static_cast<Sketcher::PointPos>(ThirdPos);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (PyNumber_Check(index_or_value)) { // can be float or int
|
||||
if (PyNumber_Check(index_or_value)) {// can be float or int
|
||||
Value = PyFloat_AsDouble(index_or_value);
|
||||
if (strcmp("SnellsLaw",ConstraintType) == 0 ) {
|
||||
if (strcmp("SnellsLaw", ConstraintType) == 0) {
|
||||
this->getConstraintPtr()->Type = SnellsLaw;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(FirstPos);
|
||||
this->getConstraintPtr()->Second = SecondIndex;
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(FirstPos);
|
||||
this->getConstraintPtr()->Second = SecondIndex;
|
||||
this->getConstraintPtr()->SecondPos = static_cast<Sketcher::PointPos>(SecondPos);
|
||||
this->getConstraintPtr()->Third = ThirdIndex;
|
||||
this->getConstraintPtr()->ThirdPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->Third = ThirdIndex;
|
||||
this->getConstraintPtr()->ThirdPos = Sketcher::PointPos::none;
|
||||
this->getConstraintPtr()->setValue(Value);
|
||||
return 0;
|
||||
}
|
||||
@@ -476,81 +489,171 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
std::string ConstraintPy::representation() const
|
||||
{
|
||||
std::stringstream result;
|
||||
result << "<Constraint " ;
|
||||
switch(this->getConstraintPtr()->Type) {
|
||||
case None : result << "'None'>";break;
|
||||
case DistanceX : result << "'DistanceX'>";break;
|
||||
case DistanceY : result << "'DistanceY'>";break;
|
||||
case Coincident : result << "'Coincident'>";break;
|
||||
case Horizontal : result << "'Horizontal' (" << getConstraintPtr()->First << ")>";break;
|
||||
case Vertical : result << "'Vertical' (" << getConstraintPtr()->First << ")>";break;
|
||||
case Block : result << "'Block' (" << getConstraintPtr()->First << ")>";break;
|
||||
case Radius : result << "'Radius'>";break;
|
||||
case Diameter : result << "'Diameter'>";break;
|
||||
case Weight : result << "'Weight'>";break;
|
||||
case Parallel : result << "'Parallel'>";break;
|
||||
case Tangent :
|
||||
result << "<Constraint ";
|
||||
switch (this->getConstraintPtr()->Type) {
|
||||
case None:
|
||||
result << "'None'>";
|
||||
break;
|
||||
case DistanceX:
|
||||
result << "'DistanceX'>";
|
||||
break;
|
||||
case DistanceY:
|
||||
result << "'DistanceY'>";
|
||||
break;
|
||||
case Coincident:
|
||||
result << "'Coincident'>";
|
||||
break;
|
||||
case Horizontal:
|
||||
result << "'Horizontal' (" << getConstraintPtr()->First << ")>";
|
||||
break;
|
||||
case Vertical:
|
||||
result << "'Vertical' (" << getConstraintPtr()->First << ")>";
|
||||
break;
|
||||
case Block:
|
||||
result << "'Block' (" << getConstraintPtr()->First << ")>";
|
||||
break;
|
||||
case Radius:
|
||||
result << "'Radius'>";
|
||||
break;
|
||||
case Diameter:
|
||||
result << "'Diameter'>";
|
||||
break;
|
||||
case Weight:
|
||||
result << "'Weight'>";
|
||||
break;
|
||||
case Parallel:
|
||||
result << "'Parallel'>";
|
||||
break;
|
||||
case Tangent:
|
||||
if (this->getConstraintPtr()->Third == GeoEnum::GeoUndef)
|
||||
result << "'Tangent'>";
|
||||
else
|
||||
result << "'TangentViaPoint'>";
|
||||
break;
|
||||
case Perpendicular :
|
||||
break;
|
||||
case Perpendicular:
|
||||
if (this->getConstraintPtr()->Third == GeoEnum::GeoUndef)
|
||||
result << "'Perpendicular'>";
|
||||
else
|
||||
result << "'PerpendicularViaPoint'>";
|
||||
break;
|
||||
case Distance : result << "'Distance'>";break;
|
||||
case Angle :
|
||||
break;
|
||||
case Distance:
|
||||
result << "'Distance'>";
|
||||
break;
|
||||
case Angle:
|
||||
if (this->getConstraintPtr()->Third == GeoEnum::GeoUndef)
|
||||
result << "'Angle'>";
|
||||
else
|
||||
result << "'AngleViaPoint'>";
|
||||
break;
|
||||
case Symmetric : result << "'Symmetric'>"; break;
|
||||
case SnellsLaw : result << "'SnellsLaw'>"; break;
|
||||
case InternalAlignment :
|
||||
switch(this->getConstraintPtr()->AlignmentType) {
|
||||
case Undef : result << "'InternalAlignment:Undef'>";break;
|
||||
case EllipseMajorDiameter : result << "'InternalAlignment:EllipseMajorDiameter'>";break;
|
||||
case EllipseMinorDiameter : result << "'InternalAlignment:EllipseMinorDiameter'>";break;
|
||||
case EllipseFocus1 : result << "'InternalAlignment:EllipseFocus1'>";break;
|
||||
case EllipseFocus2 : result << "'InternalAlignment:EllipseFocus2'>";break;
|
||||
default : result << "'InternalAlignment:?'>";break;
|
||||
break;
|
||||
case Symmetric:
|
||||
result << "'Symmetric'>";
|
||||
break;
|
||||
case SnellsLaw:
|
||||
result << "'SnellsLaw'>";
|
||||
break;
|
||||
case InternalAlignment:
|
||||
switch (this->getConstraintPtr()->AlignmentType) {
|
||||
case Undef:
|
||||
result << "'InternalAlignment:Undef'>";
|
||||
break;
|
||||
case EllipseMajorDiameter:
|
||||
result << "'InternalAlignment:EllipseMajorDiameter'>";
|
||||
break;
|
||||
case EllipseMinorDiameter:
|
||||
result << "'InternalAlignment:EllipseMinorDiameter'>";
|
||||
break;
|
||||
case EllipseFocus1:
|
||||
result << "'InternalAlignment:EllipseFocus1'>";
|
||||
break;
|
||||
case EllipseFocus2:
|
||||
result << "'InternalAlignment:EllipseFocus2'>";
|
||||
break;
|
||||
default:
|
||||
result << "'InternalAlignment:?'>";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Equal : result << "'Equal' (" << getConstraintPtr()->First << "," << getConstraintPtr()->Second << ")>";break;
|
||||
case PointOnObject : result << "'PointOnObject' (" << getConstraintPtr()->First << "," << getConstraintPtr()->Second << ")>";break;
|
||||
default : result << "'?'>";break;
|
||||
break;
|
||||
case Equal:
|
||||
result << "'Equal' (" << getConstraintPtr()->First << "," << getConstraintPtr()->Second
|
||||
<< ")>";
|
||||
break;
|
||||
case PointOnObject:
|
||||
result << "'PointOnObject' (" << getConstraintPtr()->First << ","
|
||||
<< getConstraintPtr()->Second << ")>";
|
||||
break;
|
||||
default:
|
||||
result << "'?'>";
|
||||
break;
|
||||
}
|
||||
return result.str();
|
||||
}
|
||||
|
||||
Py::String ConstraintPy::getType() const
|
||||
{
|
||||
switch(this->getConstraintPtr()->Type) {
|
||||
case None : return Py::String("None");break;
|
||||
case DistanceX : return Py::String("DistanceX");break;
|
||||
case DistanceY : return Py::String("DistanceY");break;
|
||||
case Coincident : return Py::String("Coincident");break;
|
||||
case Horizontal : return Py::String("Horizontal");break;
|
||||
case Vertical : return Py::String("Vertical");break;
|
||||
case Block : return Py::String("Block");break;
|
||||
case Radius : return Py::String("Radius");break;
|
||||
case Diameter : return Py::String("Diameter");break;
|
||||
case Weight : return Py::String("Weight");break;
|
||||
case Parallel : return Py::String("Parallel");break;
|
||||
case Tangent : return Py::String("Tangent");break;
|
||||
case Perpendicular : return Py::String("Perpendicular");break;
|
||||
case Distance : return Py::String("Distance");break;
|
||||
case Angle : return Py::String("Angle");break;
|
||||
case Symmetric : return Py::String("Symmetric"); break;
|
||||
case SnellsLaw : return Py::String("SnellsLaw"); break;
|
||||
case InternalAlignment : return Py::String("InternalAlignment"); break;
|
||||
case Equal : return Py::String("Equal"); break;
|
||||
case PointOnObject : return Py::String("PointOnObject"); break;
|
||||
default : return Py::String("Undefined");break;
|
||||
switch (this->getConstraintPtr()->Type) {
|
||||
case None:
|
||||
return Py::String("None");
|
||||
break;
|
||||
case DistanceX:
|
||||
return Py::String("DistanceX");
|
||||
break;
|
||||
case DistanceY:
|
||||
return Py::String("DistanceY");
|
||||
break;
|
||||
case Coincident:
|
||||
return Py::String("Coincident");
|
||||
break;
|
||||
case Horizontal:
|
||||
return Py::String("Horizontal");
|
||||
break;
|
||||
case Vertical:
|
||||
return Py::String("Vertical");
|
||||
break;
|
||||
case Block:
|
||||
return Py::String("Block");
|
||||
break;
|
||||
case Radius:
|
||||
return Py::String("Radius");
|
||||
break;
|
||||
case Diameter:
|
||||
return Py::String("Diameter");
|
||||
break;
|
||||
case Weight:
|
||||
return Py::String("Weight");
|
||||
break;
|
||||
case Parallel:
|
||||
return Py::String("Parallel");
|
||||
break;
|
||||
case Tangent:
|
||||
return Py::String("Tangent");
|
||||
break;
|
||||
case Perpendicular:
|
||||
return Py::String("Perpendicular");
|
||||
break;
|
||||
case Distance:
|
||||
return Py::String("Distance");
|
||||
break;
|
||||
case Angle:
|
||||
return Py::String("Angle");
|
||||
break;
|
||||
case Symmetric:
|
||||
return Py::String("Symmetric");
|
||||
break;
|
||||
case SnellsLaw:
|
||||
return Py::String("SnellsLaw");
|
||||
break;
|
||||
case InternalAlignment:
|
||||
return Py::String("InternalAlignment");
|
||||
break;
|
||||
case Equal:
|
||||
return Py::String("Equal");
|
||||
break;
|
||||
case PointOnObject:
|
||||
return Py::String("PointOnObject");
|
||||
break;
|
||||
default:
|
||||
return Py::String("Undefined");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,7 +662,7 @@ Py::Long ConstraintPy::getFirst() const
|
||||
return Py::Long(this->getConstraintPtr()->First);
|
||||
}
|
||||
|
||||
void ConstraintPy::setFirst(Py::Long arg)
|
||||
void ConstraintPy::setFirst(Py::Long arg)
|
||||
{
|
||||
this->getConstraintPtr()->First = arg;
|
||||
}
|
||||
@@ -573,7 +676,8 @@ void ConstraintPy::setFirstPos(Py::Long arg)
|
||||
{
|
||||
int pos = arg;
|
||||
|
||||
if(pos>=static_cast<int>(Sketcher::PointPos::none) && pos<=static_cast<int>(Sketcher::PointPos::mid)) {
|
||||
if (pos >= static_cast<int>(Sketcher::PointPos::none)
|
||||
&& pos <= static_cast<int>(Sketcher::PointPos::mid)) {
|
||||
this->getConstraintPtr()->FirstPos = static_cast<Sketcher::PointPos>(pos);
|
||||
}
|
||||
else {
|
||||
@@ -589,7 +693,7 @@ Py::Long ConstraintPy::getSecond() const
|
||||
return Py::Long(this->getConstraintPtr()->Second);
|
||||
}
|
||||
|
||||
void ConstraintPy::setSecond(Py::Long arg)
|
||||
void ConstraintPy::setSecond(Py::Long arg)
|
||||
{
|
||||
this->getConstraintPtr()->Second = arg;
|
||||
}
|
||||
@@ -603,7 +707,8 @@ void ConstraintPy::setSecondPos(Py::Long arg)
|
||||
{
|
||||
int pos = arg;
|
||||
|
||||
if(pos>=static_cast<int>(Sketcher::PointPos::none) && pos<=static_cast<int>(Sketcher::PointPos::mid)) {
|
||||
if (pos >= static_cast<int>(Sketcher::PointPos::none)
|
||||
&& pos <= static_cast<int>(Sketcher::PointPos::mid)) {
|
||||
this->getConstraintPtr()->SecondPos = static_cast<Sketcher::PointPos>(pos);
|
||||
}
|
||||
else {
|
||||
@@ -619,7 +724,7 @@ Py::Long ConstraintPy::getThird() const
|
||||
return Py::Long(this->getConstraintPtr()->Third);
|
||||
}
|
||||
|
||||
void ConstraintPy::setThird(Py::Long arg)
|
||||
void ConstraintPy::setThird(Py::Long arg)
|
||||
{
|
||||
this->getConstraintPtr()->Third = arg;
|
||||
}
|
||||
@@ -633,7 +738,8 @@ void ConstraintPy::setThirdPos(Py::Long arg)
|
||||
{
|
||||
int pos = arg;
|
||||
|
||||
if(pos>=static_cast<int>(Sketcher::PointPos::none) && pos<=static_cast<int>(Sketcher::PointPos::mid)) {
|
||||
if (pos >= static_cast<int>(Sketcher::PointPos::none)
|
||||
&& pos <= static_cast<int>(Sketcher::PointPos::mid)) {
|
||||
this->getConstraintPtr()->ThirdPos = static_cast<Sketcher::PointPos>(pos);
|
||||
}
|
||||
else {
|
||||
@@ -649,7 +755,7 @@ Py::String ConstraintPy::getName() const
|
||||
return Py::String(this->getConstraintPtr()->Name);
|
||||
}
|
||||
|
||||
void ConstraintPy::setName(Py::String arg)
|
||||
void ConstraintPy::setName(Py::String arg)
|
||||
{
|
||||
this->getConstraintPtr()->Name = arg;
|
||||
}
|
||||
@@ -674,7 +780,7 @@ Py::Boolean ConstraintPy::getIsActive() const
|
||||
return Py::Boolean(this->getConstraintPtr()->isActive);
|
||||
}
|
||||
|
||||
PyObject *ConstraintPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* ConstraintPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -33,19 +33,20 @@ using namespace Sketcher;
|
||||
|
||||
//---------- Geometry Extension
|
||||
|
||||
constexpr std::array<const char *, ExternalGeometryExtension::NumFlags> ExternalGeometryExtension::flag2str;
|
||||
constexpr std::array<const char*, ExternalGeometryExtension::NumFlags>
|
||||
ExternalGeometryExtension::flag2str;
|
||||
|
||||
TYPESYSTEM_SOURCE(Sketcher::ExternalGeometryExtension,Part::GeometryPersistenceExtension)
|
||||
TYPESYSTEM_SOURCE(Sketcher::ExternalGeometryExtension, Part::GeometryPersistenceExtension)
|
||||
|
||||
void ExternalGeometryExtension::copyAttributes(Part::GeometryExtension * cpy) const
|
||||
void ExternalGeometryExtension::copyAttributes(Part::GeometryExtension* cpy) const
|
||||
{
|
||||
Part::GeometryPersistenceExtension::copyAttributes(cpy);
|
||||
|
||||
static_cast<ExternalGeometryExtension *>(cpy)->Ref = this->Ref;
|
||||
static_cast<ExternalGeometryExtension *>(cpy)->Flags = this->Flags;
|
||||
static_cast<ExternalGeometryExtension*>(cpy)->Ref = this->Ref;
|
||||
static_cast<ExternalGeometryExtension*>(cpy)->Flags = this->Flags;
|
||||
}
|
||||
|
||||
void ExternalGeometryExtension::restoreAttributes(Base::XMLReader &reader)
|
||||
void ExternalGeometryExtension::restoreAttributes(Base::XMLReader& reader)
|
||||
{
|
||||
Part::GeometryPersistenceExtension::restoreAttributes(reader);
|
||||
|
||||
@@ -53,12 +54,11 @@ void ExternalGeometryExtension::restoreAttributes(Base::XMLReader &reader)
|
||||
Flags = FlagType(reader.getAttribute("Flags"));
|
||||
}
|
||||
|
||||
void ExternalGeometryExtension::saveAttributes(Base::Writer &writer) const
|
||||
void ExternalGeometryExtension::saveAttributes(Base::Writer& writer) const
|
||||
{
|
||||
Part::GeometryPersistenceExtension::saveAttributes(writer);
|
||||
|
||||
writer.Stream() << "\" Ref=\"" << Ref
|
||||
<< "\" Flags=\"" << Flags.to_string();
|
||||
writer.Stream() << "\" Ref=\"" << Ref << "\" Flags=\"" << Flags.to_string();
|
||||
}
|
||||
|
||||
std::unique_ptr<Part::GeometryExtension> ExternalGeometryExtension::copy() const
|
||||
@@ -67,32 +67,32 @@ std::unique_ptr<Part::GeometryExtension> ExternalGeometryExtension::copy() const
|
||||
|
||||
copyAttributes(cpy.get());
|
||||
|
||||
#if defined (__GNUC__) && (__GNUC__ <=4)
|
||||
#if defined(__GNUC__) && (__GNUC__ <= 4)
|
||||
return std::move(cpy);
|
||||
#else
|
||||
return cpy;
|
||||
#endif
|
||||
}
|
||||
|
||||
PyObject * ExternalGeometryExtension::getPyObject()
|
||||
PyObject* ExternalGeometryExtension::getPyObject()
|
||||
{
|
||||
return new ExternalGeometryExtensionPy(new ExternalGeometryExtension(*this));
|
||||
}
|
||||
|
||||
bool ExternalGeometryExtension::getFlagsFromName(std::string str, ExternalGeometryExtension::Flag &flag)
|
||||
bool ExternalGeometryExtension::getFlagsFromName(std::string str,
|
||||
ExternalGeometryExtension::Flag& flag)
|
||||
{
|
||||
auto pos = std::find_if( ExternalGeometryExtension::flag2str.begin(),
|
||||
ExternalGeometryExtension::flag2str.end(),
|
||||
[str](const char * val) {
|
||||
return strcmp(val,str.c_str())==0;
|
||||
}
|
||||
);
|
||||
auto pos = std::find_if(ExternalGeometryExtension::flag2str.begin(),
|
||||
ExternalGeometryExtension::flag2str.end(),
|
||||
[str](const char* val) {
|
||||
return strcmp(val, str.c_str()) == 0;
|
||||
});
|
||||
|
||||
if( pos != ExternalGeometryExtension::flag2str.end()) {
|
||||
int index = std::distance( ExternalGeometryExtension::flag2str.begin(), pos );
|
||||
if (pos != ExternalGeometryExtension::flag2str.end()) {
|
||||
int index = std::distance(ExternalGeometryExtension::flag2str.begin(), pos);
|
||||
|
||||
flag = static_cast<ExternalGeometryExtension::Flag>(index);
|
||||
return true;
|
||||
flag = static_cast<ExternalGeometryExtension::Flag>(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -37,75 +37,103 @@ class ISketchExternalGeometryExtension
|
||||
{
|
||||
public:
|
||||
// Identification information
|
||||
// START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) <realthunder.dev@gmail.com>
|
||||
// START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder)
|
||||
// <realthunder.dev@gmail.com>
|
||||
virtual bool testFlag(int flag) const = 0;
|
||||
virtual void setFlag(int flag, bool v=true) = 0;
|
||||
// END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) <realthunder.dev@gmail.com>
|
||||
virtual void setFlag(int flag, bool v = true) = 0;
|
||||
// END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder)
|
||||
// <realthunder.dev@gmail.com>
|
||||
|
||||
virtual bool isClear() const = 0;
|
||||
virtual size_t flagSize() const = 0;
|
||||
|
||||
virtual const std::string& getRef() const = 0;
|
||||
virtual void setRef(const std::string & ref) = 0;
|
||||
virtual void setRef(const std::string& ref) = 0;
|
||||
};
|
||||
|
||||
class SketcherExport ExternalGeometryExtension : public Part::GeometryPersistenceExtension, private ISketchExternalGeometryExtension
|
||||
class SketcherExport ExternalGeometryExtension: public Part::GeometryPersistenceExtension,
|
||||
private ISketchExternalGeometryExtension
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
// START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) <realthunder.dev@gmail.com>
|
||||
enum Flag {
|
||||
Defining = 0, // allow an external geometry to build shape
|
||||
Frozen = 1, // freeze an external geometry
|
||||
Detached = 2, // signal the intentions of detaching the geometry from external reference
|
||||
Missing = 3, // geometry with missing external reference
|
||||
Sync = 4, // signal the intention to synchronize a frozen geometry
|
||||
NumFlags // Must be the last type
|
||||
// START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder)
|
||||
// <realthunder.dev@gmail.com>
|
||||
enum Flag
|
||||
{
|
||||
Defining = 0,// allow an external geometry to build shape
|
||||
Frozen = 1, // freeze an external geometry
|
||||
Detached = 2,// signal the intentions of detaching the geometry from external reference
|
||||
Missing = 3, // geometry with missing external reference
|
||||
Sync = 4, // signal the intention to synchronize a frozen geometry
|
||||
NumFlags // Must be the last type
|
||||
};
|
||||
// END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) <realthunder.dev@gmail.com>
|
||||
// END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder)
|
||||
// <realthunder.dev@gmail.com>
|
||||
|
||||
constexpr static std::array<const char*, NumFlags> flag2str {
|
||||
{"Defining", "Frozen", "Detached", "Missing", "Sync"}};
|
||||
|
||||
constexpr static std::array<const char *,NumFlags> flag2str {{ "Defining", "Frozen", "Detached","Missing", "Sync" }};
|
||||
public:
|
||||
|
||||
ExternalGeometryExtension() = default;
|
||||
~ExternalGeometryExtension() override = default;
|
||||
|
||||
std::unique_ptr<Part::GeometryExtension> copy() const override;
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
// START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) <realthunder.dev@gmail.com>
|
||||
bool testFlag(int flag) const override { return Flags.test((size_t)(flag)); }
|
||||
void setFlag(int flag, bool v=true) override { Flags.set((size_t)(flag),v); }
|
||||
// END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) <realthunder.dev@gmail.com>
|
||||
// START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder)
|
||||
// <realthunder.dev@gmail.com>
|
||||
bool testFlag(int flag) const override
|
||||
{
|
||||
return Flags.test((size_t)(flag));
|
||||
}
|
||||
void setFlag(int flag, bool v = true) override
|
||||
{
|
||||
Flags.set((size_t)(flag), v);
|
||||
}
|
||||
// END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder)
|
||||
// <realthunder.dev@gmail.com>
|
||||
|
||||
bool isClear() const override {return Flags.none();}
|
||||
size_t flagSize() const override {return Flags.size();}
|
||||
bool isClear() const override
|
||||
{
|
||||
return Flags.none();
|
||||
}
|
||||
size_t flagSize() const override
|
||||
{
|
||||
return Flags.size();
|
||||
}
|
||||
|
||||
const std::string& getRef() const override {return Ref;}
|
||||
void setRef(const std::string & ref) override {Ref = ref;}
|
||||
const std::string& getRef() const override
|
||||
{
|
||||
return Ref;
|
||||
}
|
||||
void setRef(const std::string& ref) override
|
||||
{
|
||||
Ref = ref;
|
||||
}
|
||||
|
||||
static bool getFlagsFromName(std::string str, ExternalGeometryExtension::Flag &flag);
|
||||
static bool getFlagsFromName(std::string str, ExternalGeometryExtension::Flag& flag);
|
||||
|
||||
protected:
|
||||
void copyAttributes(Part::GeometryExtension * cpy) const override;
|
||||
void restoreAttributes(Base::XMLReader &reader) override;
|
||||
void saveAttributes(Base::Writer &writer) const override;
|
||||
void copyAttributes(Part::GeometryExtension* cpy) const override;
|
||||
void restoreAttributes(Base::XMLReader& reader) override;
|
||||
void saveAttributes(Base::Writer& writer) const override;
|
||||
|
||||
private:
|
||||
ExternalGeometryExtension(const ExternalGeometryExtension&) = default;
|
||||
|
||||
private:
|
||||
using FlagType = std::bitset<32>;
|
||||
// START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) <realthunder.dev@gmail.com>
|
||||
// START_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder)
|
||||
// <realthunder.dev@gmail.com>
|
||||
std::string Ref;
|
||||
FlagType Flags;
|
||||
// END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder) <realthunder.dev@gmail.com>
|
||||
|
||||
|
||||
// END_CREDIT_BLOCK: Credit under LGPL for this block to Zheng, Lei (realthunder)
|
||||
// <realthunder.dev@gmail.com>
|
||||
};
|
||||
|
||||
} //namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCHER_EXTERNALGEOMETRYEXTENSION_H
|
||||
#endif// SKETCHER_EXTERNALGEOMETRYEXTENSION_H
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include "ExternalGeometryExtensionPy.h"
|
||||
|
||||
#include "ExternalGeometryExtensionPy.cpp"
|
||||
|
||||
|
||||
@@ -36,23 +37,22 @@ std::string ExternalGeometryExtensionPy::representation() const
|
||||
std::string ref = getExternalGeometryExtensionPtr()->getRef();
|
||||
|
||||
|
||||
|
||||
str << "<ExternalGeometryExtension (";
|
||||
|
||||
if(!getExternalGeometryExtensionPtr()->getName().empty())
|
||||
if (!getExternalGeometryExtensionPtr()->getName().empty())
|
||||
str << "\'" << getExternalGeometryExtensionPtr()->getName() << "\', ";
|
||||
|
||||
str << "\"" << ref;
|
||||
|
||||
if(!getExternalGeometryExtensionPtr()->isClear()) {
|
||||
str<< "\",{";
|
||||
if (!getExternalGeometryExtensionPtr()->isClear()) {
|
||||
str << "\",{";
|
||||
|
||||
bool first=true;
|
||||
bool first = true;
|
||||
|
||||
for(size_t i=0;i<ExternalGeometryExtension::NumFlags;i++) {
|
||||
if(getExternalGeometryExtensionPtr()->testFlag(i)) {
|
||||
if(first) {
|
||||
first=false;
|
||||
for (size_t i = 0; i < ExternalGeometryExtension::NumFlags; i++) {
|
||||
if (getExternalGeometryExtensionPtr()->testFlag(i)) {
|
||||
if (first) {
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
str << ", ";
|
||||
@@ -62,7 +62,7 @@ std::string ExternalGeometryExtensionPy::representation() const
|
||||
}
|
||||
}
|
||||
|
||||
str<< "}";
|
||||
str << "}";
|
||||
}
|
||||
else {
|
||||
str << "\") >";
|
||||
@@ -73,7 +73,8 @@ std::string ExternalGeometryExtensionPy::representation() const
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *ExternalGeometryExtensionPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
// Python wrapper
|
||||
PyObject* ExternalGeometryExtensionPy::PyMake(struct _typeobject*, PyObject*, PyObject*)
|
||||
{
|
||||
// create a new instance of PointPy and the Twin object
|
||||
return new ExternalGeometryExtensionPy(new ExternalGeometryExtension);
|
||||
@@ -88,39 +89,40 @@ int ExternalGeometryExtensionPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "ExternalGeometryExtension constructor accepts:\n"
|
||||
"-- empty parameter list\n");
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"ExternalGeometryExtension constructor accepts:\n"
|
||||
"-- empty parameter list\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryExtensionPy::testFlag(PyObject *args)
|
||||
PyObject* ExternalGeometryExtensionPy::testFlag(PyObject* args)
|
||||
{
|
||||
char* flag;
|
||||
if (PyArg_ParseTuple(args, "s",&flag)) {
|
||||
if (PyArg_ParseTuple(args, "s", &flag)) {
|
||||
|
||||
ExternalGeometryExtension::Flag flagtype;
|
||||
|
||||
if(getExternalGeometryExtensionPtr()->getFlagsFromName(flag, flagtype))
|
||||
return new_reference_to(Py::Boolean(this->getExternalGeometryExtensionPtr()->testFlag(flagtype)));
|
||||
if (getExternalGeometryExtensionPtr()->getFlagsFromName(flag, flagtype))
|
||||
return new_reference_to(
|
||||
Py::Boolean(this->getExternalGeometryExtensionPtr()->testFlag(flagtype)));
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Flag string does not exist.");
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "No flag string provided.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryExtensionPy::setFlag(PyObject *args)
|
||||
PyObject* ExternalGeometryExtensionPy::setFlag(PyObject* args)
|
||||
{
|
||||
char * flag;
|
||||
PyObject * bflag = Py_True;
|
||||
char* flag;
|
||||
PyObject* bflag = Py_True;
|
||||
if (PyArg_ParseTuple(args, "s|O!", &flag, &PyBool_Type, &bflag)) {
|
||||
|
||||
ExternalGeometryExtension::Flag flagtype;
|
||||
|
||||
if(getExternalGeometryExtensionPtr()->getFlagsFromName(flag, flagtype)) {
|
||||
if (getExternalGeometryExtensionPtr()->getFlagsFromName(flag, flagtype)) {
|
||||
|
||||
this->getExternalGeometryExtensionPtr()->setFlag(flagtype, Base::asBoolean(bflag));
|
||||
Py_Return;
|
||||
@@ -145,7 +147,7 @@ void ExternalGeometryExtensionPy::setRef(Py::String value)
|
||||
}
|
||||
|
||||
|
||||
PyObject *ExternalGeometryExtensionPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* ExternalGeometryExtensionPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <boost/uuid/uuid_io.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#endif
|
||||
|
||||
#include <Base/Console.h>
|
||||
@@ -33,43 +33,45 @@
|
||||
|
||||
using namespace Sketcher;
|
||||
|
||||
TYPESYSTEM_SOURCE(Sketcher::ExternalGeometryFacade,Base::BaseClass)
|
||||
TYPESYSTEM_SOURCE(Sketcher::ExternalGeometryFacade, Base::BaseClass)
|
||||
|
||||
ExternalGeometryFacade::ExternalGeometryFacade(): Geo(nullptr), SketchGeoExtension(nullptr), ExternalGeoExtension(nullptr)
|
||||
ExternalGeometryFacade::ExternalGeometryFacade()
|
||||
: Geo(nullptr),
|
||||
SketchGeoExtension(nullptr),
|
||||
ExternalGeoExtension(nullptr)
|
||||
{}
|
||||
|
||||
ExternalGeometryFacade::ExternalGeometryFacade(const Part::Geometry* geometry)
|
||||
: Geo(geometry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ExternalGeometryFacade::ExternalGeometryFacade(const Part::Geometry * geometry)
|
||||
: Geo(geometry)
|
||||
{
|
||||
if(geometry)
|
||||
if (geometry)
|
||||
initExtensions();
|
||||
else
|
||||
THROWM(Base::ValueError, "ExternalGeometryFacade initialized with Geometry null pointer");
|
||||
}
|
||||
|
||||
std::unique_ptr<ExternalGeometryFacade> ExternalGeometryFacade::getFacade(Part::Geometry * geometry)
|
||||
std::unique_ptr<ExternalGeometryFacade> ExternalGeometryFacade::getFacade(Part::Geometry* geometry)
|
||||
{
|
||||
if(geometry)
|
||||
if (geometry)
|
||||
return std::unique_ptr<ExternalGeometryFacade>(new ExternalGeometryFacade(geometry));
|
||||
else
|
||||
else
|
||||
return std::unique_ptr<ExternalGeometryFacade>(nullptr);
|
||||
}
|
||||
|
||||
std::unique_ptr<const ExternalGeometryFacade> ExternalGeometryFacade::getFacade(const Part::Geometry * geometry)
|
||||
std::unique_ptr<const ExternalGeometryFacade>
|
||||
ExternalGeometryFacade::getFacade(const Part::Geometry* geometry)
|
||||
{
|
||||
if(geometry)
|
||||
if (geometry)
|
||||
return std::unique_ptr<const ExternalGeometryFacade>(new ExternalGeometryFacade(geometry));
|
||||
else
|
||||
else
|
||||
return std::unique_ptr<const ExternalGeometryFacade>(nullptr);
|
||||
}
|
||||
|
||||
void ExternalGeometryFacade::setGeometry(Part::Geometry *geometry)
|
||||
void ExternalGeometryFacade::setGeometry(Part::Geometry* geometry)
|
||||
{
|
||||
Geo = geometry;
|
||||
|
||||
if(geometry)
|
||||
if (geometry)
|
||||
initExtensions();
|
||||
else
|
||||
THROWM(Base::ValueError, "ExternalGeometryFacade initialized with Geometry null pointer");
|
||||
@@ -77,67 +79,72 @@ void ExternalGeometryFacade::setGeometry(Part::Geometry *geometry)
|
||||
|
||||
void ExternalGeometryFacade::initExtensions()
|
||||
{
|
||||
if(!Geo->hasExtension(SketchGeometryExtension::getClassTypeId())) {
|
||||
if (!Geo->hasExtension(SketchGeometryExtension::getClassTypeId())) {
|
||||
|
||||
getGeo()->setExtension(std::make_unique<SketchGeometryExtension>()); // Create getExtension
|
||||
getGeo()->setExtension(std::make_unique<SketchGeometryExtension>());// Create getExtension
|
||||
|
||||
Base::Console().Warning("%s\nSketcher External Geometry without Geometry Extension: %s \n", boost::uuids::to_string(Geo->getTag()).c_str());
|
||||
Base::Console().Warning("%s\nSketcher External Geometry without Geometry Extension: %s \n",
|
||||
boost::uuids::to_string(Geo->getTag()).c_str());
|
||||
}
|
||||
|
||||
if(!Geo->hasExtension(ExternalGeometryExtension::getClassTypeId())) {
|
||||
if (!Geo->hasExtension(ExternalGeometryExtension::getClassTypeId())) {
|
||||
|
||||
getGeo()->setExtension(std::make_unique<ExternalGeometryExtension>()); // Create getExtension
|
||||
getGeo()->setExtension(std::make_unique<ExternalGeometryExtension>());// Create getExtension
|
||||
|
||||
Base::Console().Warning("%s\nSketcher External Geometry without ExternalGeometryExtension: %s \n", boost::uuids::to_string(Geo->getTag()).c_str());
|
||||
Base::Console().Warning(
|
||||
"%s\nSketcher External Geometry without ExternalGeometryExtension: %s \n",
|
||||
boost::uuids::to_string(Geo->getTag()).c_str());
|
||||
}
|
||||
|
||||
SketchGeoExtension =
|
||||
std::static_pointer_cast<const SketchGeometryExtension>(
|
||||
(Geo->getExtension(SketchGeometryExtension::getClassTypeId())).lock()
|
||||
);
|
||||
SketchGeoExtension = std::static_pointer_cast<const SketchGeometryExtension>(
|
||||
(Geo->getExtension(SketchGeometryExtension::getClassTypeId())).lock());
|
||||
|
||||
ExternalGeoExtension =
|
||||
std::static_pointer_cast<const ExternalGeometryExtension>(
|
||||
(Geo->getExtension(ExternalGeometryExtension::getClassTypeId())).lock()
|
||||
);
|
||||
ExternalGeoExtension = std::static_pointer_cast<const ExternalGeometryExtension>(
|
||||
(Geo->getExtension(ExternalGeometryExtension::getClassTypeId())).lock());
|
||||
}
|
||||
|
||||
void ExternalGeometryFacade::initExtensions() const
|
||||
{
|
||||
if(!Geo->hasExtension(SketchGeometryExtension::getClassTypeId()))
|
||||
THROWM(Base::ValueError, "ExternalGeometryFacade for const::Geometry without SketchGeometryExtension");
|
||||
if (!Geo->hasExtension(SketchGeometryExtension::getClassTypeId()))
|
||||
THROWM(Base::ValueError,
|
||||
"ExternalGeometryFacade for const::Geometry without SketchGeometryExtension");
|
||||
|
||||
if(!Geo->hasExtension(ExternalGeometryExtension::getClassTypeId()))
|
||||
THROWM(Base::ValueError, "ExternalGeometryFacade for const::Geometry without ExternalGeometryExtension");
|
||||
if (!Geo->hasExtension(ExternalGeometryExtension::getClassTypeId()))
|
||||
THROWM(Base::ValueError,
|
||||
"ExternalGeometryFacade for const::Geometry without ExternalGeometryExtension");
|
||||
|
||||
auto ext = std::static_pointer_cast<const SketchGeometryExtension>(Geo->getExtension(SketchGeometryExtension::getClassTypeId()).lock());
|
||||
auto ext = std::static_pointer_cast<const SketchGeometryExtension>(
|
||||
Geo->getExtension(SketchGeometryExtension::getClassTypeId()).lock());
|
||||
|
||||
const_cast<ExternalGeometryFacade *>(this)->SketchGeoExtension = ext;
|
||||
const_cast<ExternalGeometryFacade*>(this)->SketchGeoExtension = ext;
|
||||
|
||||
auto extext = std::static_pointer_cast<const ExternalGeometryExtension>(Geo->getExtension(ExternalGeometryExtension::getClassTypeId()).lock());
|
||||
auto extext = std::static_pointer_cast<const ExternalGeometryExtension>(
|
||||
Geo->getExtension(ExternalGeometryExtension::getClassTypeId()).lock());
|
||||
|
||||
const_cast<ExternalGeometryFacade *>(this)->ExternalGeoExtension = extext;
|
||||
const_cast<ExternalGeometryFacade*>(this)->ExternalGeoExtension = extext;
|
||||
}
|
||||
|
||||
void ExternalGeometryFacade::ensureSketchGeometryExtensions(Part::Geometry * geometry)
|
||||
void ExternalGeometryFacade::ensureSketchGeometryExtensions(Part::Geometry* geometry)
|
||||
{
|
||||
if(!geometry->hasExtension(SketchGeometryExtension::getClassTypeId())) {
|
||||
geometry->setExtension(std::make_unique<SketchGeometryExtension>()); // Create geoExtension
|
||||
if (!geometry->hasExtension(SketchGeometryExtension::getClassTypeId())) {
|
||||
// Create geoExtension
|
||||
geometry->setExtension(std::make_unique<SketchGeometryExtension>());
|
||||
}
|
||||
|
||||
if(!geometry->hasExtension(ExternalGeometryExtension::getClassTypeId())) {
|
||||
geometry->setExtension(std::make_unique<ExternalGeometryExtension>()); // Create external geoExtension
|
||||
if (!geometry->hasExtension(ExternalGeometryExtension::getClassTypeId())) {
|
||||
// Create external geoExtension
|
||||
geometry->setExtension(std::make_unique<ExternalGeometryExtension>());
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalGeometryFacade::copyId(const Part::Geometry * src, Part::Geometry * dst)
|
||||
void ExternalGeometryFacade::copyId(const Part::Geometry* src, Part::Geometry* dst)
|
||||
{
|
||||
auto gfsrc = ExternalGeometryFacade::getFacade(src);
|
||||
auto gfdst = ExternalGeometryFacade::getFacade(dst);
|
||||
gfdst->setId(gfsrc->getId());
|
||||
}
|
||||
|
||||
PyObject * ExternalGeometryFacade::getPyObject()
|
||||
PyObject* ExternalGeometryFacade::getPyObject()
|
||||
{
|
||||
return new ExternalGeometryFacadePy(new ExternalGeometryFacade(this->Geo));
|
||||
}
|
||||
|
||||
@@ -34,137 +34,277 @@ namespace Sketcher
|
||||
{
|
||||
|
||||
class ExternalGeometryFacadePy;
|
||||
// This class is a Facade to handle EXTERNAL sketcher geometry and sketcher geometry extensions with a single sketcher specific interface.
|
||||
// This class is a Facade to handle EXTERNAL sketcher geometry and sketcher geometry extensions with
|
||||
// a single sketcher specific interface.
|
||||
//
|
||||
// Exactly the same considerations as for GeometryFacade apply (see documentation of GeometryFacade).
|
||||
// Exactly the same considerations as for GeometryFacade apply (see documentation of
|
||||
// GeometryFacade).
|
||||
//
|
||||
// It was not made publicly deriving from GeometryFacade because it is not possible to differentiate functions by return type, which is the
|
||||
// case of getFacade() returning a unique_ptr to GeometryFacade in GeometryFacade, and one to ExternalGeometryFacade. I have not managed to
|
||||
// find a good solution to this problem, thus the code duplication.
|
||||
// It was not made publicly deriving from GeometryFacade because it is not possible to differentiate
|
||||
// functions by return type, which is the case of getFacade() returning a unique_ptr to
|
||||
// GeometryFacade in GeometryFacade, and one to ExternalGeometryFacade. I have not managed to find a
|
||||
// good solution to this problem, thus the code duplication.
|
||||
//
|
||||
// Summary Remarks:
|
||||
// It is intended to have a separate type (not being a Geometry type).
|
||||
// it is intended to have the relevant interface in full for the sketcher extension only
|
||||
// It is intended to work on borrowed memory allocation.
|
||||
class SketcherExport ExternalGeometryFacade : public Base::BaseClass, private ISketchGeometryExtension, private ISketchExternalGeometryExtension
|
||||
class SketcherExport ExternalGeometryFacade: public Base::BaseClass,
|
||||
private ISketchGeometryExtension,
|
||||
private ISketchExternalGeometryExtension
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
private:
|
||||
explicit ExternalGeometryFacade(const Part::Geometry * geometry);
|
||||
ExternalGeometryFacade(); // As TYPESYSTEM requirement
|
||||
explicit ExternalGeometryFacade(const Part::Geometry* geometry);
|
||||
ExternalGeometryFacade();// As TYPESYSTEM requirement
|
||||
|
||||
friend class ExternalGeometryFacadePy;
|
||||
|
||||
public: // Factory methods
|
||||
static std::unique_ptr<ExternalGeometryFacade> getFacade(Part::Geometry * geometry);
|
||||
static std::unique_ptr<const ExternalGeometryFacade> getFacade(const Part::Geometry * geometry);
|
||||
public:// Factory methods
|
||||
static std::unique_ptr<ExternalGeometryFacade> getFacade(Part::Geometry* geometry);
|
||||
static std::unique_ptr<const ExternalGeometryFacade> getFacade(const Part::Geometry* geometry);
|
||||
|
||||
public: // Utility methods
|
||||
static void ensureSketchGeometryExtensions(Part::Geometry * geometry);
|
||||
static void copyId(const Part::Geometry * src, Part::Geometry * dst);
|
||||
public:// Utility methods
|
||||
static void ensureSketchGeometryExtensions(Part::Geometry* geometry);
|
||||
static void copyId(const Part::Geometry* src, Part::Geometry* dst);
|
||||
|
||||
public:
|
||||
void setGeometry(Part::Geometry *geometry);
|
||||
void setGeometry(Part::Geometry* geometry);
|
||||
|
||||
/** External GeometryExtension Interface **/
|
||||
bool testFlag(int flag) const override { return getExternalGeoExt()->testFlag(flag); }
|
||||
void setFlag(int flag, bool v=true) override { getExternalGeoExt()->setFlag(flag, v); }
|
||||
bool testFlag(int flag) const override
|
||||
{
|
||||
return getExternalGeoExt()->testFlag(flag);
|
||||
}
|
||||
void setFlag(int flag, bool v = true) override
|
||||
{
|
||||
getExternalGeoExt()->setFlag(flag, v);
|
||||
}
|
||||
|
||||
bool isClear() const override {return getExternalGeoExt()->isClear();}
|
||||
size_t flagSize() const override {return getExternalGeoExt()->flagSize();}
|
||||
bool isClear() const override
|
||||
{
|
||||
return getExternalGeoExt()->isClear();
|
||||
}
|
||||
size_t flagSize() const override
|
||||
{
|
||||
return getExternalGeoExt()->flagSize();
|
||||
}
|
||||
|
||||
const std::string& getRef() const override {return getExternalGeoExt()->getRef();}
|
||||
void setRef(const std::string & ref) override {getExternalGeoExt()->setRef(ref);}
|
||||
const std::string& getRef() const override
|
||||
{
|
||||
return getExternalGeoExt()->getRef();
|
||||
}
|
||||
void setRef(const std::string& ref) override
|
||||
{
|
||||
getExternalGeoExt()->setRef(ref);
|
||||
}
|
||||
|
||||
/** GeometryExtension Interface **/
|
||||
inline long getId() const override {return getGeoExt()->getId();}
|
||||
void setId(long id) override {getGeoExt()->setId(id);}
|
||||
inline long getId() const override
|
||||
{
|
||||
return getGeoExt()->getId();
|
||||
}
|
||||
void setId(long id) override
|
||||
{
|
||||
getGeoExt()->setId(id);
|
||||
}
|
||||
|
||||
InternalType::InternalType getInternalType() const override {return getGeoExt()->getInternalType();}
|
||||
void setInternalType(InternalType::InternalType type) override {getGeoExt()->setInternalType(type);}
|
||||
InternalType::InternalType getInternalType() const override
|
||||
{
|
||||
return getGeoExt()->getInternalType();
|
||||
}
|
||||
void setInternalType(InternalType::InternalType type) override
|
||||
{
|
||||
getGeoExt()->setInternalType(type);
|
||||
}
|
||||
|
||||
bool testGeometryMode(int flag) const override { return getGeoExt()->testGeometryMode(flag); }
|
||||
void setGeometryMode(int flag, bool v=true) override { getGeoExt()->setGeometryMode(flag, v); }
|
||||
bool testGeometryMode(int flag) const override
|
||||
{
|
||||
return getGeoExt()->testGeometryMode(flag);
|
||||
}
|
||||
void setGeometryMode(int flag, bool v = true) override
|
||||
{
|
||||
getGeoExt()->setGeometryMode(flag, v);
|
||||
}
|
||||
|
||||
int getGeometryLayerId() const override { return getGeoExt()->getGeometryLayerId();}
|
||||
void setGeometryLayerId(int geolayer) override { getGeoExt()->setGeometryLayerId(geolayer);}
|
||||
int getGeometryLayerId() const override
|
||||
{
|
||||
return getGeoExt()->getGeometryLayerId();
|
||||
}
|
||||
void setGeometryLayerId(int geolayer) override
|
||||
{
|
||||
getGeoExt()->setGeometryLayerId(geolayer);
|
||||
}
|
||||
|
||||
// Convenience accessor
|
||||
bool getBlocked() const { return this->testGeometryMode(GeometryMode::Blocked);}
|
||||
void setBlocked(bool status = true) {this->setGeometryMode(GeometryMode::Blocked, status);}
|
||||
bool getBlocked() const
|
||||
{
|
||||
return this->testGeometryMode(GeometryMode::Blocked);
|
||||
}
|
||||
void setBlocked(bool status = true)
|
||||
{
|
||||
this->setGeometryMode(GeometryMode::Blocked, status);
|
||||
}
|
||||
|
||||
inline bool getConstruction() const {return this->testGeometryMode(GeometryMode::Construction);};
|
||||
inline void setConstruction(bool construction) {this->setGeometryMode(GeometryMode::Construction, construction);};
|
||||
inline bool getConstruction() const
|
||||
{
|
||||
return this->testGeometryMode(GeometryMode::Construction);
|
||||
};
|
||||
inline void setConstruction(bool construction)
|
||||
{
|
||||
this->setGeometryMode(GeometryMode::Construction, construction);
|
||||
};
|
||||
|
||||
// Geometry Extension Information
|
||||
inline const std::string &getSketchExtensionName () const {return SketchGeoExtension->getName();}
|
||||
inline const std::string &getExternalExtensionName () const {return ExternalGeoExtension->getName();}
|
||||
inline const std::string& getSketchExtensionName() const
|
||||
{
|
||||
return SketchGeoExtension->getName();
|
||||
}
|
||||
inline const std::string& getExternalExtensionName() const
|
||||
{
|
||||
return ExternalGeoExtension->getName();
|
||||
}
|
||||
|
||||
// Geometry Element
|
||||
template < typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<
|
||||
std::is_base_of<Part::Geometry, typename std::decay<GeometryT>::type>::value
|
||||
>::type
|
||||
>
|
||||
GeometryT * getGeometry() {return dynamic_cast<GeometryT *>(const_cast<GeometryT *>(Geo));}
|
||||
template<typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<std::is_base_of<
|
||||
Part::Geometry, typename std::decay<GeometryT>::type>::value>::type>
|
||||
GeometryT* getGeometry()
|
||||
{
|
||||
return dynamic_cast<GeometryT*>(const_cast<GeometryT*>(Geo));
|
||||
}
|
||||
|
||||
// Geometry Element
|
||||
template < typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<
|
||||
std::is_base_of<Part::Geometry, typename std::decay<GeometryT>::type>::value
|
||||
>::type
|
||||
>
|
||||
GeometryT * getGeometry() const {return dynamic_cast<GeometryT *>(Geo);}
|
||||
template<typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<std::is_base_of<
|
||||
Part::Geometry, typename std::decay<GeometryT>::type>::value>::type>
|
||||
GeometryT* getGeometry() const
|
||||
{
|
||||
return dynamic_cast<GeometryT*>(Geo);
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
/** Geometry Interface **/
|
||||
TopoDS_Shape toShape() const {return getGeo()->toShape();};
|
||||
const Handle(Geom_Geometry)& handle() const {return getGeo()->handle();};
|
||||
Part::Geometry *copy() const {return getGeo()->copy();};
|
||||
Part::Geometry *clone() const {return getGeo()->clone();};
|
||||
boost::uuids::uuid getTag() const {return getGeo()->getTag();};
|
||||
TopoDS_Shape toShape() const
|
||||
{
|
||||
return getGeo()->toShape();
|
||||
};
|
||||
const Handle(Geom_Geometry) & handle() const
|
||||
{
|
||||
return getGeo()->handle();
|
||||
};
|
||||
Part::Geometry* copy() const
|
||||
{
|
||||
return getGeo()->copy();
|
||||
};
|
||||
Part::Geometry* clone() const
|
||||
{
|
||||
return getGeo()->clone();
|
||||
};
|
||||
boost::uuids::uuid getTag() const
|
||||
{
|
||||
return getGeo()->getTag();
|
||||
};
|
||||
|
||||
std::vector<std::weak_ptr<const Part::GeometryExtension>> getExtensions() const {return getGeo()->getExtensions();};
|
||||
bool hasExtension(Base::Type type) const {return getGeo()->hasExtension(type);};
|
||||
bool hasExtension(const std::string & name) const {return getGeo()->hasExtension(name);};
|
||||
std::weak_ptr<const Part::GeometryExtension> getExtension(Base::Type type) const {return getGeo()->getExtension(type);};
|
||||
std::weak_ptr<const Part::GeometryExtension> getExtension(const std::string & name) const {return getGeo()->getExtension(name);};
|
||||
void setExtension(std::unique_ptr<Part::GeometryExtension> &&geo) {return getGeo()->setExtension(std::move(geo));};
|
||||
void deleteExtension(Base::Type type) {return getGeo()->deleteExtension(type);};
|
||||
void deleteExtension(const std::string & name) {return getGeo()->deleteExtension(name);};
|
||||
std::vector<std::weak_ptr<const Part::GeometryExtension>> getExtensions() const
|
||||
{
|
||||
return getGeo()->getExtensions();
|
||||
};
|
||||
bool hasExtension(Base::Type type) const
|
||||
{
|
||||
return getGeo()->hasExtension(type);
|
||||
};
|
||||
bool hasExtension(const std::string& name) const
|
||||
{
|
||||
return getGeo()->hasExtension(name);
|
||||
};
|
||||
std::weak_ptr<const Part::GeometryExtension> getExtension(Base::Type type) const
|
||||
{
|
||||
return getGeo()->getExtension(type);
|
||||
};
|
||||
std::weak_ptr<const Part::GeometryExtension> getExtension(const std::string& name) const
|
||||
{
|
||||
return getGeo()->getExtension(name);
|
||||
};
|
||||
void setExtension(std::unique_ptr<Part::GeometryExtension>&& geo)
|
||||
{
|
||||
return getGeo()->setExtension(std::move(geo));
|
||||
};
|
||||
void deleteExtension(Base::Type type)
|
||||
{
|
||||
return getGeo()->deleteExtension(type);
|
||||
};
|
||||
void deleteExtension(const std::string& name)
|
||||
{
|
||||
return getGeo()->deleteExtension(name);
|
||||
};
|
||||
|
||||
void mirror(const Base::Vector3d & point) {return getGeo()->mirror(point);};
|
||||
void mirror(const Base::Vector3d & point, Base::Vector3d dir) {return getGeo()->mirror(point, dir);};
|
||||
void rotate(const Base::Placement & plm) {return getGeo()->rotate(plm);};
|
||||
void scale(const Base::Vector3d & vec, double scale) {return getGeo()->scale(vec, scale);};
|
||||
void transform(const Base::Matrix4D & mat) {return getGeo()->transform(mat);};
|
||||
void translate(const Base::Vector3d & vec) {return getGeo()->translate(vec);};
|
||||
void mirror(const Base::Vector3d& point)
|
||||
{
|
||||
return getGeo()->mirror(point);
|
||||
};
|
||||
void mirror(const Base::Vector3d& point, Base::Vector3d dir)
|
||||
{
|
||||
return getGeo()->mirror(point, dir);
|
||||
};
|
||||
void rotate(const Base::Placement& plm)
|
||||
{
|
||||
return getGeo()->rotate(plm);
|
||||
};
|
||||
void scale(const Base::Vector3d& vec, double scale)
|
||||
{
|
||||
return getGeo()->scale(vec, scale);
|
||||
};
|
||||
void transform(const Base::Matrix4D& mat)
|
||||
{
|
||||
return getGeo()->transform(mat);
|
||||
};
|
||||
void translate(const Base::Vector3d& vec)
|
||||
{
|
||||
return getGeo()->translate(vec);
|
||||
};
|
||||
|
||||
private:
|
||||
void initExtensions();
|
||||
void initExtensions() const;
|
||||
|
||||
const Part::Geometry * getGeo() const {return Geo;}
|
||||
Part::Geometry * getGeo() {return const_cast<Part::Geometry *>(Geo);}
|
||||
const Part::Geometry* getGeo() const
|
||||
{
|
||||
return Geo;
|
||||
}
|
||||
Part::Geometry* getGeo()
|
||||
{
|
||||
return const_cast<Part::Geometry*>(Geo);
|
||||
}
|
||||
|
||||
std::shared_ptr<const SketchGeometryExtension> getGeoExt() const {return SketchGeoExtension;}
|
||||
std::shared_ptr<SketchGeometryExtension> getGeoExt () {return std::const_pointer_cast<SketchGeometryExtension>(SketchGeoExtension);}
|
||||
std::shared_ptr<const SketchGeometryExtension> getGeoExt() const
|
||||
{
|
||||
return SketchGeoExtension;
|
||||
}
|
||||
std::shared_ptr<SketchGeometryExtension> getGeoExt()
|
||||
{
|
||||
return std::const_pointer_cast<SketchGeometryExtension>(SketchGeoExtension);
|
||||
}
|
||||
|
||||
std::shared_ptr<const ExternalGeometryExtension> getExternalGeoExt() const {return ExternalGeoExtension;}
|
||||
std::shared_ptr<ExternalGeometryExtension> getExternalGeoExt () {return std::const_pointer_cast<ExternalGeometryExtension>(ExternalGeoExtension);}
|
||||
std::shared_ptr<const ExternalGeometryExtension> getExternalGeoExt() const
|
||||
{
|
||||
return ExternalGeoExtension;
|
||||
}
|
||||
std::shared_ptr<ExternalGeometryExtension> getExternalGeoExt()
|
||||
{
|
||||
return std::const_pointer_cast<ExternalGeometryExtension>(ExternalGeoExtension);
|
||||
}
|
||||
|
||||
private:
|
||||
const Part::Geometry * Geo;
|
||||
const Part::Geometry* Geo;
|
||||
std::shared_ptr<const SketchGeometryExtension> SketchGeoExtension;
|
||||
std::shared_ptr<const ExternalGeometryExtension> ExternalGeoExtension;
|
||||
};
|
||||
|
||||
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
} //namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCHER_GEOMETRYEXTERNALFACADE_H
|
||||
#endif// SKETCHER_GEOMETRYEXTERNALFACADE_H
|
||||
|
||||
@@ -27,11 +27,12 @@
|
||||
#include <Base/PlacementPy.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Base/VectorPy.h>
|
||||
#include <Mod/Part/App/GeometryPy.h>
|
||||
#include <Mod/Part/App/GeometryExtensionPy.h>
|
||||
#include <Mod/Part/App/GeometryPy.h>
|
||||
#include <Mod/Part/App/OCCError.h>
|
||||
|
||||
#include "ExternalGeometryFacadePy.h"
|
||||
|
||||
#include "ExternalGeometryFacadePy.cpp"
|
||||
|
||||
|
||||
@@ -47,7 +48,8 @@ std::string ExternalGeometryFacadePy::representation() const
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *ExternalGeometryFacadePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
PyObject* ExternalGeometryFacadePy::PyMake(struct _typeobject*, PyObject*,
|
||||
PyObject*)// Python wrapper
|
||||
{
|
||||
// create a new instance of PointPy and the Twin object
|
||||
return new ExternalGeometryFacadePy(new ExternalGeometryFacade());
|
||||
@@ -56,60 +58,61 @@ PyObject *ExternalGeometryFacadePy::PyMake(struct _typeobject *, PyObject *, PyO
|
||||
// constructor method
|
||||
int ExternalGeometryFacadePy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
{
|
||||
PyObject *object;
|
||||
if (PyArg_ParseTuple(args,"O!",&(Part::GeometryPy::Type), &object)) {
|
||||
Part::Geometry * geo = static_cast<Part::GeometryPy *>(object)->getGeometryPtr();
|
||||
PyObject* object;
|
||||
if (PyArg_ParseTuple(args, "O!", &(Part::GeometryPy::Type), &object)) {
|
||||
Part::Geometry* geo = static_cast<Part::GeometryPy*>(object)->getGeometryPtr();
|
||||
|
||||
getExternalGeometryFacadePtr()->setGeometry(geo->clone());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Sketcher::ExternalGeometryFacade constructor accepts:\n"
|
||||
"-- Part.Geometry\n"
|
||||
);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Sketcher::ExternalGeometryFacade constructor accepts:\n"
|
||||
"-- Part.Geometry\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::testFlag(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::testFlag(PyObject* args)
|
||||
{
|
||||
char* flag;
|
||||
if (PyArg_ParseTuple(args, "s",&flag)) {
|
||||
if (PyArg_ParseTuple(args, "s", &flag)) {
|
||||
|
||||
auto pos = std::find_if(ExternalGeometryExtension::flag2str.begin(),
|
||||
ExternalGeometryExtension::flag2str.end(),
|
||||
[flag](const char * val) { return strcmp(val,flag) == 0;});
|
||||
ExternalGeometryExtension::flag2str.end(),
|
||||
[flag](const char* val) {
|
||||
return strcmp(val, flag) == 0;
|
||||
});
|
||||
|
||||
if( pos != ExternalGeometryExtension::flag2str.end()) {
|
||||
int index = std::distance( ExternalGeometryExtension::flag2str.begin(), pos );
|
||||
if (pos != ExternalGeometryExtension::flag2str.end()) {
|
||||
int index = std::distance(ExternalGeometryExtension::flag2str.begin(), pos);
|
||||
|
||||
return new_reference_to(Py::Boolean(this->getExternalGeometryFacadePtr()->testFlag(index)));
|
||||
return new_reference_to(
|
||||
Py::Boolean(this->getExternalGeometryFacadePtr()->testFlag(index)));
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Flag string does not exist.");
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "No flag string provided.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::setFlag(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::setFlag(PyObject* args)
|
||||
{
|
||||
char * flag;
|
||||
PyObject * bflag = Py_True;
|
||||
char* flag;
|
||||
PyObject* bflag = Py_True;
|
||||
if (PyArg_ParseTuple(args, "s|O!", &flag, &PyBool_Type, &bflag)) {
|
||||
|
||||
auto pos = std::find_if(ExternalGeometryExtension::flag2str.begin(),
|
||||
ExternalGeometryExtension::flag2str.end(),
|
||||
[flag](const char * val) {
|
||||
return strcmp(val,flag)==0;
|
||||
}
|
||||
);
|
||||
[flag](const char* val) {
|
||||
return strcmp(val, flag) == 0;
|
||||
});
|
||||
|
||||
if( pos != ExternalGeometryExtension::flag2str.end()) {
|
||||
int index = std::distance( ExternalGeometryExtension::flag2str.begin(), pos );
|
||||
if (pos != ExternalGeometryExtension::flag2str.end()) {
|
||||
int index = std::distance(ExternalGeometryExtension::flag2str.begin(), pos);
|
||||
|
||||
this->getExternalGeometryFacadePtr()->setFlag(index, Base::asBoolean(bflag));
|
||||
Py_Return;
|
||||
@@ -147,12 +150,12 @@ Py::String ExternalGeometryFacadePy::getInternalType() const
|
||||
{
|
||||
int internaltypeindex = (int)this->getExternalGeometryFacadePtr()->getInternalType();
|
||||
|
||||
if(internaltypeindex >= InternalType::NumInternalGeometryType)
|
||||
if (internaltypeindex >= InternalType::NumInternalGeometryType)
|
||||
throw Py::NotImplementedError("String name of enum not implemented");
|
||||
|
||||
std::string typestr = SketchGeometryExtension::internaltype2str[internaltypeindex];
|
||||
|
||||
return Py::String(typestr);
|
||||
return Py::String(typestr);
|
||||
}
|
||||
|
||||
void ExternalGeometryFacadePy::setInternalType(Py::String arg)
|
||||
@@ -160,7 +163,7 @@ void ExternalGeometryFacadePy::setInternalType(Py::String arg)
|
||||
std::string argstr = arg;
|
||||
InternalType::InternalType type;
|
||||
|
||||
if(SketchGeometryExtension::getInternalTypeFromName(argstr, type)) {
|
||||
if (SketchGeometryExtension::getInternalTypeFromName(argstr, type)) {
|
||||
this->getExternalGeometryFacadePtr()->setInternalType(type);
|
||||
return;
|
||||
}
|
||||
@@ -178,10 +181,10 @@ void ExternalGeometryFacadePy::setBlocked(Py::Boolean arg)
|
||||
getExternalGeometryFacadePtr()->setBlocked(arg);
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::mirror(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::mirror(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type),&o)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &o)) {
|
||||
Base::Vector3d vec = static_cast<Base::VectorPy*>(o)->value();
|
||||
getExternalGeometryFacadePtr()->mirror(vec);
|
||||
Py_Return;
|
||||
@@ -189,22 +192,23 @@ PyObject* ExternalGeometryFacadePy::mirror(PyObject *args)
|
||||
|
||||
PyErr_Clear();
|
||||
PyObject* axis;
|
||||
if (PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type),&o,
|
||||
&(Base::VectorPy::Type),&axis)) {
|
||||
if (PyArg_ParseTuple(
|
||||
args, "O!O!", &(Base::VectorPy::Type), &o, &(Base::VectorPy::Type), &axis)) {
|
||||
Base::Vector3d pnt = static_cast<Base::VectorPy*>(o)->value();
|
||||
Base::Vector3d dir = static_cast<Base::VectorPy*>(axis)->value();
|
||||
getExternalGeometryFacadePtr()->mirror(pnt, dir);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "either a point (vector) or axis (vector, vector) must be given");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"either a point (vector) or axis (vector, vector) must be given");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::rotate(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::rotate(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type),&o))
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &o))
|
||||
return nullptr;
|
||||
|
||||
Base::Placement* plm = static_cast<Base::PlacementPy*>(o)->getPlacementPtr();
|
||||
@@ -212,19 +216,19 @@ PyObject* ExternalGeometryFacadePy::rotate(PyObject *args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::scale(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::scale(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
double scale;
|
||||
Base::Vector3d vec;
|
||||
if (PyArg_ParseTuple(args, "O!d", &(Base::VectorPy::Type),&o, &scale)) {
|
||||
if (PyArg_ParseTuple(args, "O!d", &(Base::VectorPy::Type), &o, &scale)) {
|
||||
vec = static_cast<Base::VectorPy*>(o)->value();
|
||||
getExternalGeometryFacadePtr()->scale(vec, scale);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O!d", &PyTuple_Type,&o, &scale)) {
|
||||
if (PyArg_ParseTuple(args, "O!d", &PyTuple_Type, &o, &scale)) {
|
||||
vec = Base::getVectorFromTuple<double>(o);
|
||||
getExternalGeometryFacadePtr()->scale(vec, scale);
|
||||
Py_Return;
|
||||
@@ -234,28 +238,28 @@ PyObject* ExternalGeometryFacadePy::scale(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::transform(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::transform(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type),&o))
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type), &o))
|
||||
return nullptr;
|
||||
Base::Matrix4D mat = static_cast<Base::MatrixPy*>(o)->value();
|
||||
getExternalGeometryFacadePtr()->transform(mat);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::translate(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::translate(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
Base::Vector3d vec;
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type),&o)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &o)) {
|
||||
vec = static_cast<Base::VectorPy*>(o)->value();
|
||||
getExternalGeometryFacadePtr()->translate(vec);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O!", &PyTuple_Type,&o)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &o)) {
|
||||
vec = Base::getVectorFromTuple<double>(o);
|
||||
getExternalGeometryFacadePtr()->translate(vec);
|
||||
Py_Return;
|
||||
@@ -265,12 +269,12 @@ PyObject* ExternalGeometryFacadePy::translate(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::setExtension(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::setExtension(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
if (PyArg_ParseTuple(args, "O!", &(Part::GeometryExtensionPy::Type),&o)) {
|
||||
Part::GeometryExtension * ext;
|
||||
ext = static_cast<Part::GeometryExtensionPy *>(o)->getGeometryExtensionPtr();
|
||||
if (PyArg_ParseTuple(args, "O!", &(Part::GeometryExtensionPy::Type), &o)) {
|
||||
Part::GeometryExtension* ext;
|
||||
ext = static_cast<Part::GeometryExtensionPy*>(o)->getGeometryExtensionPtr();
|
||||
|
||||
// make copy of Python managed memory and wrap it in smart pointer
|
||||
auto cpy = ext->copy();
|
||||
@@ -283,154 +287,159 @@ PyObject* ExternalGeometryFacadePy::setExtension(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::getExtensionOfType(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::getExtensionOfType(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
|
||||
Base::Type type = Base::Type::fromName(o);
|
||||
|
||||
if(type != Base::Type::badType()) {
|
||||
if (type != Base::Type::badType()) {
|
||||
try {
|
||||
std::shared_ptr<const Part::GeometryExtension> ext(this->getExternalGeometryFacadePtr()->getExtension(type));
|
||||
std::shared_ptr<const Part::GeometryExtension> ext(
|
||||
this->getExternalGeometryFacadePtr()->getExtension(type));
|
||||
|
||||
// we create a copy and transfer this copy's memory management responsibility to Python
|
||||
// we create a copy and transfer this copy's memory management responsibility to
|
||||
// Python
|
||||
PyObject* cpy = ext->copyPyObject();
|
||||
return cpy;
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
catch(const std::bad_weak_ptr&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not exist anymore.");
|
||||
catch (const std::bad_weak_ptr&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"Geometry extension does not exist anymore.");
|
||||
return nullptr;
|
||||
}
|
||||
catch(Base::NotImplementedError&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not implement a Python counterpart.");
|
||||
catch (Base::NotImplementedError&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"Geometry extension does not implement a Python counterpart.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Exception type does not exist");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with the name of the geometry extension type was expected");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"A string with the name of the geometry extension type was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::getExtensionOfName(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::getExtensionOfName(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
|
||||
try {
|
||||
std::shared_ptr<const Part::GeometryExtension> ext(this->getExternalGeometryFacadePtr()->getExtension(std::string(o)));
|
||||
std::shared_ptr<const Part::GeometryExtension> ext(
|
||||
this->getExternalGeometryFacadePtr()->getExtension(std::string(o)));
|
||||
|
||||
// we create a copy and transfer this copy's memory management responsibility to Python
|
||||
PyObject* cpy = ext->copyPyObject();
|
||||
return cpy;
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
catch(const std::bad_weak_ptr&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not exist anymore.");
|
||||
catch (const std::bad_weak_ptr&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"Geometry extension does not exist anymore.");
|
||||
return nullptr;
|
||||
}
|
||||
catch(Base::NotImplementedError&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not implement a Python counterpart.");
|
||||
catch (Base::NotImplementedError&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"Geometry extension does not implement a Python counterpart.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with the name of the geometry extension was expected");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"A string with the name of the geometry extension was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::hasExtensionOfType(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::hasExtensionOfType(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
|
||||
Base::Type type = Base::Type::fromName(o);
|
||||
|
||||
if(type != Base::Type::badType()) {
|
||||
if (type != Base::Type::badType()) {
|
||||
try {
|
||||
return Py::new_reference_to(Py::Boolean(this->getExternalGeometryFacadePtr()->hasExtension(type)));
|
||||
return Py::new_reference_to(
|
||||
Py::Boolean(this->getExternalGeometryFacadePtr()->hasExtension(type)));
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Exception type does not exist");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with the type of the geometry extension was expected");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"A string with the type of the geometry extension was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::hasExtensionOfName(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::hasExtensionOfName(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
|
||||
try {
|
||||
return Py::new_reference_to(Py::Boolean(this->getExternalGeometryFacadePtr()->hasExtension(std::string(o))));
|
||||
return Py::new_reference_to(
|
||||
Py::Boolean(this->getExternalGeometryFacadePtr()->hasExtension(std::string(o))));
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with the type of the geometry extension was expected");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"A string with the type of the geometry extension was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::deleteExtensionOfType(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::deleteExtensionOfType(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
|
||||
Base::Type type = Base::Type::fromName(o);
|
||||
|
||||
if(type != Base::Type::badType()) {
|
||||
if (type != Base::Type::badType()) {
|
||||
try {
|
||||
this->getExternalGeometryFacadePtr()->deleteExtension(type);
|
||||
Py_Return;
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Type does not exist");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with a type object was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::deleteExtensionOfName(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::deleteExtensionOfName(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
@@ -439,38 +448,40 @@ PyObject* ExternalGeometryFacadePy::deleteExtensionOfName(PyObject *args)
|
||||
this->getExternalGeometryFacadePtr()->deleteExtension(std::string(o));
|
||||
Py_Return;
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with the name of the extension was expected");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"A string with the name of the extension was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* ExternalGeometryFacadePy::getExtensions(PyObject *args)
|
||||
PyObject* ExternalGeometryFacadePy::getExtensions(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")){
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "No arguments were expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
const std::vector<std::weak_ptr<const Part::GeometryExtension>> ext = this->getExternalGeometryFacadePtr()->getExtensions();
|
||||
const std::vector<std::weak_ptr<const Part::GeometryExtension>> ext =
|
||||
this->getExternalGeometryFacadePtr()->getExtensions();
|
||||
|
||||
Py::List list;
|
||||
|
||||
for (std::size_t i=0; i<ext.size(); ++i) {
|
||||
for (std::size_t i = 0; i < ext.size(); ++i) {
|
||||
|
||||
std::shared_ptr<const Part::GeometryExtension> p = ext[i].lock();
|
||||
|
||||
if(p) {
|
||||
if (p) {
|
||||
// we create a python copy and add it to the list
|
||||
try {
|
||||
list.append(Py::asObject(p->copyPyObject()));
|
||||
}
|
||||
catch(Base::NotImplementedError&) {
|
||||
catch (Base::NotImplementedError&) {
|
||||
// silently ignoring extensions not having a Python object
|
||||
}
|
||||
}
|
||||
@@ -478,11 +489,10 @@ PyObject* ExternalGeometryFacadePy::getExtensions(PyObject *args)
|
||||
|
||||
return Py::new_reference_to(list);
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Py::Boolean ExternalGeometryFacadePy::getConstruction() const
|
||||
@@ -490,7 +500,7 @@ Py::Boolean ExternalGeometryFacadePy::getConstruction() const
|
||||
return Py::Boolean(getExternalGeometryFacadePtr()->getConstruction());
|
||||
}
|
||||
|
||||
void ExternalGeometryFacadePy::setConstruction(Py::Boolean arg)
|
||||
void ExternalGeometryFacadePy::setConstruction(Py::Boolean arg)
|
||||
{
|
||||
if (getExternalGeometryFacadePtr()->getTypeId() != Part::GeomPoint::getClassTypeId())
|
||||
getExternalGeometryFacadePtr()->setConstruction(arg);
|
||||
@@ -519,17 +529,17 @@ Py::Object ExternalGeometryFacadePy::getGeometry() const
|
||||
return Py::Object(geo->getPyObject(), true);
|
||||
}
|
||||
|
||||
void ExternalGeometryFacadePy::setGeometry(Py::Object arg)
|
||||
void ExternalGeometryFacadePy::setGeometry(Py::Object arg)
|
||||
{
|
||||
if (PyObject_TypeCheck(arg.ptr(), &(Part::GeometryPy::Type))) {
|
||||
Part::GeometryPy * gp = static_cast<Part::GeometryPy *>(arg.ptr());
|
||||
Part::GeometryPy* gp = static_cast<Part::GeometryPy*>(arg.ptr());
|
||||
|
||||
getExternalGeometryFacadePtr()->setGeometry(gp->getGeometryPtr()->clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyObject *ExternalGeometryFacadePy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* ExternalGeometryFacadePy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#ifndef SKETCHER_GeoEnum_H
|
||||
#define SKETCHER_GeoEnum_H
|
||||
|
||||
#include <functional>
|
||||
#include <Mod/Sketcher/SketcherGlobal.h>
|
||||
#include <functional>
|
||||
|
||||
namespace Sketcher
|
||||
{
|
||||
@@ -56,46 +56,49 @@ namespace Sketcher
|
||||
*
|
||||
* Geometry shapes having more or different elements than those supported by the PointPos
|
||||
* struct, such as conics, in particular an arc of ellipse, are called complex geometries. The extra
|
||||
* elements of complex geometries are actual separate geometries (focus of an ellipse, line defining the
|
||||
* major axis of an ellipse, circle representing the weight of a BSpline), and they are call InternalAlignment
|
||||
* geometries.
|
||||
* elements of complex geometries are actual separate geometries (focus of an ellipse, line defining
|
||||
* the major axis of an ellipse, circle representing the weight of a BSpline), and they are call
|
||||
* InternalAlignment geometries.
|
||||
*
|
||||
* For Geometry lists, refer to GeoListModel template.
|
||||
*/
|
||||
enum GeoEnum
|
||||
{
|
||||
RtPnt = -1, // GeoId of the Root Point
|
||||
HAxis = -1, // GeoId of the Horizontal Axis
|
||||
VAxis = -2, // GeoId of the Vertical Axis
|
||||
RefExt = -3, // Starting GeoID of external geometry ( negative geoIds starting at this index)
|
||||
GeoUndef = -2000, // GeoId of an undefined Geometry (uninitialised or unused GeoId)
|
||||
RtPnt = -1, // GeoId of the Root Point
|
||||
HAxis = -1, // GeoId of the Horizontal Axis
|
||||
VAxis = -2, // GeoId of the Vertical Axis
|
||||
RefExt = -3,// Starting GeoID of external geometry ( negative geoIds starting at this index)
|
||||
GeoUndef = -2000,// GeoId of an undefined Geometry (uninitialised or unused GeoId)
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief PointPos lets us refer to different aspects of a piece of geometry.
|
||||
* @details sketcher::none refers to an edge itself (eg., for a Perpendicular constraint
|
||||
* on two lines). sketcher::start and sketcher::end denote the endpoints of lines or bounded curves.
|
||||
* Sketcher::mid denotes geometries with geometrical centers (eg., circle, ellipse). Bare points use 'start'.
|
||||
* More complex geometries like parabola focus or b-spline knots use InternalAlignment constraints
|
||||
* in addition to PointPos.
|
||||
* Sketcher::mid denotes geometries with geometrical centers (eg., circle, ellipse). Bare points use
|
||||
* 'start'. More complex geometries like parabola focus or b-spline knots use InternalAlignment
|
||||
* constraints in addition to PointPos.
|
||||
*/
|
||||
enum class PointPos : int {
|
||||
none = 0, // Edge of a geometry
|
||||
start = 1, // Starting point of a geometry
|
||||
end = 2, // End point of a geometry
|
||||
mid = 3 // Mid point of a geometry
|
||||
enum class PointPos : int
|
||||
{
|
||||
none = 0, // Edge of a geometry
|
||||
start = 1,// Starting point of a geometry
|
||||
end = 2, // End point of a geometry
|
||||
mid = 3 // Mid point of a geometry
|
||||
};
|
||||
|
||||
/** @brief Struct for storing a {GeoId, PointPos} pair.
|
||||
*
|
||||
* @details
|
||||
* {GeoId, PointPos} is pervasive in the sketcher as means to identify geometry (edges) and geometry elements (vertices).
|
||||
* {GeoId, PointPos} is pervasive in the sketcher as means to identify geometry (edges) and geometry
|
||||
* elements (vertices).
|
||||
*
|
||||
* GeoElementId intends to substitute this pair whenever appropriate. For example in containers and ordered containers.
|
||||
*
|
||||
* It has overloaded equality operator and specialised std::less so that it can safely be used in containers, including
|
||||
* GeoElementId intends to substitute this pair whenever appropriate. For example in containers and
|
||||
* ordered containers.
|
||||
*
|
||||
* It has overloaded equality operator and specialised std::less so that it can safely be used in
|
||||
* containers, including ordered containers.
|
||||
*
|
||||
*/
|
||||
class SketcherExport GeoElementId
|
||||
{
|
||||
@@ -109,7 +112,7 @@ public:
|
||||
bool operator==(const GeoElementId& obj) const;
|
||||
|
||||
/** @brief inequality operator
|
||||
*/
|
||||
*/
|
||||
bool operator!=(const GeoElementId& obj) const;
|
||||
|
||||
/** @brief Underlying GeoId (see GeoEnum for definition)
|
||||
@@ -135,15 +138,18 @@ public:
|
||||
};
|
||||
|
||||
// inline constexpr constructor
|
||||
inline constexpr GeoElementId::GeoElementId(int geoId, PointPos pos): GeoId(geoId), Pos(pos)
|
||||
{
|
||||
}
|
||||
inline constexpr GeoElementId::GeoElementId(int geoId, PointPos pos)
|
||||
: GeoId(geoId),
|
||||
Pos(pos)
|
||||
{}
|
||||
|
||||
inline bool GeoElementId::isCurve() const {
|
||||
inline bool GeoElementId::isCurve() const
|
||||
{
|
||||
return Pos == PointPos::none;
|
||||
}
|
||||
|
||||
inline int GeoElementId::posIdAsInt() const {
|
||||
inline int GeoElementId::posIdAsInt() const
|
||||
{
|
||||
return static_cast<int>(Pos);
|
||||
}
|
||||
|
||||
@@ -153,18 +159,19 @@ constexpr const GeoElementId GeoElementId::HAxis = GeoElementId(GeoEnum::HAxis,
|
||||
constexpr const GeoElementId GeoElementId::VAxis = GeoElementId(GeoEnum::VAxis, PointPos::none);
|
||||
#endif
|
||||
|
||||
} // namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<> struct less<Sketcher::GeoElementId>
|
||||
template<>
|
||||
struct less<Sketcher::GeoElementId>
|
||||
{
|
||||
bool operator()(const Sketcher::GeoElementId& lhs, const Sketcher::GeoElementId& rhs) const
|
||||
{
|
||||
bool operator() (const Sketcher::GeoElementId& lhs, const Sketcher::GeoElementId& rhs) const
|
||||
{
|
||||
return (lhs.GeoId != rhs.GeoId)?(lhs.GeoId < rhs.GeoId):(static_cast<int>(lhs.Pos) < static_cast<int>(rhs.Pos));
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif // SKETCHER_GeoEnum_H
|
||||
return (lhs.GeoId != rhs.GeoId) ? (lhs.GeoId < rhs.GeoId)
|
||||
: (static_cast<int>(lhs.Pos) < static_cast<int>(rhs.Pos));
|
||||
}
|
||||
};
|
||||
}// namespace std
|
||||
|
||||
#endif// SKETCHER_GeoEnum_H
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <cassert>
|
||||
#endif // #ifndef _PreComp_
|
||||
#include <cassert>
|
||||
#endif// #ifndef _PreComp_
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
@@ -37,179 +37,188 @@
|
||||
using namespace Sketcher;
|
||||
|
||||
// Vector is moved
|
||||
template <typename T>
|
||||
GeoListModel<T>::GeoListModel( std::vector<T> && geometrylist,
|
||||
int intgeocount,
|
||||
bool ownerT): geomlist(std::move(geometrylist)),
|
||||
intGeoCount(intgeocount),
|
||||
OwnerT(ownerT),
|
||||
indexInit(false)
|
||||
{
|
||||
|
||||
}
|
||||
template<typename T>
|
||||
GeoListModel<T>::GeoListModel(std::vector<T>&& geometrylist, int intgeocount, bool ownerT)
|
||||
: geomlist(std::move(geometrylist)),
|
||||
intGeoCount(intgeocount),
|
||||
OwnerT(ownerT),
|
||||
indexInit(false)
|
||||
{}
|
||||
|
||||
// Vector is shallow copied (copy constructed)
|
||||
template <typename T>
|
||||
GeoListModel<T>::GeoListModel( const std::vector<T> & geometrylist,
|
||||
int intgeocount): geomlist(geometrylist), // copy constructed here
|
||||
intGeoCount(intgeocount),
|
||||
OwnerT(false),
|
||||
indexInit(false)
|
||||
{
|
||||
template<typename T>
|
||||
GeoListModel<T>::GeoListModel(const std::vector<T>& geometrylist,
|
||||
int intgeocount)
|
||||
: geomlist(geometrylist),// copy constructed here
|
||||
intGeoCount(intgeocount),
|
||||
OwnerT(false),
|
||||
indexInit(false)
|
||||
{}
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
GeoListModel<T>::~GeoListModel()
|
||||
{
|
||||
if(OwnerT) {
|
||||
for(auto & g : geomlist)
|
||||
if (OwnerT) {
|
||||
for (auto& g : geomlist)
|
||||
delete g;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
GeoListModel<T> GeoListModel<T>::getGeoListModel(std::vector<T> && geometrylist, int intgeocount, bool ownerT)
|
||||
template<typename T>
|
||||
GeoListModel<T> GeoListModel<T>::getGeoListModel(std::vector<T>&& geometrylist, int intgeocount,
|
||||
bool ownerT)
|
||||
{
|
||||
return GeoListModel(std::move(geometrylist), intgeocount, ownerT);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const GeoListModel<T> GeoListModel<T>::getGeoListModel(const std::vector<T> &geometrylist, int intgeocount)
|
||||
template<typename T>
|
||||
const GeoListModel<T> GeoListModel<T>::getGeoListModel(const std::vector<T>& geometrylist,
|
||||
int intgeocount)
|
||||
{
|
||||
return GeoListModel(geometrylist, intgeocount);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
int GeoListModel<T>::getGeoIdFromGeomListIndex(int index) const
|
||||
{
|
||||
assert(index < int(geomlist.size()));
|
||||
|
||||
if(index < intGeoCount)
|
||||
if (index < intGeoCount)
|
||||
return index;
|
||||
else
|
||||
return ( index - geomlist.size());
|
||||
return (index - geomlist.size());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const Part::Geometry * GeoListModel<T>::getGeometryFromGeoId(const std::vector<T> & geometrylist, int geoId)
|
||||
template<typename T>
|
||||
const Part::Geometry* GeoListModel<T>::getGeometryFromGeoId(const std::vector<T>& geometrylist,
|
||||
int geoId)
|
||||
{
|
||||
if constexpr (std::is_same<T,GeometryPtr>()) {
|
||||
if constexpr (std::is_same<T, GeometryPtr>()) {
|
||||
if (geoId >= 0)
|
||||
return geometrylist[geoId];
|
||||
else
|
||||
return geometrylist[geometrylist.size()+geoId];
|
||||
return geometrylist[geometrylist.size() + geoId];
|
||||
}
|
||||
else if constexpr (std::is_same<T,GeometryFacadeUniquePtr>()) {
|
||||
else if constexpr (std::is_same<T, GeometryFacadeUniquePtr>()) {
|
||||
if (geoId >= 0)
|
||||
return geometrylist[geoId]->getGeometry();
|
||||
else
|
||||
return geometrylist[geometrylist.size()+geoId]->getGeometry();
|
||||
return geometrylist[geometrylist.size() + geoId]->getGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const Sketcher::GeometryFacade * GeoListModel<T>::getGeometryFacadeFromGeoId(const std::vector<T> & geometrylist, int geoId)
|
||||
template<typename T>
|
||||
const Sketcher::GeometryFacade*
|
||||
GeoListModel<T>::getGeometryFacadeFromGeoId(const std::vector<T>& geometrylist, int geoId)
|
||||
{
|
||||
if constexpr (std::is_same<T,GeometryPtr>()) {
|
||||
if constexpr (std::is_same<T, GeometryPtr>()) {
|
||||
if (geoId >= 0)
|
||||
return GeometryFacade::getFacade(geometrylist[geoId]).release();
|
||||
else
|
||||
return GeometryFacade::getFacade(geometrylist[geometrylist.size()+geoId]).release();
|
||||
return GeometryFacade::getFacade(geometrylist[geometrylist.size() + geoId]).release();
|
||||
}
|
||||
else if constexpr (std::is_same<T,GeometryFacadeUniquePtr>()) {
|
||||
else if constexpr (std::is_same<T, GeometryFacadeUniquePtr>()) {
|
||||
if (geoId >= 0)
|
||||
return geometrylist[geoId].get();
|
||||
else
|
||||
return geometrylist[geometrylist.size()+geoId].get();
|
||||
return geometrylist[geometrylist.size() + geoId].get();
|
||||
}
|
||||
}
|
||||
|
||||
// this function is used to simulate cyclic periodic negative geometry indices (for external geometry)
|
||||
template <typename T>
|
||||
const Part::Geometry * GeoListModel<T>::getGeometryFromGeoId(int geoId) const
|
||||
// this function is used to simulate cyclic periodic negative geometry indices (for external
|
||||
// geometry)
|
||||
template<typename T>
|
||||
const Part::Geometry* GeoListModel<T>::getGeometryFromGeoId(int geoId) const
|
||||
{
|
||||
return GeoListModel<T>::getGeometryFromGeoId(geomlist, geoId);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const Sketcher::GeometryFacade * GeoListModel<T>::getGeometryFacadeFromGeoId(int geoId) const
|
||||
template<typename T>
|
||||
const Sketcher::GeometryFacade* GeoListModel<T>::getGeometryFacadeFromGeoId(int geoId) const
|
||||
{
|
||||
return GeoListModel<T>::getGeometryFacadeFromGeoId(geomlist, geoId);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
Base::Vector3d GeoListModel<T>::getPoint(int geoId, Sketcher::PointPos pos) const
|
||||
{
|
||||
const Part::Geometry * geo = getGeometryFromGeoId(geoId);
|
||||
const Part::Geometry* geo = getGeometryFromGeoId(geoId);
|
||||
|
||||
return getPoint(geo, pos);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Base::Vector3d GeoListModel<T>::getPoint(const GeoElementId & geid) const
|
||||
template<typename T>
|
||||
Base::Vector3d GeoListModel<T>::getPoint(const GeoElementId& geid) const
|
||||
{
|
||||
return getPoint(geid.GeoId, geid.Pos);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Base::Vector3d GeoListModel<T>::getPoint(const Part::Geometry * geo, Sketcher::PointPos pos) const
|
||||
template<typename T>
|
||||
Base::Vector3d GeoListModel<T>::getPoint(const Part::Geometry* geo, Sketcher::PointPos pos) const
|
||||
{
|
||||
using namespace Sketcher;
|
||||
|
||||
if (geo->getTypeId() == Part::GeomPoint::getClassTypeId()) {
|
||||
const Part::GeomPoint *p = static_cast<const Part::GeomPoint*>(geo);
|
||||
const Part::GeomPoint* p = static_cast<const Part::GeomPoint*>(geo);
|
||||
if (pos == PointPos::start || pos == PointPos::mid || pos == PointPos::end)
|
||||
return p->getPoint();
|
||||
} else if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
const Part::GeomLineSegment *lineSeg = static_cast<const Part::GeomLineSegment*>(geo);
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
const Part::GeomLineSegment* lineSeg = static_cast<const Part::GeomLineSegment*>(geo);
|
||||
if (pos == PointPos::start)
|
||||
return lineSeg->getStartPoint();
|
||||
else if (pos == PointPos::end)
|
||||
return lineSeg->getEndPoint();
|
||||
} else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
const Part::GeomCircle *circle = static_cast<const Part::GeomCircle*>(geo);
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
const Part::GeomCircle* circle = static_cast<const Part::GeomCircle*>(geo);
|
||||
if (pos == PointPos::mid)
|
||||
return circle->getCenter();
|
||||
} else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
const Part::GeomEllipse *ellipse = static_cast<const Part::GeomEllipse*>(geo);
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
const Part::GeomEllipse* ellipse = static_cast<const Part::GeomEllipse*>(geo);
|
||||
if (pos == PointPos::mid)
|
||||
return ellipse->getCenter();
|
||||
} else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
const Part::GeomArcOfCircle *aoc = static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
const Part::GeomArcOfCircle* aoc = static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
if (pos == PointPos::start)
|
||||
return aoc->getStartPoint(/*emulateCCW=*/true);
|
||||
else if (pos == PointPos::end)
|
||||
return aoc->getEndPoint(/*emulateCCW=*/true);
|
||||
else if (pos == PointPos::mid)
|
||||
return aoc->getCenter();
|
||||
} else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
const Part::GeomArcOfEllipse *aoc = static_cast<const Part::GeomArcOfEllipse*>(geo);
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
const Part::GeomArcOfEllipse* aoc = static_cast<const Part::GeomArcOfEllipse*>(geo);
|
||||
if (pos == PointPos::start)
|
||||
return aoc->getStartPoint(/*emulateCCW=*/true);
|
||||
else if (pos == PointPos::end)
|
||||
return aoc->getEndPoint(/*emulateCCW=*/true);
|
||||
else if (pos == PointPos::mid)
|
||||
return aoc->getCenter();
|
||||
} else if (geo->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId()) {
|
||||
const Part::GeomArcOfHyperbola *aoh = static_cast<const Part::GeomArcOfHyperbola*>(geo);
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId()) {
|
||||
const Part::GeomArcOfHyperbola* aoh = static_cast<const Part::GeomArcOfHyperbola*>(geo);
|
||||
if (pos == PointPos::start)
|
||||
return aoh->getStartPoint();
|
||||
else if (pos == PointPos::end)
|
||||
return aoh->getEndPoint();
|
||||
else if (pos == PointPos::mid)
|
||||
return aoh->getCenter();
|
||||
} else if (geo->getTypeId() == Part::GeomArcOfParabola::getClassTypeId()) {
|
||||
const Part::GeomArcOfParabola *aop = static_cast<const Part::GeomArcOfParabola*>(geo);
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomArcOfParabola::getClassTypeId()) {
|
||||
const Part::GeomArcOfParabola* aop = static_cast<const Part::GeomArcOfParabola*>(geo);
|
||||
if (pos == PointPos::start)
|
||||
return aop->getStartPoint();
|
||||
else if (pos == PointPos::end)
|
||||
return aop->getEndPoint();
|
||||
else if (pos == PointPos::mid)
|
||||
return aop->getCenter();
|
||||
} else if (geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
|
||||
const Part::GeomBSplineCurve *bsp = static_cast<const Part::GeomBSplineCurve*>(geo);
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
|
||||
const Part::GeomBSplineCurve* bsp = static_cast<const Part::GeomBSplineCurve*>(geo);
|
||||
if (pos == PointPos::start)
|
||||
return bsp->getStartPoint();
|
||||
else if (pos == PointPos::end)
|
||||
@@ -219,20 +228,20 @@ Base::Vector3d GeoListModel<T>::getPoint(const Part::Geometry * geo, Sketcher::P
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
void GeoListModel<T>::rebuildVertexIndex() const
|
||||
{
|
||||
VertexId2GeoElementId.clear();
|
||||
GeoElementId2VertexId.clear();
|
||||
|
||||
int geoId=0;
|
||||
int pointId=0;
|
||||
int geoId = 0;
|
||||
int pointId = 0;
|
||||
|
||||
auto addGeoElement = [this, &pointId](int geoId, PointPos pos) {
|
||||
VertexId2GeoElementId.emplace_back(geoId,pos);
|
||||
VertexId2GeoElementId.emplace_back(geoId, pos);
|
||||
GeoElementId2VertexId.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(geoId, pos),
|
||||
std::forward_as_tuple(pointId++));
|
||||
std::forward_as_tuple(geoId, pos),
|
||||
std::forward_as_tuple(pointId++));
|
||||
};
|
||||
|
||||
if (geomlist.size() <= 2)
|
||||
@@ -241,72 +250,75 @@ void GeoListModel<T>::rebuildVertexIndex() const
|
||||
|
||||
Base::Type type;
|
||||
|
||||
if constexpr (std::is_same<T, Part::Geometry *>::value)
|
||||
if constexpr (std::is_same<T, Part::Geometry*>::value)
|
||||
type = (*it)->getTypeId();
|
||||
else if constexpr (std::is_same<T, std::unique_ptr<const Sketcher::GeometryFacade>>::value)
|
||||
type = (*it)->getGeometry()->getTypeId();
|
||||
|
||||
if ( geoId > getInternalCount())
|
||||
if (geoId > getInternalCount())
|
||||
geoId = -getExternalCount();
|
||||
|
||||
if (type == Part::GeomPoint::getClassTypeId()) {
|
||||
addGeoElement(geoId,PointPos::start);
|
||||
} else if (type == Part::GeomLineSegment::getClassTypeId() ||
|
||||
type == Part::GeomBSplineCurve::getClassTypeId()) {
|
||||
addGeoElement(geoId,PointPos::start);
|
||||
addGeoElement(geoId,PointPos::end);
|
||||
} else if (type == Part::GeomCircle::getClassTypeId() ||
|
||||
type == Part::GeomEllipse::getClassTypeId()) {
|
||||
addGeoElement(geoId,PointPos::mid);
|
||||
} else if (type == Part::GeomArcOfCircle::getClassTypeId() ||
|
||||
type == Part::GeomArcOfEllipse::getClassTypeId() ||
|
||||
type == Part::GeomArcOfHyperbola::getClassTypeId() ||
|
||||
type == Part::GeomArcOfParabola::getClassTypeId()) {
|
||||
addGeoElement(geoId,PointPos::start);
|
||||
addGeoElement(geoId,PointPos::end);
|
||||
addGeoElement(geoId,PointPos::mid);
|
||||
addGeoElement(geoId, PointPos::start);
|
||||
}
|
||||
else if (type == Part::GeomLineSegment::getClassTypeId()
|
||||
|| type == Part::GeomBSplineCurve::getClassTypeId()) {
|
||||
addGeoElement(geoId, PointPos::start);
|
||||
addGeoElement(geoId, PointPos::end);
|
||||
}
|
||||
else if (type == Part::GeomCircle::getClassTypeId()
|
||||
|| type == Part::GeomEllipse::getClassTypeId()) {
|
||||
addGeoElement(geoId, PointPos::mid);
|
||||
}
|
||||
else if (type == Part::GeomArcOfCircle::getClassTypeId()
|
||||
|| type == Part::GeomArcOfEllipse::getClassTypeId()
|
||||
|| type == Part::GeomArcOfHyperbola::getClassTypeId()
|
||||
|| type == Part::GeomArcOfParabola::getClassTypeId()) {
|
||||
addGeoElement(geoId, PointPos::start);
|
||||
addGeoElement(geoId, PointPos::end);
|
||||
addGeoElement(geoId, PointPos::mid);
|
||||
}
|
||||
}
|
||||
|
||||
indexInit = true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
Sketcher::GeoElementId GeoListModel<T>::getGeoElementIdFromVertexId(int vertexId)
|
||||
{
|
||||
if(!indexInit) // lazy initialised
|
||||
if (!indexInit)// lazy initialised
|
||||
rebuildVertexIndex();
|
||||
|
||||
return VertexId2GeoElementId[vertexId];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int GeoListModel<T>::getVertexIdFromGeoElementId(const Sketcher::GeoElementId & geoelementId) const
|
||||
template<typename T>
|
||||
int GeoListModel<T>::getVertexIdFromGeoElementId(const Sketcher::GeoElementId& geoelementId) const
|
||||
{
|
||||
if(!indexInit) // lazy initialised
|
||||
if (!indexInit)// lazy initialised
|
||||
rebuildVertexIndex();
|
||||
|
||||
auto found = std::find(VertexId2GeoElementId.begin(), VertexId2GeoElementId.end(), geoelementId);
|
||||
auto found =
|
||||
std::find(VertexId2GeoElementId.begin(), VertexId2GeoElementId.end(), geoelementId);
|
||||
|
||||
if( found != VertexId2GeoElementId.end() )
|
||||
if (found != VertexId2GeoElementId.end())
|
||||
return std::distance(found, VertexId2GeoElementId.begin());
|
||||
|
||||
THROWM(Base::IndexError, "GeoElementId not indexed");
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace Sketcher {
|
||||
namespace Sketcher
|
||||
{
|
||||
|
||||
// Template specialisations
|
||||
template <>
|
||||
template<>
|
||||
GeoListModel<GeometryFacadeUniquePtr>::GeoListModel(
|
||||
std::vector<GeometryFacadeUniquePtr> && geometrylist,
|
||||
int intgeocount,
|
||||
bool ownerT) : geomlist(std::move(geometrylist)),
|
||||
intGeoCount(intgeocount),
|
||||
OwnerT(false),
|
||||
indexInit(false)
|
||||
std::vector<GeometryFacadeUniquePtr>&& geometrylist, int intgeocount, bool ownerT)
|
||||
: geomlist(std::move(geometrylist)),
|
||||
intGeoCount(intgeocount),
|
||||
OwnerT(false),
|
||||
indexInit(false)
|
||||
{
|
||||
// GeometryFacades hold the responsibility for releasing the resources.
|
||||
//
|
||||
@@ -321,62 +333,72 @@ GeoListModel<GeometryFacadeUniquePtr>::GeoListModel(
|
||||
boost::ignore_unused(ownerT);
|
||||
}
|
||||
|
||||
template <>
|
||||
template<>
|
||||
GeoListModel<GeometryFacadeUniquePtr>::GeoListModel(
|
||||
const std::vector<GeometryFacadeUniquePtr> & geometrylist,
|
||||
int intgeocount): intGeoCount(intgeocount),
|
||||
OwnerT(false),
|
||||
indexInit(false)
|
||||
const std::vector<GeometryFacadeUniquePtr>& geometrylist, int intgeocount)
|
||||
: intGeoCount(intgeocount),
|
||||
OwnerT(false),
|
||||
indexInit(false)
|
||||
{
|
||||
// GeometryFacades are movable, but not copiable, so they need to be reconstructed (shallow copy of vector)
|
||||
// Under the Single Responsibility Principle, these will not take over a responsibility that shall be enforced
|
||||
// on the original GeometryFacade. Use the move version of getGeoListModel if moving the responsibility is intended.
|
||||
// GeometryFacades are movable, but not copiable, so they need to be reconstructed (shallow copy
|
||||
// of vector) Under the Single Responsibility Principle, these will not take over a
|
||||
// responsibility that shall be enforced on the original GeometryFacade. Use the move version of
|
||||
// getGeoListModel if moving the responsibility is intended.
|
||||
|
||||
geomlist.reserve(geometrylist.size());
|
||||
|
||||
for(auto & v : geometrylist) {
|
||||
for (auto& v : geometrylist) {
|
||||
geomlist.push_back(GeometryFacade::getFacade(v->getGeometry()));
|
||||
}
|
||||
}
|
||||
|
||||
template <> SketcherExport
|
||||
GeoListModel<std::unique_ptr<const Sketcher::GeometryFacade>>::~GeoListModel()
|
||||
template<>
|
||||
SketcherExport GeoListModel<std::unique_ptr<const Sketcher::GeometryFacade>>::~GeoListModel()
|
||||
{
|
||||
// GeometryFacade is responsible for taken ownership of its pointers and deleting them.
|
||||
|
||||
}
|
||||
|
||||
|
||||
// instantiate the types so that other translation units can access template constructors
|
||||
template class SketcherExport GeoListModel<Part::Geometry *>;
|
||||
template class SketcherExport GeoListModel<Part::Geometry*>;
|
||||
#if !defined(__MINGW32__)
|
||||
template class SketcherExport GeoListModel<std::unique_ptr<const Sketcher::GeometryFacade>>;
|
||||
#else
|
||||
// Remark: It looks like when implementing a method of GeoListModel for GeometryFacadeUniquePtr then under MinGW
|
||||
// the explicit template instantiation doesn't do anything. As workaround all other methods must be declared separately
|
||||
template SketcherExport const Part::Geometry* GeoListModel<GeometryFacadeUniquePtr>::getGeometryFromGeoId(int geoId) const;
|
||||
template SketcherExport const Sketcher::GeometryFacade* GeoListModel<GeometryFacadeUniquePtr>::getGeometryFacadeFromGeoId(int geoId) const;
|
||||
template SketcherExport int GeoListModel<GeometryFacadeUniquePtr>::getGeoIdFromGeomListIndex(int index) const;
|
||||
template SketcherExport int GeoListModel<GeometryFacadeUniquePtr>::getVertexIdFromGeoElementId(const Sketcher::GeoElementId &) const;
|
||||
template SketcherExport GeoElementId GeoListModel<GeometryFacadeUniquePtr>::getGeoElementIdFromVertexId(int);
|
||||
template SketcherExport Base::Vector3d GeoListModel<GeometryFacadeUniquePtr>::getPoint(int geoId, Sketcher::PointPos pos) const;
|
||||
template SketcherExport Base::Vector3d GeoListModel<GeometryFacadeUniquePtr>::getPoint(const GeoElementId &) const;
|
||||
template SketcherExport GeoListModel<GeometryFacadeUniquePtr> GeoListModel<GeometryFacadeUniquePtr>::getGeoListModel
|
||||
(std::vector<GeometryFacadeUniquePtr>&& geometrylist, int intgeocount, bool ownerT);
|
||||
// Remark: It looks like when implementing a method of GeoListModel for GeometryFacadeUniquePtr then
|
||||
// under MinGW the explicit template instantiation doesn't do anything. As workaround all other
|
||||
// methods must be declared separately
|
||||
template SketcherExport const Part::Geometry*
|
||||
GeoListModel<GeometryFacadeUniquePtr>::getGeometryFromGeoId(int geoId) const;
|
||||
template SketcherExport const Sketcher::GeometryFacade*
|
||||
GeoListModel<GeometryFacadeUniquePtr>::getGeometryFacadeFromGeoId(int geoId) const;
|
||||
template SketcherExport int
|
||||
GeoListModel<GeometryFacadeUniquePtr>::getGeoIdFromGeomListIndex(int index) const;
|
||||
template SketcherExport int GeoListModel<GeometryFacadeUniquePtr>::getVertexIdFromGeoElementId(
|
||||
const Sketcher::GeoElementId&) const;
|
||||
template SketcherExport GeoElementId
|
||||
GeoListModel<GeometryFacadeUniquePtr>::getGeoElementIdFromVertexId(int);
|
||||
template SketcherExport Base::Vector3d
|
||||
GeoListModel<GeometryFacadeUniquePtr>::getPoint(int geoId, Sketcher::PointPos pos) const;
|
||||
template SketcherExport Base::Vector3d
|
||||
GeoListModel<GeometryFacadeUniquePtr>::getPoint(const GeoElementId&) const;
|
||||
template SketcherExport GeoListModel<GeometryFacadeUniquePtr>
|
||||
GeoListModel<GeometryFacadeUniquePtr>::getGeoListModel(
|
||||
std::vector<GeometryFacadeUniquePtr>&& geometrylist, int intgeocount, bool ownerT);
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
GeoListFacade Sketcher::getGeoListFacade(const GeoList & geolist)
|
||||
GeoListFacade Sketcher::getGeoListFacade(const GeoList& geolist)
|
||||
{
|
||||
std::vector<std::unique_ptr<const GeometryFacade>> facade;
|
||||
facade.reserve( geolist.geomlist.size());
|
||||
facade.reserve(geolist.geomlist.size());
|
||||
|
||||
for(auto geo : geolist.geomlist)
|
||||
for (auto geo : geolist.geomlist)
|
||||
facade.push_back(GeometryFacade::getFacade(geo));
|
||||
|
||||
auto geolistfacade = GeoListFacade::getGeoListModel(std::move(facade), geolist.getInternalCount());
|
||||
auto geolistfacade =
|
||||
GeoListFacade::getGeoListModel(std::move(facade), geolist.getInternalCount());
|
||||
|
||||
return geolistfacade;
|
||||
}
|
||||
|
||||
@@ -30,19 +30,23 @@
|
||||
#include "GeometryFacade.h"
|
||||
|
||||
|
||||
namespace Base {
|
||||
template< typename T >
|
||||
class Vector3;
|
||||
namespace Base
|
||||
{
|
||||
template<typename T>
|
||||
class Vector3;
|
||||
}
|
||||
|
||||
namespace Part {
|
||||
class Geometry;
|
||||
namespace Part
|
||||
{
|
||||
class Geometry;
|
||||
}
|
||||
|
||||
namespace Sketcher {
|
||||
namespace Sketcher
|
||||
{
|
||||
}
|
||||
|
||||
namespace Sketcher {
|
||||
namespace Sketcher
|
||||
{
|
||||
|
||||
/** @brief Class for managing internal and external geometry as a single object
|
||||
* @details
|
||||
@@ -66,107 +70,126 @@ namespace Sketcher {
|
||||
* N.B.: Note that the index of the geomlist (all layers) and the GeoId can be converted
|
||||
* from each other as needed using the member functions (and sometimes the static functions).
|
||||
*/
|
||||
template <typename T>
|
||||
class GeoListModel {
|
||||
template<typename T>
|
||||
class GeoListModel
|
||||
{
|
||||
using Vector3d = Base::Vector3<double>;
|
||||
|
||||
|
||||
protected:
|
||||
/** @brief
|
||||
* Constructors are protected, use static methods getGeoListModel() to construct the objects instead.
|
||||
* Constructors are protected, use static methods getGeoListModel() to construct the objects
|
||||
* instead.
|
||||
*
|
||||
* Constructs the object from a list of geometry in geomlist format and the number of internal
|
||||
* geometries (non external) present in the list.
|
||||
*
|
||||
* @param geometrylist: the geometry in geomlist format (external after internal in a single vector).
|
||||
* @param geometrylist: the geometry in geomlist format (external after internal in a single
|
||||
* vector).
|
||||
* @param intgeocount: the number of internal geometries (non external) in the list.
|
||||
* @param ownerT: indicates whether the GeoListModel takes ownership of the elements of the std::vector<T> (for pointers)
|
||||
* @param ownerT: indicates whether the GeoListModel takes ownership of the elements of the
|
||||
* std::vector<T> (for pointers)
|
||||
*/
|
||||
explicit GeoListModel(std::vector<T> && geometrylist, int intgeocount, bool ownerT = false);
|
||||
explicit GeoListModel(std::vector<T>&& geometrylist, int intgeocount, bool ownerT = false);
|
||||
|
||||
explicit GeoListModel(const std::vector<T> & geometrylist, int intgeocount);
|
||||
explicit GeoListModel(const std::vector<T>& geometrylist, int intgeocount);
|
||||
|
||||
public:
|
||||
/** @brief Destructor having type dependent behaviour
|
||||
*
|
||||
* @warning
|
||||
* For GeoList, the destructor will destruct the Part::Geometry pointers * only * if it was constructed with ownerT = true.
|
||||
* For GeoList, the destructor will destruct the Part::Geometry pointers * only * if it was
|
||||
* constructed with ownerT = true.
|
||||
*
|
||||
* For GeoListFacade, the smart pointers will be deleted. However, a GeometryFacade does * not * delete the underlying naked pointers
|
||||
* by default (which is mostly the desired behaviour as the ownership of the pointers belongs to sketchObject). If GeometryFacade is
|
||||
* to delete the underlying naked pointers (because it is a temporal deep copy), then the GeometryFacade needs to get ownership (see
|
||||
* setOwner method).
|
||||
* For GeoListFacade, the smart pointers will be deleted. However, a GeometryFacade does * not *
|
||||
* delete the underlying naked pointers by default (which is mostly the desired behaviour as the
|
||||
* ownership of the pointers belongs to sketchObject). If GeometryFacade is to delete the
|
||||
* underlying naked pointers (because it is a temporal deep copy), then the GeometryFacade needs
|
||||
* to get ownership (see setOwner method).
|
||||
*
|
||||
*/
|
||||
~GeoListModel();
|
||||
|
||||
// Explicit deletion to show intent (not that it is needed). This is a move only type.
|
||||
GeoListModel(const GeoListModel &) = delete;
|
||||
GeoListModel(const GeoListModel&) = delete;
|
||||
GeoListModel& operator=(const GeoListModel&) = delete;
|
||||
|
||||
// enable move constructor and move assignment. This is a move only type.
|
||||
GeoListModel(GeoListModel &&) = default;
|
||||
GeoListModel(GeoListModel&&) = default;
|
||||
GeoListModel& operator=(GeoListModel&&) = default;
|
||||
|
||||
/** @brief
|
||||
* GeoListModel manages the lifetime of its internal std::vector. This means that while the actual ownership
|
||||
* of the T parameter needs to be specified or separately handled. In the absence of that, a new vector will
|
||||
* be created and the T elements shallow copied to the internal vector.
|
||||
* GeoListModel manages the lifetime of its internal std::vector. This means that while the
|
||||
* actual ownership of the T parameter needs to be specified or separately handled. In the
|
||||
* absence of that, a new vector will be created and the T elements shallow copied to the
|
||||
* internal vector.
|
||||
*
|
||||
* The constness of the GeoListModel is tied to the constness of the std::vector from which it is constructed.
|
||||
* The constness of the GeoListModel is tied to the constness of the std::vector from which it
|
||||
* is constructed.
|
||||
*
|
||||
* @warning
|
||||
* For GeoListFacade ownership at GeoListModel level cannot be taken (ownerT cannot be true). An assertion is raised
|
||||
* if this happens. The ownership needs to be specified on the GeoListFacade objects themselves (setOwner method).
|
||||
* For GeoListFacade ownership at GeoListModel level cannot be taken (ownerT cannot be true). An
|
||||
* assertion is raised if this happens. The ownership needs to be specified on the GeoListFacade
|
||||
* objects themselves (setOwner method).
|
||||
*/
|
||||
static GeoListModel<T> getGeoListModel(std::vector<T> && geometrylist, int intgeocount, bool ownerT = false);
|
||||
static const GeoListModel<T> getGeoListModel(const std::vector<T> & geometrylist, int intgeocount);
|
||||
static GeoListModel<T> getGeoListModel(std::vector<T>&& geometrylist, int intgeocount,
|
||||
bool ownerT = false);
|
||||
static const GeoListModel<T> getGeoListModel(const std::vector<T>& geometrylist,
|
||||
int intgeocount);
|
||||
|
||||
|
||||
/** @brief
|
||||
* returns the geometry given by the GeoId
|
||||
*/
|
||||
const Part::Geometry * getGeometryFromGeoId(int geoId) const;
|
||||
* returns the geometry given by the GeoId
|
||||
*/
|
||||
const Part::Geometry* getGeometryFromGeoId(int geoId) const;
|
||||
|
||||
/** @brief returns a geometryfacade
|
||||
* @warning If the underlying model of the list is a naked pointed (Part::Geometry *), i.e. a GeoList instantiation, the
|
||||
* client (the user) bears responsibility for releasing the GeometryFacade pointer!!
|
||||
* @warning If the underlying model of the list is a naked pointed (Part::Geometry *), i.e. a
|
||||
* GeoList instantiation, the client (the user) bears responsibility for releasing the
|
||||
* GeometryFacade pointer!!
|
||||
*
|
||||
* This is not a problem when the model of the list is a std::unique_ptr<Sketcher::GeometryFacade>, because the lifetime is tied to
|
||||
* the GeometryFacade. It will destruct the pointer if it is the owner.
|
||||
* This is not a problem when the model of the list is a
|
||||
* std::unique_ptr<Sketcher::GeometryFacade>, because the lifetime is tied to the
|
||||
* GeometryFacade. It will destruct the pointer if it is the owner.
|
||||
*/
|
||||
const Sketcher::GeometryFacade * getGeometryFacadeFromGeoId(int geoId) const;
|
||||
const Sketcher::GeometryFacade* getGeometryFacadeFromGeoId(int geoId) const;
|
||||
|
||||
/** @brief
|
||||
* returns the GeoId index from the index in the geometry in geomlist format with which it was constructed.
|
||||
*
|
||||
* @param index: the index of the list of geometry in geomlist format.
|
||||
*/
|
||||
* returns the GeoId index from the index in the geometry in geomlist format with which it was
|
||||
* constructed.
|
||||
*
|
||||
* @param index: the index of the list of geometry in geomlist format.
|
||||
*/
|
||||
int getGeoIdFromGeomListIndex(int index) const;
|
||||
|
||||
/** @brief
|
||||
* returns the geometry given by the GeoId in the geometrylist in geomlist format provided as a parameter.
|
||||
*
|
||||
* @param geometrylist: the geometry in geomlist format (external after internal in a single vector).
|
||||
*
|
||||
* @param index: the index of the list of geometry in geomlist format.
|
||||
*/
|
||||
static const Part::Geometry * getGeometryFromGeoId(const std::vector<T> & geometrylist, int geoId);
|
||||
* returns the geometry given by the GeoId in the geometrylist in geomlist format provided as a
|
||||
* parameter.
|
||||
*
|
||||
* @param geometrylist: the geometry in geomlist format (external after internal in a single
|
||||
* vector).
|
||||
*
|
||||
* @param index: the index of the list of geometry in geomlist format.
|
||||
*/
|
||||
static const Part::Geometry* getGeometryFromGeoId(const std::vector<T>& geometrylist,
|
||||
int geoId);
|
||||
|
||||
/** @brief returns a geometry facade
|
||||
* @warning If the underlying model of the list is a naked pointed (Part::Geometry *), the client (the user) bears responsibility
|
||||
* for releasing the GeometryFacade pointer!!
|
||||
* @warning If the underlying model of the list is a naked pointed (Part::Geometry *), the
|
||||
* client (the user) bears responsibility for releasing the GeometryFacade pointer!!
|
||||
*
|
||||
* This is not a problem when the model of the list is a std::unique_ptr<Sketcher::GeometryFacade>, because the lifetime is tied to
|
||||
* the model itself.
|
||||
* This is not a problem when the model of the list is a
|
||||
* std::unique_ptr<Sketcher::GeometryFacade>, because the lifetime is tied to the model itself.
|
||||
*/
|
||||
static const Sketcher::GeometryFacade * getGeometryFacadeFromGeoId(const std::vector<T> & geometrylist, int geoId);
|
||||
static const Sketcher::GeometryFacade*
|
||||
getGeometryFacadeFromGeoId(const std::vector<T>& geometrylist, int geoId);
|
||||
|
||||
/** @brief
|
||||
* Obtain a GeoElementId class {GeoId, Pos} given a VertexId.
|
||||
*
|
||||
* A vertexId is a positive index of the vertex, where indices of external geometry taken higher positive values than normal geometry.
|
||||
* It is the same format of vertex numbering used in the Sketcher, Sketch.cpp, and ViewProviderSketch.
|
||||
* A vertexId is a positive index of the vertex, where indices of external geometry taken higher
|
||||
* positive values than normal geometry. It is the same format of vertex numbering used in the
|
||||
* Sketcher, Sketch.cpp, and ViewProviderSketch.
|
||||
*
|
||||
*/
|
||||
Sketcher::GeoElementId getGeoElementIdFromVertexId(int vertexId);
|
||||
@@ -175,31 +198,38 @@ public:
|
||||
/** @brief
|
||||
* Given an GeoElementId {GeoId, Pos}, it returns the index of the vertex in VertexId format.
|
||||
*
|
||||
* A vertexId is a positive index of the vertex, where indices of external geometry taken higher positive values than normal geometry.
|
||||
* It is the same format of vertex numbering used in the Sketcher, Sketch.cpp, and ViewProviderSketch.
|
||||
* A vertexId is a positive index of the vertex, where indices of external geometry taken higher
|
||||
* positive values than normal geometry. It is the same format of vertex numbering used in the
|
||||
* Sketcher, Sketch.cpp, and ViewProviderSketch.
|
||||
*
|
||||
*/
|
||||
int getVertexIdFromGeoElementId(const Sketcher::GeoElementId & geoelementId) const;
|
||||
int getVertexIdFromGeoElementId(const Sketcher::GeoElementId& geoelementId) const;
|
||||
|
||||
/** @brief
|
||||
* Returns a point coordinates given {GeoId, Pos}.
|
||||
*/
|
||||
Vector3d getPoint(int geoId, Sketcher::PointPos pos) const;
|
||||
|
||||
/** @brief
|
||||
/** @brief
|
||||
* Returns a point coordinates given GeoElementId {GeoId, Pos}.
|
||||
*/
|
||||
Vector3d getPoint(const GeoElementId & geid) const;
|
||||
Vector3d getPoint(const GeoElementId& geid) const;
|
||||
|
||||
/** @brief
|
||||
* returns the amount of internal (normal, non-external) geometry objects.
|
||||
*/
|
||||
int getInternalCount() const { return intGeoCount;}
|
||||
* returns the amount of internal (normal, non-external) geometry objects.
|
||||
*/
|
||||
int getInternalCount() const
|
||||
{
|
||||
return intGeoCount;
|
||||
}
|
||||
|
||||
/** @brief
|
||||
* returns the amount of external geometry objects.
|
||||
*/
|
||||
int getExternalCount() const { return int(geomlist.size()) - intGeoCount;}
|
||||
* returns the amount of external geometry objects.
|
||||
*/
|
||||
int getExternalCount() const
|
||||
{
|
||||
return int(geomlist.size()) - intGeoCount;
|
||||
}
|
||||
|
||||
/** @brief
|
||||
* return a reference to the internal geometry list vector.
|
||||
@@ -207,13 +237,16 @@ public:
|
||||
* @warning { It returns a reference to the internal list vector. The validity of the
|
||||
* reference depends on the lifetime of the GeoListModel object.}
|
||||
*/
|
||||
std::vector<T> & geometryList() { return const_cast<std::vector<T> &>(geomlist);}
|
||||
std::vector<T>& geometryList()
|
||||
{
|
||||
return const_cast<std::vector<T>&>(geomlist);
|
||||
}
|
||||
|
||||
public:
|
||||
std::vector<T> geomlist;
|
||||
|
||||
private:
|
||||
Vector3d getPoint(const Part::Geometry * geo, Sketcher::PointPos pos) const;
|
||||
Vector3d getPoint(const Part::Geometry* geo, Sketcher::PointPos pos) const;
|
||||
|
||||
void rebuildVertexIndex() const;
|
||||
|
||||
@@ -221,20 +254,20 @@ private:
|
||||
int intGeoCount;
|
||||
bool OwnerT;
|
||||
mutable bool indexInit;
|
||||
mutable std::vector<Sketcher::GeoElementId> VertexId2GeoElementId; // these maps a lazy initialised on first demand.
|
||||
mutable std::vector<Sketcher::GeoElementId>
|
||||
VertexId2GeoElementId;// these maps a lazy initialised on first demand.
|
||||
mutable std::map<Sketcher::GeoElementId, int> GeoElementId2VertexId;
|
||||
};
|
||||
|
||||
using GeometryPtr = Part::Geometry *;
|
||||
using GeometryPtr = Part::Geometry*;
|
||||
using GeometryFacadeUniquePtr = std::unique_ptr<const Sketcher::GeometryFacade>;
|
||||
|
||||
using GeoList = GeoListModel<GeometryPtr>;
|
||||
using GeoListFacade = GeoListModel<GeometryFacadeUniquePtr>;
|
||||
|
||||
GeoListFacade getGeoListFacade(const GeoList & geolist);
|
||||
GeoListFacade getGeoListFacade(const GeoList& geolist);
|
||||
|
||||
} // namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCHER_GeoList_H
|
||||
|
||||
#endif// SKETCHER_GeoList_H
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <boost/uuid/uuid_io.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#endif
|
||||
|
||||
#include "GeometryFacade.h"
|
||||
@@ -31,17 +31,19 @@
|
||||
|
||||
using namespace Sketcher;
|
||||
|
||||
TYPESYSTEM_SOURCE(Sketcher::GeometryFacade,Base::BaseClass)
|
||||
TYPESYSTEM_SOURCE(Sketcher::GeometryFacade, Base::BaseClass)
|
||||
|
||||
GeometryFacade::GeometryFacade(): Geo(nullptr), OwnerGeo(false), SketchGeoExtension(nullptr)
|
||||
GeometryFacade::GeometryFacade()
|
||||
: Geo(nullptr),
|
||||
OwnerGeo(false),
|
||||
SketchGeoExtension(nullptr)
|
||||
{}
|
||||
|
||||
GeometryFacade::GeometryFacade(const Part::Geometry* geometry, bool owner)
|
||||
: Geo(geometry),
|
||||
OwnerGeo(owner)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GeometryFacade::GeometryFacade(const Part::Geometry * geometry, bool owner)
|
||||
: Geo(geometry), OwnerGeo(owner)
|
||||
{
|
||||
assert(geometry); // This should never be nullptr, as this constructor is protected
|
||||
assert(geometry);// This should never be nullptr, as this constructor is protected
|
||||
|
||||
initExtension();
|
||||
}
|
||||
@@ -52,29 +54,31 @@ GeometryFacade::~GeometryFacade()
|
||||
delete Geo;
|
||||
}
|
||||
|
||||
std::unique_ptr<GeometryFacade> GeometryFacade::getFacade(Part::Geometry * geometry, bool owner)
|
||||
std::unique_ptr<GeometryFacade> GeometryFacade::getFacade(Part::Geometry* geometry, bool owner)
|
||||
{
|
||||
if(geometry)
|
||||
if (geometry)
|
||||
return std::unique_ptr<GeometryFacade>(new GeometryFacade(geometry, owner));
|
||||
else
|
||||
return std::unique_ptr<GeometryFacade>(nullptr);
|
||||
//return std::make_unique<GeometryFacade>(geometry); // make_unique has no access to private constructor
|
||||
// make_unique has no access to private constructor
|
||||
// return std::make_unique<GeometryFacade>(geometry);
|
||||
}
|
||||
|
||||
std::unique_ptr<const GeometryFacade> GeometryFacade::getFacade(const Part::Geometry * geometry)
|
||||
std::unique_ptr<const GeometryFacade> GeometryFacade::getFacade(const Part::Geometry* geometry)
|
||||
{
|
||||
if(geometry)
|
||||
if (geometry)
|
||||
return std::unique_ptr<const GeometryFacade>(new GeometryFacade(geometry));
|
||||
else
|
||||
else
|
||||
return std::unique_ptr<const GeometryFacade>(nullptr);
|
||||
//return std::make_unique<const GeometryFacade>(geometry); // make_unique has no access to private constructor
|
||||
// make_unique has no access to private constructor
|
||||
// return std::make_unique<const GeometryFacade>(geometry);
|
||||
}
|
||||
|
||||
void GeometryFacade::setGeometry(Part::Geometry *geometry)
|
||||
void GeometryFacade::setGeometry(Part::Geometry* geometry)
|
||||
{
|
||||
Geo = geometry;
|
||||
|
||||
if(geometry)
|
||||
if (geometry)
|
||||
initExtension();
|
||||
else
|
||||
THROWM(Base::ValueError, "GeometryFacade initialized with Geometry null pointer");
|
||||
@@ -82,46 +86,48 @@ void GeometryFacade::setGeometry(Part::Geometry *geometry)
|
||||
|
||||
void GeometryFacade::initExtension()
|
||||
{
|
||||
if(!Geo->hasExtension(SketchGeometryExtension::getClassTypeId())) {
|
||||
if (!Geo->hasExtension(SketchGeometryExtension::getClassTypeId())) {
|
||||
|
||||
getGeo()->setExtension(std::make_unique<SketchGeometryExtension>()); // Create getExtension
|
||||
getGeo()->setExtension(std::make_unique<SketchGeometryExtension>());// Create getExtension
|
||||
|
||||
//Base::Console().Warning("%s\nSketcher Geometry without Extension: %s \n", boost::uuids::to_string(Geo->getTag()).c_str());
|
||||
// Base::Console().Warning("%s\nSketcher Geometry without Extension: %s \n",
|
||||
// boost::uuids::to_string(Geo->getTag()).c_str());
|
||||
}
|
||||
|
||||
SketchGeoExtension =
|
||||
std::static_pointer_cast<const SketchGeometryExtension>(
|
||||
(Geo->getExtension(SketchGeometryExtension::getClassTypeId())).lock()
|
||||
);
|
||||
SketchGeoExtension = std::static_pointer_cast<const SketchGeometryExtension>(
|
||||
(Geo->getExtension(SketchGeometryExtension::getClassTypeId())).lock());
|
||||
}
|
||||
|
||||
void GeometryFacade::initExtension() const
|
||||
{
|
||||
// const Geometry without SketchGeometryExtension cannot initialise a GeometryFacade
|
||||
if(!Geo->hasExtension(SketchGeometryExtension::getClassTypeId()))
|
||||
THROWM(Base::ValueError, "Cannot create a GeometryFacade out of a const Geometry pointer not having a SketchGeometryExtension!");
|
||||
if (!Geo->hasExtension(SketchGeometryExtension::getClassTypeId()))
|
||||
THROWM(Base::ValueError,
|
||||
"Cannot create a GeometryFacade out of a const Geometry pointer not having a "
|
||||
"SketchGeometryExtension!");
|
||||
|
||||
auto ext = std::static_pointer_cast<const SketchGeometryExtension>(Geo->getExtension(SketchGeometryExtension::getClassTypeId()).lock());
|
||||
auto ext = std::static_pointer_cast<const SketchGeometryExtension>(
|
||||
Geo->getExtension(SketchGeometryExtension::getClassTypeId()).lock());
|
||||
|
||||
const_cast<GeometryFacade *>(this)->SketchGeoExtension = ext;
|
||||
const_cast<GeometryFacade*>(this)->SketchGeoExtension = ext;
|
||||
}
|
||||
|
||||
void GeometryFacade::throwOnNullPtr(const Part::Geometry * geo)
|
||||
void GeometryFacade::throwOnNullPtr(const Part::Geometry* geo)
|
||||
{
|
||||
if(!geo)
|
||||
if (!geo)
|
||||
THROWM(Base::ValueError, "Geometry is nullptr!");
|
||||
}
|
||||
|
||||
void GeometryFacade::ensureSketchGeometryExtension(Part::Geometry * geometry)
|
||||
void GeometryFacade::ensureSketchGeometryExtension(Part::Geometry* geometry)
|
||||
{
|
||||
throwOnNullPtr(geometry);
|
||||
|
||||
if(!geometry->hasExtension(SketchGeometryExtension::getClassTypeId())) {
|
||||
geometry->setExtension(std::make_unique<SketchGeometryExtension>()); // Create getExtension
|
||||
if (!geometry->hasExtension(SketchGeometryExtension::getClassTypeId())) {
|
||||
geometry->setExtension(std::make_unique<SketchGeometryExtension>());// Create getExtension
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryFacade::copyId(const Part::Geometry * src, Part::Geometry * dst)
|
||||
void GeometryFacade::copyId(const Part::Geometry* src, Part::Geometry* dst)
|
||||
{
|
||||
throwOnNullPtr(src);
|
||||
throwOnNullPtr(dst);
|
||||
@@ -131,7 +137,7 @@ void GeometryFacade::copyId(const Part::Geometry * src, Part::Geometry * dst)
|
||||
gfdst->setId(gfsrc->getId());
|
||||
}
|
||||
|
||||
bool GeometryFacade::getConstruction(const Part::Geometry * geometry)
|
||||
bool GeometryFacade::getConstruction(const Part::Geometry* geometry)
|
||||
{
|
||||
throwOnNullPtr(geometry);
|
||||
|
||||
@@ -139,7 +145,7 @@ bool GeometryFacade::getConstruction(const Part::Geometry * geometry)
|
||||
return gf->getConstruction();
|
||||
}
|
||||
|
||||
void GeometryFacade::setConstruction(Part::Geometry * geometry, bool construction)
|
||||
void GeometryFacade::setConstruction(Part::Geometry* geometry, bool construction)
|
||||
{
|
||||
throwOnNullPtr(geometry);
|
||||
|
||||
@@ -147,7 +153,7 @@ void GeometryFacade::setConstruction(Part::Geometry * geometry, bool constructio
|
||||
return gf->setConstruction(construction);
|
||||
}
|
||||
|
||||
bool GeometryFacade::isInternalType(const Part::Geometry * geometry, InternalType::InternalType type)
|
||||
bool GeometryFacade::isInternalType(const Part::Geometry* geometry, InternalType::InternalType type)
|
||||
{
|
||||
throwOnNullPtr(geometry);
|
||||
|
||||
@@ -155,7 +161,7 @@ bool GeometryFacade::isInternalType(const Part::Geometry * geometry, InternalTyp
|
||||
return gf->getInternalType() == type;
|
||||
}
|
||||
|
||||
bool GeometryFacade::isInternalAligned(const Part::Geometry * geometry)
|
||||
bool GeometryFacade::isInternalAligned(const Part::Geometry* geometry)
|
||||
{
|
||||
throwOnNullPtr(geometry);
|
||||
|
||||
@@ -163,7 +169,7 @@ bool GeometryFacade::isInternalAligned(const Part::Geometry * geometry)
|
||||
return gf->isInternalAligned();
|
||||
}
|
||||
|
||||
bool GeometryFacade::getBlocked(const Part::Geometry * geometry)
|
||||
bool GeometryFacade::getBlocked(const Part::Geometry* geometry)
|
||||
{
|
||||
throwOnNullPtr(geometry);
|
||||
|
||||
@@ -171,7 +177,7 @@ bool GeometryFacade::getBlocked(const Part::Geometry * geometry)
|
||||
return gf->getBlocked();
|
||||
}
|
||||
|
||||
PyObject * GeometryFacade::getPyObject()
|
||||
PyObject* GeometryFacade::getPyObject()
|
||||
{
|
||||
return new GeometryFacadePy(new GeometryFacade(this->Geo));
|
||||
}
|
||||
|
||||
@@ -34,29 +34,34 @@ namespace Sketcher
|
||||
{
|
||||
|
||||
class GeometryFacadePy;
|
||||
/** @brief This class is a Facade to handle geometry and sketcher geometry extensions with a single sketcher specific interface
|
||||
/** @brief This class is a Facade to handle geometry and sketcher geometry extensions with a single
|
||||
* sketcher specific interface
|
||||
*
|
||||
* @details
|
||||
* The facade privately inherits from a common interface it shares with the extension thereby implementing a compiler enforced
|
||||
* same interface as the extension. It does not inherit from Part::Geometry and thus is intended to provide, in part a convenience
|
||||
* subset of the interface of Part::Geometry, in part a different interface.
|
||||
* The facade privately inherits from a common interface it shares with the extension thereby
|
||||
* implementing a compiler enforced same interface as the extension. It does not inherit from
|
||||
* Part::Geometry and thus is intended to provide, in part a convenience subset of the interface of
|
||||
* Part::Geometry, in part a different interface.
|
||||
*
|
||||
* GeometryFacade has private constructors and objects may only be created using the getFacade factory methods.
|
||||
* GeometryFacade has private constructors and objects may only be created using the getFacade
|
||||
* factory methods.
|
||||
*
|
||||
* There is a version of getFacade taking a const Part::Geometry and producing a const GeometryFacade, and a non-const
|
||||
* version producing a non-const GeometryFacade. So constness of the Part::Geometry object is preserved by the GeometryFacade
|
||||
* container.
|
||||
* There is a version of getFacade taking a const Part::Geometry and producing a const
|
||||
* GeometryFacade, and a non-const version producing a non-const GeometryFacade. So constness of the
|
||||
* Part::Geometry object is preserved by the GeometryFacade container.
|
||||
*
|
||||
* There are some static convenience utility functions to simplify common operations such as ID copy or to ensure that a geometry
|
||||
* object has the extension (creating the extension if not existing).
|
||||
* There are some static convenience utility functions to simplify common operations such as ID copy
|
||||
* or to ensure that a geometry object has the extension (creating the extension if not existing).
|
||||
*
|
||||
* @warning
|
||||
* The const factory method will throw if the geometry does not have a SketchGeometryExtension (being const, it commits not to
|
||||
* create one and modify the const Part::Geometry object). The non-const factory method will create the extension if not existing.
|
||||
* The const factory method will throw if the geometry does not have a SketchGeometryExtension
|
||||
* (being const, it commits not to create one and modify the const Part::Geometry object). The
|
||||
* non-const factory method will create the extension if not existing.
|
||||
*
|
||||
* @warning
|
||||
* If the Geometry Pointer fed into the factory method is a nullptr, a nullptr GeometryFacade is created. It should not be possible
|
||||
* to create a GeometryFacade having a Part::Geometry * being a nullptr.
|
||||
* If the Geometry Pointer fed into the factory method is a nullptr, a nullptr GeometryFacade is
|
||||
* created. It should not be possible to create a GeometryFacade having a Part::Geometry * being a
|
||||
* nullptr.
|
||||
*
|
||||
* A simple usage example:
|
||||
*
|
||||
@@ -86,43 +91,44 @@ class GeometryFacadePy;
|
||||
* GeometryFacade::setConstruction(copy, construction);
|
||||
* }
|
||||
*
|
||||
* Note: The standard GeometryFacade stores Part::Geometry derived classes as a Part::Geometry *, while
|
||||
* it has the ability to return a dynamic_cast-ed version to a provided type as follows:
|
||||
* Note: The standard GeometryFacade stores Part::Geometry derived classes as a Part::Geometry *,
|
||||
* while it has the ability to return a dynamic_cast-ed version to a provided type as follows:
|
||||
*
|
||||
* HLine->getGeometry<Part::GeomLineSegment>();
|
||||
*
|
||||
* If for seamless operation it is convenient to have a given derived class of Part::Geometry, it is possible
|
||||
* to use GeometryTypedFacade (see below).
|
||||
* If for seamless operation it is convenient to have a given derived class of Part::Geometry, it is
|
||||
* possible to use GeometryTypedFacade (see below).
|
||||
*
|
||||
* @remarks
|
||||
* Summary Remarks:
|
||||
* It is intended to have a separate type (not being a Geometry type).
|
||||
* it is intended to have the relevant interface in full for the sketcher extension only
|
||||
* It is intended to work on borrowed memory allocation. But the getFacade has an owner parameter to take ownership of the
|
||||
* geometry pointer if that is intended (this can also be achieved via the setOwner method once created).
|
||||
* It is intended to work on borrowed memory allocation. But the getFacade has an owner parameter to
|
||||
* take ownership of the geometry pointer if that is intended (this can also be achieved via the
|
||||
* setOwner method once created).
|
||||
*/
|
||||
class SketcherExport GeometryFacade : public Base::BaseClass, private ISketchGeometryExtension
|
||||
class SketcherExport GeometryFacade: public Base::BaseClass, private ISketchGeometryExtension
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
protected:
|
||||
explicit GeometryFacade(const Part::Geometry * geometry, bool owner = false);
|
||||
GeometryFacade(); // As TYPESYSTEM requirement
|
||||
explicit GeometryFacade(const Part::Geometry* geometry, bool owner = false);
|
||||
GeometryFacade();// As TYPESYSTEM requirement
|
||||
|
||||
friend class GeometryFacadePy;
|
||||
|
||||
public: // Factory methods
|
||||
static std::unique_ptr<GeometryFacade> getFacade(Part::Geometry * geometry, bool owner = false);
|
||||
static std::unique_ptr<const GeometryFacade> getFacade(const Part::Geometry * geometry);
|
||||
public:// Factory methods
|
||||
static std::unique_ptr<GeometryFacade> getFacade(Part::Geometry* geometry, bool owner = false);
|
||||
static std::unique_ptr<const GeometryFacade> getFacade(const Part::Geometry* geometry);
|
||||
|
||||
public: // Utility methods
|
||||
static void ensureSketchGeometryExtension(Part::Geometry * geometry);
|
||||
static void copyId(const Part::Geometry * src, Part::Geometry * dst);
|
||||
static bool getConstruction(const Part::Geometry * geometry);
|
||||
static void setConstruction(Part::Geometry * geometry, bool construction);
|
||||
static bool isInternalType(const Part::Geometry * geometry, InternalType::InternalType type);
|
||||
public:// Utility methods
|
||||
static void ensureSketchGeometryExtension(Part::Geometry* geometry);
|
||||
static void copyId(const Part::Geometry* src, Part::Geometry* dst);
|
||||
static bool getConstruction(const Part::Geometry* geometry);
|
||||
static void setConstruction(Part::Geometry* geometry, bool construction);
|
||||
static bool isInternalType(const Part::Geometry* geometry, InternalType::InternalType type);
|
||||
static bool isInternalAligned(const Part::Geometry* geometry);
|
||||
static bool getBlocked(const Part::Geometry * geometry);
|
||||
static bool getBlocked(const Part::Geometry* geometry);
|
||||
|
||||
public:
|
||||
// Explicit deletion to show intent (not that it is needed)
|
||||
@@ -133,108 +139,228 @@ public:
|
||||
GeometryFacade& operator=(GeometryFacade&&) = default;
|
||||
|
||||
~GeometryFacade() override;
|
||||
void setGeometry(Part::Geometry *geometry);
|
||||
void setGeometry(Part::Geometry* geometry);
|
||||
|
||||
void setOwner(bool owner) {
|
||||
void setOwner(bool owner)
|
||||
{
|
||||
OwnerGeo = owner;
|
||||
}
|
||||
|
||||
// returns if the facade is the owner of the geometry pointer.
|
||||
bool getOwner() const {
|
||||
bool getOwner() const
|
||||
{
|
||||
return OwnerGeo;
|
||||
}
|
||||
|
||||
// Geometry Extension Interface
|
||||
inline long getId() const override {return getGeoExt()->getId();}
|
||||
void setId(long id) override {getGeoExt()->setId(id);}
|
||||
inline long getId() const override
|
||||
{
|
||||
return getGeoExt()->getId();
|
||||
}
|
||||
void setId(long id) override
|
||||
{
|
||||
getGeoExt()->setId(id);
|
||||
}
|
||||
|
||||
InternalType::InternalType getInternalType() const override {return getGeoExt()->getInternalType();}
|
||||
void setInternalType(InternalType::InternalType type) override {getGeoExt()->setInternalType(type);}
|
||||
InternalType::InternalType getInternalType() const override
|
||||
{
|
||||
return getGeoExt()->getInternalType();
|
||||
}
|
||||
void setInternalType(InternalType::InternalType type) override
|
||||
{
|
||||
getGeoExt()->setInternalType(type);
|
||||
}
|
||||
|
||||
bool testGeometryMode(int flag) const override { return getGeoExt()->testGeometryMode(flag); }
|
||||
void setGeometryMode(int flag, bool v=true) override { getGeoExt()->setGeometryMode(flag, v); }
|
||||
bool testGeometryMode(int flag) const override
|
||||
{
|
||||
return getGeoExt()->testGeometryMode(flag);
|
||||
}
|
||||
void setGeometryMode(int flag, bool v = true) override
|
||||
{
|
||||
getGeoExt()->setGeometryMode(flag, v);
|
||||
}
|
||||
|
||||
int getGeometryLayerId() const override { return getGeoExt()->getGeometryLayerId();}
|
||||
void setGeometryLayerId(int geolayer) override { getGeoExt()->setGeometryLayerId(geolayer);}
|
||||
int getGeometryLayerId() const override
|
||||
{
|
||||
return getGeoExt()->getGeometryLayerId();
|
||||
}
|
||||
void setGeometryLayerId(int geolayer) override
|
||||
{
|
||||
getGeoExt()->setGeometryLayerId(geolayer);
|
||||
}
|
||||
|
||||
// Convenience accessor
|
||||
bool getBlocked() const { return this->testGeometryMode(GeometryMode::Blocked);}
|
||||
void setBlocked(bool status = true) {this->setGeometryMode(GeometryMode::Blocked, status);}
|
||||
bool getBlocked() const
|
||||
{
|
||||
return this->testGeometryMode(GeometryMode::Blocked);
|
||||
}
|
||||
void setBlocked(bool status = true)
|
||||
{
|
||||
this->setGeometryMode(GeometryMode::Blocked, status);
|
||||
}
|
||||
|
||||
inline bool getConstruction() const {return this->testGeometryMode(GeometryMode::Construction);}
|
||||
inline void setConstruction(bool construction) {this->setGeometryMode(GeometryMode::Construction, construction);}
|
||||
inline bool getConstruction() const
|
||||
{
|
||||
return this->testGeometryMode(GeometryMode::Construction);
|
||||
}
|
||||
inline void setConstruction(bool construction)
|
||||
{
|
||||
this->setGeometryMode(GeometryMode::Construction, construction);
|
||||
}
|
||||
|
||||
bool isInternalAligned() const { return this->getInternalType() != InternalType::None; }
|
||||
bool isInternalAligned() const
|
||||
{
|
||||
return this->getInternalType() != InternalType::None;
|
||||
}
|
||||
|
||||
bool isInternalType(InternalType::InternalType type) const { return this->getInternalType() == type; }
|
||||
bool isInternalType(InternalType::InternalType type) const
|
||||
{
|
||||
return this->getInternalType() == type;
|
||||
}
|
||||
|
||||
// Geometry Extension Information
|
||||
inline const std::string &getExtensionName () const {return SketchGeoExtension->getName();}
|
||||
inline const std::string& getExtensionName() const
|
||||
{
|
||||
return SketchGeoExtension->getName();
|
||||
}
|
||||
|
||||
// Geometry Element
|
||||
template < typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<
|
||||
std::is_base_of<Part::Geometry, typename std::decay<GeometryT>::type>::value
|
||||
>::type
|
||||
>
|
||||
GeometryT * getGeometry() {return dynamic_cast<GeometryT *>(const_cast<Part::Geometry *>(Geo));}
|
||||
template<typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<std::is_base_of<
|
||||
Part::Geometry, typename std::decay<GeometryT>::type>::value>::type>
|
||||
GeometryT* getGeometry()
|
||||
{
|
||||
return dynamic_cast<GeometryT*>(const_cast<Part::Geometry*>(Geo));
|
||||
}
|
||||
|
||||
// Geometry Element
|
||||
template < typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<
|
||||
std::is_base_of<Part::Geometry, typename std::decay<GeometryT>::type>::value
|
||||
>::type
|
||||
>
|
||||
const GeometryT * getGeometry() const {return dynamic_cast<const GeometryT *>(Geo);}
|
||||
template<typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<std::is_base_of<
|
||||
Part::Geometry, typename std::decay<GeometryT>::type>::value>::type>
|
||||
const GeometryT* getGeometry() const
|
||||
{
|
||||
return dynamic_cast<const GeometryT*>(Geo);
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
// Geometry Interface
|
||||
TopoDS_Shape toShape() const {return getGeo()->toShape();}
|
||||
const Handle(Geom_Geometry)& handle() const {return getGeo()->handle();}
|
||||
Part::Geometry *copy() const {return getGeo()->copy();}
|
||||
Part::Geometry *clone() const {return getGeo()->clone();}
|
||||
boost::uuids::uuid getTag() const {return getGeo()->getTag();}
|
||||
TopoDS_Shape toShape() const
|
||||
{
|
||||
return getGeo()->toShape();
|
||||
}
|
||||
const Handle(Geom_Geometry) & handle() const
|
||||
{
|
||||
return getGeo()->handle();
|
||||
}
|
||||
Part::Geometry* copy() const
|
||||
{
|
||||
return getGeo()->copy();
|
||||
}
|
||||
Part::Geometry* clone() const
|
||||
{
|
||||
return getGeo()->clone();
|
||||
}
|
||||
boost::uuids::uuid getTag() const
|
||||
{
|
||||
return getGeo()->getTag();
|
||||
}
|
||||
|
||||
std::vector<std::weak_ptr<const Part::GeometryExtension>> getExtensions() const {return getGeo()->getExtensions();}
|
||||
bool hasExtension(const Base::Type & type) const {return getGeo()->hasExtension(type);}
|
||||
bool hasExtension(const std::string & name) const {return getGeo()->hasExtension(name);}
|
||||
std::weak_ptr<const Part::GeometryExtension> getExtension(const Base::Type & type) const {return getGeo()->getExtension(type);}
|
||||
std::weak_ptr<const Part::GeometryExtension> getExtension(const std::string & name) const {return getGeo()->getExtension(name);}
|
||||
void setExtension(std::unique_ptr<Part::GeometryExtension> &&geo) {return getGeo()->setExtension(std::move(geo));}
|
||||
void deleteExtension(const Base::Type & type) {return getGeo()->deleteExtension(type);}
|
||||
void deleteExtension(const std::string & name) {return getGeo()->deleteExtension(name);}
|
||||
std::vector<std::weak_ptr<const Part::GeometryExtension>> getExtensions() const
|
||||
{
|
||||
return getGeo()->getExtensions();
|
||||
}
|
||||
bool hasExtension(const Base::Type& type) const
|
||||
{
|
||||
return getGeo()->hasExtension(type);
|
||||
}
|
||||
bool hasExtension(const std::string& name) const
|
||||
{
|
||||
return getGeo()->hasExtension(name);
|
||||
}
|
||||
std::weak_ptr<const Part::GeometryExtension> getExtension(const Base::Type& type) const
|
||||
{
|
||||
return getGeo()->getExtension(type);
|
||||
}
|
||||
std::weak_ptr<const Part::GeometryExtension> getExtension(const std::string& name) const
|
||||
{
|
||||
return getGeo()->getExtension(name);
|
||||
}
|
||||
void setExtension(std::unique_ptr<Part::GeometryExtension>&& geo)
|
||||
{
|
||||
return getGeo()->setExtension(std::move(geo));
|
||||
}
|
||||
void deleteExtension(const Base::Type& type)
|
||||
{
|
||||
return getGeo()->deleteExtension(type);
|
||||
}
|
||||
void deleteExtension(const std::string& name)
|
||||
{
|
||||
return getGeo()->deleteExtension(name);
|
||||
}
|
||||
|
||||
void mirror(const Base::Vector3d & point) {return getGeo()->mirror(point);}
|
||||
void mirror(const Base::Vector3d & point, Base::Vector3d dir) {return getGeo()->mirror(point, dir);}
|
||||
void rotate(const Base::Placement & plm) {return getGeo()->rotate(plm);}
|
||||
void scale(const Base::Vector3d & vec, double scale) {return getGeo()->scale(vec, scale);}
|
||||
void transform(const Base::Matrix4D & mat) {return getGeo()->transform(mat);}
|
||||
void translate(const Base::Vector3d & vec) {return getGeo()->translate(vec);}
|
||||
void mirror(const Base::Vector3d& point)
|
||||
{
|
||||
return getGeo()->mirror(point);
|
||||
}
|
||||
void mirror(const Base::Vector3d& point, Base::Vector3d dir)
|
||||
{
|
||||
return getGeo()->mirror(point, dir);
|
||||
}
|
||||
void rotate(const Base::Placement& plm)
|
||||
{
|
||||
return getGeo()->rotate(plm);
|
||||
}
|
||||
void scale(const Base::Vector3d& vec, double scale)
|
||||
{
|
||||
return getGeo()->scale(vec, scale);
|
||||
}
|
||||
void transform(const Base::Matrix4D& mat)
|
||||
{
|
||||
return getGeo()->transform(mat);
|
||||
}
|
||||
void translate(const Base::Vector3d& vec)
|
||||
{
|
||||
return getGeo()->translate(vec);
|
||||
}
|
||||
|
||||
// convenience GeometryFunctions
|
||||
bool isGeoType(const Base::Type &type) const { return getGeo()->getTypeId() == type;}
|
||||
bool isGeoType(const Base::Type& type) const
|
||||
{
|
||||
return getGeo()->getTypeId() == type;
|
||||
}
|
||||
|
||||
private:
|
||||
void initExtension();
|
||||
void initExtension() const;
|
||||
|
||||
const Part::Geometry * getGeo() const {return Geo;}
|
||||
Part::Geometry * getGeo() {return const_cast<Part::Geometry *>(Geo);}
|
||||
const Part::Geometry* getGeo() const
|
||||
{
|
||||
return Geo;
|
||||
}
|
||||
Part::Geometry* getGeo()
|
||||
{
|
||||
return const_cast<Part::Geometry*>(Geo);
|
||||
}
|
||||
|
||||
std::shared_ptr<const SketchGeometryExtension> getGeoExt() const {return SketchGeoExtension;}
|
||||
std::shared_ptr<SketchGeometryExtension> getGeoExt () {return std::const_pointer_cast<SketchGeometryExtension>(SketchGeoExtension);}
|
||||
std::shared_ptr<const SketchGeometryExtension> getGeoExt() const
|
||||
{
|
||||
return SketchGeoExtension;
|
||||
}
|
||||
std::shared_ptr<SketchGeometryExtension> getGeoExt()
|
||||
{
|
||||
return std::const_pointer_cast<SketchGeometryExtension>(SketchGeoExtension);
|
||||
}
|
||||
|
||||
static void throwOnNullPtr(const Part::Geometry * geo);
|
||||
static void throwOnNullPtr(const Part::Geometry* geo);
|
||||
|
||||
private:
|
||||
const Part::Geometry * Geo;
|
||||
const Part::Geometry* Geo;
|
||||
bool OwnerGeo;
|
||||
std::shared_ptr<const SketchGeometryExtension> SketchGeoExtension;
|
||||
};
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GeometryTypedFacade
|
||||
@@ -251,8 +377,8 @@ private:
|
||||
* HLine->getTypedGeometry()->setPoints(Base::Vector3d(0,0,0),Base::Vector3d(1,0,0));
|
||||
*
|
||||
* If a facade is requested without passing an Part::Geometry derived object, the constructor
|
||||
* of the indicated geometry type is called with any parameter passed as argument (emplace style). In
|
||||
* this case the facade takes ownership of the newly created Part::Geometry object.
|
||||
* of the indicated geometry type is called with any parameter passed as argument (emplace style).
|
||||
* In this case the facade takes ownership of the newly created Part::Geometry object.
|
||||
*
|
||||
* Example of seamless operation with a GeomLineSegment:
|
||||
*
|
||||
@@ -261,27 +387,39 @@ private:
|
||||
* HLine->setConstruction(true);
|
||||
* ExternalGeo.push_back(HLine->getGeometry());
|
||||
*/
|
||||
template < typename GeometryT >
|
||||
class SketcherExport GeometryTypedFacade : public GeometryFacade
|
||||
template<typename GeometryT>
|
||||
class SketcherExport GeometryTypedFacade: public GeometryFacade
|
||||
{
|
||||
static_assert( std::is_base_of<Part::Geometry, typename std::decay<GeometryT>::type>::value &&
|
||||
!std::is_same<Part::Geometry, typename std::decay<GeometryT>::type>::value, "Only for classes derived from Geometry!");
|
||||
private:
|
||||
explicit GeometryTypedFacade(const Part::Geometry * geometry, bool owner = false):GeometryFacade(geometry, owner) {}
|
||||
GeometryTypedFacade():GeometryFacade() {}
|
||||
static_assert(std::is_base_of<Part::Geometry, typename std::decay<GeometryT>::type>::value
|
||||
&& !std::is_same<Part::Geometry, typename std::decay<GeometryT>::type>::value,
|
||||
"Only for classes derived from Geometry!");
|
||||
|
||||
public: // Factory methods
|
||||
static std::unique_ptr<GeometryTypedFacade<GeometryT>> getTypedFacade(GeometryT * geometry, bool owner = false) {
|
||||
if(geometry) {
|
||||
return std::unique_ptr<GeometryTypedFacade<GeometryT>>(new GeometryTypedFacade(geometry, owner));
|
||||
private:
|
||||
explicit GeometryTypedFacade(const Part::Geometry* geometry, bool owner = false)
|
||||
: GeometryFacade(geometry, owner)
|
||||
{}
|
||||
GeometryTypedFacade()
|
||||
: GeometryFacade()
|
||||
{}
|
||||
|
||||
public:// Factory methods
|
||||
static std::unique_ptr<GeometryTypedFacade<GeometryT>> getTypedFacade(GeometryT* geometry,
|
||||
bool owner = false)
|
||||
{
|
||||
if (geometry) {
|
||||
return std::unique_ptr<GeometryTypedFacade<GeometryT>>(
|
||||
new GeometryTypedFacade(geometry, owner));
|
||||
}
|
||||
else {
|
||||
return std::unique_ptr<GeometryTypedFacade<GeometryT>>(nullptr);
|
||||
}
|
||||
}
|
||||
static std::unique_ptr<const GeometryTypedFacade<GeometryT>> getTypedFacade(const GeometryT * geometry) {
|
||||
if(geometry) {
|
||||
return std::unique_ptr<const GeometryTypedFacade<GeometryT>>(new GeometryTypedFacade(geometry));
|
||||
static std::unique_ptr<const GeometryTypedFacade<GeometryT>>
|
||||
getTypedFacade(const GeometryT* geometry)
|
||||
{
|
||||
if (geometry) {
|
||||
return std::unique_ptr<const GeometryTypedFacade<GeometryT>>(
|
||||
new GeometryTypedFacade(geometry));
|
||||
}
|
||||
else {
|
||||
return std::unique_ptr<const GeometryTypedFacade<GeometryT>>(nullptr);
|
||||
@@ -289,23 +427,28 @@ public: // Factory methods
|
||||
}
|
||||
|
||||
// This function takes direct ownership of the object it creates.
|
||||
template < typename... Args >
|
||||
static std::unique_ptr<GeometryTypedFacade<GeometryT>> getTypedFacade(Args&&... args) {
|
||||
return GeometryTypedFacade::getTypedFacade(new GeometryT(std::forward<Args>(args)...), true);
|
||||
template<typename... Args>
|
||||
static std::unique_ptr<GeometryTypedFacade<GeometryT>> getTypedFacade(Args&&... args)
|
||||
{
|
||||
return GeometryTypedFacade::getTypedFacade(new GeometryT(std::forward<Args>(args)...),
|
||||
true);
|
||||
}
|
||||
|
||||
// Geometry Element
|
||||
GeometryT * getTypedGeometry() {return GeometryFacade::getGeometry<GeometryT>();}
|
||||
GeometryT* getTypedGeometry()
|
||||
{
|
||||
return GeometryFacade::getGeometry<GeometryT>();
|
||||
}
|
||||
|
||||
// Geometry Element
|
||||
GeometryT * getTypedGeometry() const {return GeometryFacade::getGeometry<GeometryT>();}
|
||||
GeometryT* getTypedGeometry() const
|
||||
{
|
||||
return GeometryFacade::getGeometry<GeometryT>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
|
||||
} //namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCHER_GEOMETRYFACADE_H
|
||||
#endif// SKETCHER_GEOMETRYFACADE_H
|
||||
|
||||
@@ -24,14 +24,15 @@
|
||||
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
#include <Base/MatrixPy.h>
|
||||
#include <Base/PlacementPy.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Base/VectorPy.h>
|
||||
#include <Base/PlacementPy.h>
|
||||
#include <Mod/Part/App/GeometryExtensionPy.h>
|
||||
#include <Mod/Part/App/GeometryPy.h>
|
||||
#include <Mod/Part/App/OCCError.h>
|
||||
|
||||
#include "GeometryFacadePy.h"
|
||||
|
||||
#include "GeometryFacadePy.cpp"
|
||||
|
||||
|
||||
@@ -47,7 +48,7 @@ std::string GeometryFacadePy::representation() const
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *GeometryFacadePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
PyObject* GeometryFacadePy::PyMake(struct _typeobject*, PyObject*, PyObject*)// Python wrapper
|
||||
{
|
||||
// create a new instance of PointPy and the Twin object
|
||||
return new GeometryFacadePy(new GeometryFacade());
|
||||
@@ -56,18 +57,18 @@ PyObject *GeometryFacadePy::PyMake(struct _typeobject *, PyObject *, PyObject *)
|
||||
// constructor method
|
||||
int GeometryFacadePy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
{
|
||||
PyObject *object;
|
||||
if (PyArg_ParseTuple(args,"O!",&(Part::GeometryPy::Type), &object)) {
|
||||
Part::Geometry * geo = static_cast<Part::GeometryPy *>(object)->getGeometryPtr();
|
||||
PyObject* object;
|
||||
if (PyArg_ParseTuple(args, "O!", &(Part::GeometryPy::Type), &object)) {
|
||||
Part::Geometry* geo = static_cast<Part::GeometryPy*>(object)->getGeometryPtr();
|
||||
|
||||
getGeometryFacadePtr()->setGeometry(geo->clone());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Sketcher::GeometryFacade constructor accepts:\n"
|
||||
"-- Part.Geometry\n"
|
||||
);
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Sketcher::GeometryFacade constructor accepts:\n"
|
||||
"-- Part.Geometry\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -85,12 +86,12 @@ Py::String GeometryFacadePy::getInternalType() const
|
||||
{
|
||||
int internaltypeindex = (int)this->getGeometryFacadePtr()->getInternalType();
|
||||
|
||||
if(internaltypeindex >= InternalType::NumInternalGeometryType)
|
||||
if (internaltypeindex >= InternalType::NumInternalGeometryType)
|
||||
throw Py::NotImplementedError("String name of enum not implemented");
|
||||
|
||||
std::string typestr = SketchGeometryExtension::internaltype2str[internaltypeindex];
|
||||
|
||||
return Py::String(typestr);
|
||||
return Py::String(typestr);
|
||||
}
|
||||
|
||||
void GeometryFacadePy::setInternalType(Py::String arg)
|
||||
@@ -98,7 +99,7 @@ void GeometryFacadePy::setInternalType(Py::String arg)
|
||||
std::string argstr = arg;
|
||||
InternalType::InternalType type;
|
||||
|
||||
if(SketchGeometryExtension::getInternalTypeFromName(argstr, type)) {
|
||||
if (SketchGeometryExtension::getInternalTypeFromName(argstr, type)) {
|
||||
this->getGeometryFacadePtr()->setInternalType(type);
|
||||
return;
|
||||
}
|
||||
@@ -116,14 +117,14 @@ void GeometryFacadePy::setBlocked(Py::Boolean arg)
|
||||
getGeometryFacadePtr()->setBlocked(arg);
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::testGeometryMode(PyObject *args)
|
||||
PyObject* GeometryFacadePy::testGeometryMode(PyObject* args)
|
||||
{
|
||||
char* flag;
|
||||
if (PyArg_ParseTuple(args, "s",&flag)) {
|
||||
if (PyArg_ParseTuple(args, "s", &flag)) {
|
||||
|
||||
GeometryMode::GeometryMode mode;
|
||||
|
||||
if(SketchGeometryExtension::getGeometryModeFromName(flag, mode))
|
||||
if (SketchGeometryExtension::getGeometryModeFromName(flag, mode))
|
||||
return new_reference_to(Py::Boolean(getGeometryFacadePtr()->testGeometryMode(mode)));
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Flag string does not exist.");
|
||||
@@ -134,15 +135,15 @@ PyObject* GeometryFacadePy::testGeometryMode(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::setGeometryMode(PyObject *args)
|
||||
PyObject* GeometryFacadePy::setGeometryMode(PyObject* args)
|
||||
{
|
||||
char * flag;
|
||||
PyObject * bflag = Py_True;
|
||||
char* flag;
|
||||
PyObject* bflag = Py_True;
|
||||
if (PyArg_ParseTuple(args, "s|O!", &flag, &PyBool_Type, &bflag)) {
|
||||
|
||||
GeometryMode::GeometryMode mode;
|
||||
|
||||
if(SketchGeometryExtension::getGeometryModeFromName(flag, mode)) {
|
||||
if (SketchGeometryExtension::getGeometryModeFromName(flag, mode)) {
|
||||
getGeometryFacadePtr()->setGeometryMode(mode, Base::asBoolean(bflag));
|
||||
Py_Return;
|
||||
}
|
||||
@@ -156,10 +157,10 @@ PyObject* GeometryFacadePy::setGeometryMode(PyObject *args)
|
||||
}
|
||||
|
||||
|
||||
PyObject* GeometryFacadePy::mirror(PyObject *args)
|
||||
PyObject* GeometryFacadePy::mirror(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type),&o)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &o)) {
|
||||
Base::Vector3d vec = static_cast<Base::VectorPy*>(o)->value();
|
||||
getGeometryFacadePtr()->mirror(vec);
|
||||
Py_Return;
|
||||
@@ -167,22 +168,23 @@ PyObject* GeometryFacadePy::mirror(PyObject *args)
|
||||
|
||||
PyErr_Clear();
|
||||
PyObject* axis;
|
||||
if (PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type),&o,
|
||||
&(Base::VectorPy::Type),&axis)) {
|
||||
if (PyArg_ParseTuple(
|
||||
args, "O!O!", &(Base::VectorPy::Type), &o, &(Base::VectorPy::Type), &axis)) {
|
||||
Base::Vector3d pnt = static_cast<Base::VectorPy*>(o)->value();
|
||||
Base::Vector3d dir = static_cast<Base::VectorPy*>(axis)->value();
|
||||
getGeometryFacadePtr()->mirror(pnt, dir);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "either a point (vector) or axis (vector, vector) must be given");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"either a point (vector) or axis (vector, vector) must be given");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::rotate(PyObject *args)
|
||||
PyObject* GeometryFacadePy::rotate(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type),&o))
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &o))
|
||||
return nullptr;
|
||||
|
||||
Base::Placement* plm = static_cast<Base::PlacementPy*>(o)->getPlacementPtr();
|
||||
@@ -190,19 +192,19 @@ PyObject* GeometryFacadePy::rotate(PyObject *args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::scale(PyObject *args)
|
||||
PyObject* GeometryFacadePy::scale(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
double scale;
|
||||
Base::Vector3d vec;
|
||||
if (PyArg_ParseTuple(args, "O!d", &(Base::VectorPy::Type),&o, &scale)) {
|
||||
if (PyArg_ParseTuple(args, "O!d", &(Base::VectorPy::Type), &o, &scale)) {
|
||||
vec = static_cast<Base::VectorPy*>(o)->value();
|
||||
getGeometryFacadePtr()->scale(vec, scale);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O!d", &PyTuple_Type,&o, &scale)) {
|
||||
if (PyArg_ParseTuple(args, "O!d", &PyTuple_Type, &o, &scale)) {
|
||||
vec = Base::getVectorFromTuple<double>(o);
|
||||
getGeometryFacadePtr()->scale(vec, scale);
|
||||
Py_Return;
|
||||
@@ -212,28 +214,28 @@ PyObject* GeometryFacadePy::scale(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::transform(PyObject *args)
|
||||
PyObject* GeometryFacadePy::transform(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type),&o))
|
||||
if (!PyArg_ParseTuple(args, "O!", &(Base::MatrixPy::Type), &o))
|
||||
return nullptr;
|
||||
Base::Matrix4D mat = static_cast<Base::MatrixPy*>(o)->value();
|
||||
getGeometryFacadePtr()->transform(mat);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::translate(PyObject *args)
|
||||
PyObject* GeometryFacadePy::translate(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
Base::Vector3d vec;
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type),&o)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &o)) {
|
||||
vec = static_cast<Base::VectorPy*>(o)->value();
|
||||
getGeometryFacadePtr()->translate(vec);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O!", &PyTuple_Type,&o)) {
|
||||
if (PyArg_ParseTuple(args, "O!", &PyTuple_Type, &o)) {
|
||||
vec = Base::getVectorFromTuple<double>(o);
|
||||
getGeometryFacadePtr()->translate(vec);
|
||||
Py_Return;
|
||||
@@ -243,12 +245,12 @@ PyObject* GeometryFacadePy::translate(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::setExtension(PyObject *args)
|
||||
PyObject* GeometryFacadePy::setExtension(PyObject* args)
|
||||
{
|
||||
PyObject* o;
|
||||
if (PyArg_ParseTuple(args, "O!", &(Part::GeometryExtensionPy::Type),&o)) {
|
||||
Part::GeometryExtension * ext;
|
||||
ext = static_cast<Part::GeometryExtensionPy *>(o)->getGeometryExtensionPtr();
|
||||
if (PyArg_ParseTuple(args, "O!", &(Part::GeometryExtensionPy::Type), &o)) {
|
||||
Part::GeometryExtension* ext;
|
||||
ext = static_cast<Part::GeometryExtensionPy*>(o)->getGeometryExtensionPtr();
|
||||
|
||||
// make copy of Python managed memory and wrap it in smart pointer
|
||||
auto cpy = ext->copy();
|
||||
@@ -261,153 +263,159 @@ PyObject* GeometryFacadePy::setExtension(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::getExtensionOfType(PyObject *args)
|
||||
PyObject* GeometryFacadePy::getExtensionOfType(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
|
||||
Base::Type type = Base::Type::fromName(o);
|
||||
|
||||
if(type != Base::Type::badType()) {
|
||||
if (type != Base::Type::badType()) {
|
||||
try {
|
||||
std::shared_ptr<const Part::GeometryExtension> ext(this->getGeometryFacadePtr()->getExtension(type));
|
||||
std::shared_ptr<const Part::GeometryExtension> ext(
|
||||
this->getGeometryFacadePtr()->getExtension(type));
|
||||
|
||||
// we create a copy and transfer this copy's memory management responsibility to Python
|
||||
// we create a copy and transfer this copy's memory management responsibility to
|
||||
// Python
|
||||
PyObject* cpy = ext->copyPyObject();
|
||||
return cpy;
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
catch(const std::bad_weak_ptr&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not exist anymore.");
|
||||
catch (const std::bad_weak_ptr&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"Geometry extension does not exist anymore.");
|
||||
return nullptr;
|
||||
}
|
||||
catch(Base::NotImplementedError&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not implement a Python counterpart.");
|
||||
catch (Base::NotImplementedError&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"Geometry extension does not implement a Python counterpart.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Exception type does not exist");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with the name of the geometry extension type was expected");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"A string with the name of the geometry extension type was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::getExtensionOfName(PyObject *args)
|
||||
PyObject* GeometryFacadePy::getExtensionOfName(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
|
||||
try {
|
||||
std::shared_ptr<const Part::GeometryExtension> ext(this->getGeometryFacadePtr()->getExtension(std::string(o)));
|
||||
std::shared_ptr<const Part::GeometryExtension> ext(
|
||||
this->getGeometryFacadePtr()->getExtension(std::string(o)));
|
||||
|
||||
// we create a copy and transfer this copy's memory management responsibility to Python
|
||||
PyObject* cpy = ext->copyPyObject();
|
||||
return cpy;
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
catch(const std::bad_weak_ptr&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not exist anymore.");
|
||||
catch (const std::bad_weak_ptr&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"Geometry extension does not exist anymore.");
|
||||
return nullptr;
|
||||
}
|
||||
catch(Base::NotImplementedError&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not implement a Python counterpart.");
|
||||
catch (Base::NotImplementedError&) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"Geometry extension does not implement a Python counterpart.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with the name of the geometry extension was expected");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"A string with the name of the geometry extension was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::hasExtensionOfType(PyObject *args)
|
||||
PyObject* GeometryFacadePy::hasExtensionOfType(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
|
||||
Base::Type type = Base::Type::fromName(o);
|
||||
|
||||
if(type != Base::Type::badType()) {
|
||||
if (type != Base::Type::badType()) {
|
||||
try {
|
||||
return Py::new_reference_to(Py::Boolean(this->getGeometryFacadePtr()->hasExtension(type)));
|
||||
return Py::new_reference_to(
|
||||
Py::Boolean(this->getGeometryFacadePtr()->hasExtension(type)));
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Exception type does not exist");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with the type of the geometry extension was expected");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"A string with the type of the geometry extension was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::hasExtensionOfName(PyObject *args)
|
||||
PyObject* GeometryFacadePy::hasExtensionOfName(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
|
||||
try {
|
||||
return Py::new_reference_to(Py::Boolean(this->getGeometryFacadePtr()->hasExtension(std::string(o))));
|
||||
return Py::new_reference_to(
|
||||
Py::Boolean(this->getGeometryFacadePtr()->hasExtension(std::string(o))));
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with the type of the geometry extension was expected");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"A string with the type of the geometry extension was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::deleteExtensionOfType(PyObject *args)
|
||||
PyObject* GeometryFacadePy::deleteExtensionOfType(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
|
||||
Base::Type type = Base::Type::fromName(o);
|
||||
|
||||
if(type != Base::Type::badType()) {
|
||||
if (type != Base::Type::badType()) {
|
||||
try {
|
||||
this->getGeometryFacadePtr()->deleteExtension(type);
|
||||
Py_Return;
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "Type does not exist");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with a type object was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::deleteExtensionOfName(PyObject *args)
|
||||
PyObject* GeometryFacadePy::deleteExtensionOfName(PyObject* args)
|
||||
{
|
||||
char* o;
|
||||
if (PyArg_ParseTuple(args, "s", &o)) {
|
||||
@@ -416,38 +424,40 @@ PyObject* GeometryFacadePy::deleteExtensionOfName(PyObject *args)
|
||||
this->getGeometryFacadePtr()->deleteExtension(std::string(o));
|
||||
Py_Return;
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "A string with the name of the extension was expected");
|
||||
PyErr_SetString(Part::PartExceptionOCCError,
|
||||
"A string with the name of the extension was expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* GeometryFacadePy::getExtensions(PyObject *args)
|
||||
PyObject* GeometryFacadePy::getExtensions(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, "")){
|
||||
if (!PyArg_ParseTuple(args, "")) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, "No arguments were expected");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
const std::vector<std::weak_ptr<const Part::GeometryExtension>> ext = this->getGeometryFacadePtr()->getExtensions();
|
||||
const std::vector<std::weak_ptr<const Part::GeometryExtension>> ext =
|
||||
this->getGeometryFacadePtr()->getExtensions();
|
||||
|
||||
Py::List list;
|
||||
|
||||
for (std::size_t i=0; i<ext.size(); ++i) {
|
||||
for (std::size_t i = 0; i < ext.size(); ++i) {
|
||||
|
||||
std::shared_ptr<const Part::GeometryExtension> p = ext[i].lock();
|
||||
|
||||
if(p) {
|
||||
if (p) {
|
||||
// we create a python copy and add it to the list
|
||||
try {
|
||||
list.append(Py::asObject(p->copyPyObject()));
|
||||
}
|
||||
catch(Base::NotImplementedError&) {
|
||||
catch (Base::NotImplementedError&) {
|
||||
// silently ignoring extensions not having a Python object
|
||||
}
|
||||
}
|
||||
@@ -455,11 +465,10 @@ PyObject* GeometryFacadePy::getExtensions(PyObject *args)
|
||||
|
||||
return Py::new_reference_to(list);
|
||||
}
|
||||
catch(const Base::ValueError& e) {
|
||||
catch (const Base::ValueError& e) {
|
||||
PyErr_SetString(Part::PartExceptionOCCError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Py::Boolean GeometryFacadePy::getConstruction() const
|
||||
@@ -467,7 +476,7 @@ Py::Boolean GeometryFacadePy::getConstruction() const
|
||||
return Py::Boolean(getGeometryFacadePtr()->getConstruction());
|
||||
}
|
||||
|
||||
void GeometryFacadePy::setConstruction(Py::Boolean arg)
|
||||
void GeometryFacadePy::setConstruction(Py::Boolean arg)
|
||||
{
|
||||
getGeometryFacadePtr()->setConstruction(arg);
|
||||
}
|
||||
@@ -495,17 +504,17 @@ Py::Object GeometryFacadePy::getGeometry() const
|
||||
return Py::Object(geo->getPyObject(), true);
|
||||
}
|
||||
|
||||
void GeometryFacadePy::setGeometry(Py::Object arg)
|
||||
void GeometryFacadePy::setGeometry(Py::Object arg)
|
||||
{
|
||||
if (PyObject_TypeCheck(arg.ptr(), &(Part::GeometryPy::Type))) {
|
||||
Part::GeometryPy * gp = static_cast<Part::GeometryPy *>(arg.ptr());
|
||||
Part::GeometryPy* gp = static_cast<Part::GeometryPy*>(arg.ptr());
|
||||
|
||||
getGeometryFacadePtr()->setGeometry(gp->getGeometryPtr()->clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyObject *GeometryFacadePy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* GeometryFacadePy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#include "PreCompiled.h"
|
||||
|
||||
@@ -43,15 +43,17 @@
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
// OpenCasCade
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <BRepOffsetAPI_NormalProjection.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <GC_MakeCircle.hxx>
|
||||
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_Circle.hxx>
|
||||
#include <Geom_Ellipse.hxx>
|
||||
@@ -60,8 +62,19 @@
|
||||
#include <Geom_Parabola.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <Geom_TrimmedCurve.hxx>
|
||||
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <Standard_Version.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Circ.hxx>
|
||||
#include <gp_Elips.hxx>
|
||||
@@ -69,25 +82,12 @@
|
||||
#include <gp_Parab.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <Standard_Version.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
|
||||
#elif defined(FC_OS_WIN32)
|
||||
#ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
# include <windows.h>
|
||||
#endif // _PreComp_
|
||||
#include <windows.h>
|
||||
#endif// _PreComp_
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,18 +22,18 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <cassert>
|
||||
#include <cassert>
|
||||
#endif
|
||||
|
||||
#include <App/ExpressionParser.h>
|
||||
#include <App/ObjectIdentifier.h>
|
||||
#include <Base/QuantityPy.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Writer.h>
|
||||
|
||||
#include "PropertyConstraintList.h"
|
||||
#include "ConstraintPy.h"
|
||||
#include "PropertyConstraintList.h"
|
||||
|
||||
|
||||
using namespace App;
|
||||
@@ -52,32 +52,32 @@ TYPESYSTEM_SOURCE(Sketcher::PropertyConstraintList, App::PropertyLists)
|
||||
|
||||
|
||||
PropertyConstraintList::PropertyConstraintList()
|
||||
: validGeometryKeys(0)
|
||||
, invalidGeometry(true)
|
||||
, restoreFromTransaction(false)
|
||||
, invalidIndices(false)
|
||||
{
|
||||
|
||||
}
|
||||
: validGeometryKeys(0),
|
||||
invalidGeometry(true),
|
||||
restoreFromTransaction(false),
|
||||
invalidIndices(false)
|
||||
{}
|
||||
|
||||
PropertyConstraintList::~PropertyConstraintList()
|
||||
{
|
||||
for (std::vector<Constraint*>::iterator it = _lValueList.begin(); it != _lValueList.end(); ++it)
|
||||
if (*it) delete *it;
|
||||
if (*it)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
App::ObjectIdentifier PropertyConstraintList::makeArrayPath(int idx)
|
||||
{
|
||||
return App::ObjectIdentifier(*this,idx);
|
||||
return App::ObjectIdentifier(*this, idx);
|
||||
}
|
||||
|
||||
App::ObjectIdentifier PropertyConstraintList::makeSimplePath(const Constraint * c)
|
||||
App::ObjectIdentifier PropertyConstraintList::makeSimplePath(const Constraint* c)
|
||||
{
|
||||
return App::ObjectIdentifier(*this) << App::ObjectIdentifier::SimpleComponent(
|
||||
App::ObjectIdentifier::String(c->Name, !ExpressionParser::isTokenAnIndentifier(c->Name)));
|
||||
return App::ObjectIdentifier(*this)
|
||||
<< App::ObjectIdentifier::SimpleComponent(App::ObjectIdentifier::String(
|
||||
c->Name, !ExpressionParser::isTokenAnIndentifier(c->Name)));
|
||||
}
|
||||
|
||||
App::ObjectIdentifier PropertyConstraintList::makePath(int idx, const Constraint * c)
|
||||
App::ObjectIdentifier PropertyConstraintList::makePath(int idx, const Constraint* c)
|
||||
{
|
||||
return c->Name.empty() ? makeArrayPath(idx) : makeSimplePath(c);
|
||||
}
|
||||
@@ -176,13 +176,14 @@ void PropertyConstraintList::setValue(const Constraint* lValue)
|
||||
void PropertyConstraintList::setValues(const std::vector<Constraint*>& lValue)
|
||||
{
|
||||
auto copy = lValue;
|
||||
for(auto &cstr : copy)
|
||||
for (auto& cstr : copy)
|
||||
cstr = cstr->clone();
|
||||
|
||||
setValues(std::move(copy));
|
||||
}
|
||||
|
||||
void PropertyConstraintList::setValues(std::vector<Constraint*>&& lValue) {
|
||||
void PropertyConstraintList::setValues(std::vector<Constraint*>&& lValue)
|
||||
{
|
||||
aboutToSetValue();
|
||||
applyValues(std::move(lValue));
|
||||
hasSetValue();
|
||||
@@ -190,18 +191,19 @@ void PropertyConstraintList::setValues(std::vector<Constraint*>&& lValue) {
|
||||
|
||||
void PropertyConstraintList::applyValues(std::vector<Constraint*>&& lValue)
|
||||
{
|
||||
std::set<Constraint*> oldVals(_lValueList.begin(),_lValueList.end());
|
||||
std::set<Constraint*> oldVals(_lValueList.begin(), _lValueList.end());
|
||||
std::map<App::ObjectIdentifier, App::ObjectIdentifier> renamed;
|
||||
std::set<App::ObjectIdentifier> removed;
|
||||
boost::unordered_map<boost::uuids::uuid, std::size_t> newValueMap;
|
||||
|
||||
/* Check for renames */
|
||||
for (unsigned int i = 0; i < lValue.size(); i++) {
|
||||
boost::unordered_map<boost::uuids::uuid, std::size_t>::const_iterator j = valueMap.find(lValue[i]->tag);
|
||||
boost::unordered_map<boost::uuids::uuid, std::size_t>::const_iterator j =
|
||||
valueMap.find(lValue[i]->tag);
|
||||
|
||||
if (j != valueMap.end()) {
|
||||
if(i != j->second || _lValueList[j->second]->Name != lValue[i]->Name) {
|
||||
App::ObjectIdentifier old_oid(makePath(j->second, _lValueList[j->second] ));
|
||||
if (i != j->second || _lValueList[j->second]->Name != lValue[i]->Name) {
|
||||
App::ObjectIdentifier old_oid(makePath(j->second, _lValueList[j->second]));
|
||||
App::ObjectIdentifier new_oid(makePath(i, lValue[i]));
|
||||
renamed[old_oid] = new_oid;
|
||||
}
|
||||
@@ -215,13 +217,14 @@ void PropertyConstraintList::applyValues(std::vector<Constraint*>&& lValue)
|
||||
}
|
||||
|
||||
/* Collect info about removed elements */
|
||||
for(auto &v : valueMap)
|
||||
removed.insert(makePath(v.second,_lValueList[v.second]));
|
||||
for (auto& v : valueMap)
|
||||
removed.insert(makePath(v.second, _lValueList[v.second]));
|
||||
|
||||
/* Update value map with new tags from new array */
|
||||
valueMap = std::move(newValueMap);
|
||||
|
||||
/* Signal removes first, in case renamed values below have the same names as some of the removed ones. */
|
||||
/* Signal removes first, in case renamed values below have the same names as some of the removed
|
||||
* ones. */
|
||||
if (!removed.empty() && !restoreFromTransaction)
|
||||
signalConstraintsRemoved(removed);
|
||||
|
||||
@@ -232,52 +235,54 @@ void PropertyConstraintList::applyValues(std::vector<Constraint*>&& lValue)
|
||||
_lValueList = std::move(lValue);
|
||||
|
||||
/* Clean-up; remove old values */
|
||||
for(auto &v : oldVals)
|
||||
for (auto& v : oldVals)
|
||||
delete v;
|
||||
}
|
||||
|
||||
PyObject *PropertyConstraintList::getPyObject()
|
||||
PyObject* PropertyConstraintList::getPyObject()
|
||||
{
|
||||
PyObject* list = PyList_New(getSize());
|
||||
for (int i = 0; i < getSize(); i++)
|
||||
PyList_SetItem( list, i, _lValueList[i]->getPyObject());
|
||||
PyList_SetItem(list, i, _lValueList[i]->getPyObject());
|
||||
return list;
|
||||
}
|
||||
|
||||
bool PropertyConstraintList::getPyPathValue(const App::ObjectIdentifier &path, Py::Object &res) const {
|
||||
if(path.numSubComponents()!=2 || path.getPropertyComponent(0).getName()!=getName())
|
||||
bool PropertyConstraintList::getPyPathValue(const App::ObjectIdentifier& path,
|
||||
Py::Object& res) const
|
||||
{
|
||||
if (path.numSubComponents() != 2 || path.getPropertyComponent(0).getName() != getName())
|
||||
return false;
|
||||
|
||||
const ObjectIdentifier::Component & c1 = path.getPropertyComponent(1);
|
||||
const ObjectIdentifier::Component& c1 = path.getPropertyComponent(1);
|
||||
|
||||
const Constraint *cstr = nullptr;
|
||||
const Constraint* cstr = nullptr;
|
||||
|
||||
if (c1.isArray())
|
||||
cstr = _lValueList[c1.getIndex(_lValueList.size())];
|
||||
else if (c1.isSimple()) {
|
||||
ObjectIdentifier::Component c1 = path.getPropertyComponent(1);
|
||||
for(auto c : _lValueList) {
|
||||
if(c->Name == c1.getName()) {
|
||||
for (auto c : _lValueList) {
|
||||
if (c->Name == c1.getName()) {
|
||||
cstr = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!cstr)
|
||||
if (!cstr)
|
||||
return false;
|
||||
Quantity q = cstr->getPresentationValue();
|
||||
res = new Base::QuantityPy(new Base::Quantity(q));
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertyConstraintList::setPyObject(PyObject *value)
|
||||
void PropertyConstraintList::setPyObject(PyObject* value)
|
||||
{
|
||||
if (PyList_Check(value)) {
|
||||
Py_ssize_t nSize = PyList_Size(value);
|
||||
std::vector<Constraint*> values;
|
||||
values.resize(nSize);
|
||||
|
||||
for (Py_ssize_t i=0; i < nSize; ++i) {
|
||||
for (Py_ssize_t i = 0; i < nSize; ++i) {
|
||||
PyObject* item = PyList_GetItem(value, i);
|
||||
if (!PyObject_TypeCheck(item, &(ConstraintPy::Type))) {
|
||||
std::string error = std::string("types in list must be 'Constraint', not ");
|
||||
@@ -291,7 +296,7 @@ void PropertyConstraintList::setPyObject(PyObject *value)
|
||||
setValues(values);
|
||||
}
|
||||
else if (PyObject_TypeCheck(value, &(ConstraintPy::Type))) {
|
||||
ConstraintPy *pcObject = static_cast<ConstraintPy*>(value);
|
||||
ConstraintPy* pcObject = static_cast<ConstraintPy*>(value);
|
||||
setValue(pcObject->getConstraintPtr());
|
||||
}
|
||||
else {
|
||||
@@ -301,17 +306,17 @@ void PropertyConstraintList::setPyObject(PyObject *value)
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyConstraintList::Save(Writer &writer) const
|
||||
void PropertyConstraintList::Save(Writer& writer) const
|
||||
{
|
||||
writer.Stream() << writer.ind() << "<ConstraintList count=\"" << getSize() <<"\">" << endl;
|
||||
writer.Stream() << writer.ind() << "<ConstraintList count=\"" << getSize() << "\">" << endl;
|
||||
writer.incInd();
|
||||
for (int i = 0; i < getSize(); i++)
|
||||
_lValueList[i]->Save(writer);
|
||||
writer.decInd();
|
||||
writer.Stream() << writer.ind() << "</ConstraintList>" << endl ;
|
||||
writer.Stream() << writer.ind() << "</ConstraintList>" << endl;
|
||||
}
|
||||
|
||||
void PropertyConstraintList::Restore(Base::XMLReader &reader)
|
||||
void PropertyConstraintList::Restore(Base::XMLReader& reader)
|
||||
{
|
||||
// read my element
|
||||
reader.readElement("ConstraintList");
|
||||
@@ -321,7 +326,7 @@ void PropertyConstraintList::Restore(Base::XMLReader &reader)
|
||||
std::vector<Constraint*> values;
|
||||
values.reserve(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
Constraint *newC = new Constraint();
|
||||
Constraint* newC = new Constraint();
|
||||
newC->Restore(reader);
|
||||
// To keep upward compatibility ignore unknown constraint types
|
||||
if (newC->Type < Sketcher::NumConstraintTypes) {
|
||||
@@ -339,15 +344,15 @@ void PropertyConstraintList::Restore(Base::XMLReader &reader)
|
||||
setValues(std::move(values));
|
||||
}
|
||||
|
||||
Property *PropertyConstraintList::Copy() const
|
||||
Property* PropertyConstraintList::Copy() const
|
||||
{
|
||||
PropertyConstraintList *p = new PropertyConstraintList();
|
||||
PropertyConstraintList* p = new PropertyConstraintList();
|
||||
p->applyValidGeometryKeys(validGeometryKeys);
|
||||
p->setValues(_lValueList);
|
||||
return p;
|
||||
}
|
||||
|
||||
void PropertyConstraintList::Paste(const Property &from)
|
||||
void PropertyConstraintList::Paste(const Property& from)
|
||||
{
|
||||
Base::StateLocker lock(restoreFromTransaction, true);
|
||||
const PropertyConstraintList& FromList = dynamic_cast<const PropertyConstraintList&>(from);
|
||||
@@ -362,7 +367,7 @@ unsigned int PropertyConstraintList::getMemSize() const
|
||||
return size;
|
||||
}
|
||||
|
||||
void PropertyConstraintList::acceptGeometry(const std::vector<Part::Geometry *> &GeoList)
|
||||
void PropertyConstraintList::acceptGeometry(const std::vector<Part::Geometry*>& GeoList)
|
||||
{
|
||||
aboutToSetValue();
|
||||
validGeometryKeys.clear();
|
||||
@@ -373,21 +378,21 @@ void PropertyConstraintList::acceptGeometry(const std::vector<Part::Geometry *>
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
void PropertyConstraintList::applyValidGeometryKeys(const std::vector<unsigned int> &keys)
|
||||
void PropertyConstraintList::applyValidGeometryKeys(const std::vector<unsigned int>& keys)
|
||||
{
|
||||
validGeometryKeys = keys;
|
||||
}
|
||||
|
||||
bool PropertyConstraintList::checkGeometry(const std::vector<Part::Geometry *> &GeoList)
|
||||
bool PropertyConstraintList::checkGeometry(const std::vector<Part::Geometry*>& GeoList)
|
||||
{
|
||||
if (!scanGeometry(GeoList)) {
|
||||
invalidGeometry = true;
|
||||
return invalidGeometry;
|
||||
}
|
||||
|
||||
//if we made it here, geometry is OK
|
||||
// if we made it here, geometry is OK
|
||||
if (invalidGeometry) {
|
||||
//geometry was bad, but now it became OK.
|
||||
// geometry was bad, but now it became OK.
|
||||
invalidGeometry = false;
|
||||
touch();
|
||||
}
|
||||
@@ -400,18 +405,18 @@ bool PropertyConstraintList::checkConstraintIndices(int geomax, int geomin)
|
||||
int mininternalgeoid = std::numeric_limits<int>::max();
|
||||
int maxinternalgeoid = GeoEnum::GeoUndef;
|
||||
|
||||
auto cmin = [] (int previousmin, int cindex) {
|
||||
if( cindex == GeoEnum::GeoUndef )
|
||||
auto cmin = [](int previousmin, int cindex) {
|
||||
if (cindex == GeoEnum::GeoUndef)
|
||||
return previousmin;
|
||||
|
||||
return ( cindex < previousmin )? cindex : previousmin;
|
||||
return (cindex < previousmin) ? cindex : previousmin;
|
||||
};
|
||||
|
||||
auto cmax = [] (int previousmax, int cindex) {
|
||||
return ( cindex > previousmax )? cindex : previousmax;
|
||||
auto cmax = [](int previousmax, int cindex) {
|
||||
return (cindex > previousmax) ? cindex : previousmax;
|
||||
};
|
||||
|
||||
for (const auto &v : _lValueList) {
|
||||
for (const auto& v : _lValueList) {
|
||||
|
||||
mininternalgeoid = cmin(mininternalgeoid, v->First);
|
||||
mininternalgeoid = cmin(mininternalgeoid, v->Second);
|
||||
@@ -422,7 +427,7 @@ bool PropertyConstraintList::checkConstraintIndices(int geomax, int geomin)
|
||||
maxinternalgeoid = cmax(maxinternalgeoid, v->Third);
|
||||
}
|
||||
|
||||
if(maxinternalgeoid > geomax || mininternalgeoid < geomin)
|
||||
if (maxinternalgeoid > geomax || mininternalgeoid < geomin)
|
||||
invalidIndices = true;
|
||||
else
|
||||
invalidIndices = false;
|
||||
@@ -436,15 +441,15 @@ bool PropertyConstraintList::checkConstraintIndices(int geomax, int geomin)
|
||||
* \param GeoList - new geometry list to be checked
|
||||
* \return false, if the types have changed.
|
||||
*/
|
||||
bool PropertyConstraintList::scanGeometry(const std::vector<Part::Geometry *> &GeoList) const
|
||||
bool PropertyConstraintList::scanGeometry(const std::vector<Part::Geometry*>& GeoList) const
|
||||
{
|
||||
if (validGeometryKeys.size() != GeoList.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int i=0;
|
||||
for (std::vector< Part::Geometry * >::const_iterator it=GeoList.begin();
|
||||
it != GeoList.end(); ++it, i++) {
|
||||
unsigned int i = 0;
|
||||
for (std::vector<Part::Geometry*>::const_iterator it = GeoList.begin(); it != GeoList.end();
|
||||
++it, i++) {
|
||||
if (validGeometryKeys[i] != (*it)->getTypeId().getKey()) {
|
||||
return false;
|
||||
}
|
||||
@@ -453,7 +458,7 @@ bool PropertyConstraintList::scanGeometry(const std::vector<Part::Geometry *> &G
|
||||
return true;
|
||||
}
|
||||
|
||||
string PropertyConstraintList::getConstraintName(const std::string & name, int i)
|
||||
string PropertyConstraintList::getConstraintName(const std::string& name, int i)
|
||||
{
|
||||
if (!name.empty())
|
||||
return name;
|
||||
@@ -469,27 +474,27 @@ string PropertyConstraintList::getConstraintName(int i)
|
||||
return str.str();
|
||||
}
|
||||
|
||||
bool PropertyConstraintList::validConstraintName(const std::string & name)
|
||||
bool PropertyConstraintList::validConstraintName(const std::string& name)
|
||||
{
|
||||
return !name.empty();
|
||||
}
|
||||
|
||||
ObjectIdentifier PropertyConstraintList::createPath(int ConstrNbr) const
|
||||
{
|
||||
return App::ObjectIdentifier(*this,ConstrNbr);
|
||||
return App::ObjectIdentifier(*this, ConstrNbr);
|
||||
}
|
||||
|
||||
int PropertyConstraintList::getIndexFromConstraintName(const string &name)
|
||||
int PropertyConstraintList::getIndexFromConstraintName(const string& name)
|
||||
{
|
||||
return std::atoi(name.substr(10,4000).c_str()) - 1;
|
||||
return std::atoi(name.substr(10, 4000).c_str()) - 1;
|
||||
}
|
||||
|
||||
void PropertyConstraintList::setPathValue(const ObjectIdentifier &path, const boost::any &value)
|
||||
void PropertyConstraintList::setPathValue(const ObjectIdentifier& path, const boost::any& value)
|
||||
{
|
||||
if(path.numSubComponents()!=2 || path.getPropertyComponent(0).getName()!=getName())
|
||||
FC_THROWM(Base::ValueError,"invalid constraint path " << path.toString());
|
||||
if (path.numSubComponents() != 2 || path.getPropertyComponent(0).getName() != getName())
|
||||
FC_THROWM(Base::ValueError, "invalid constraint path " << path.toString());
|
||||
|
||||
const ObjectIdentifier::Component & c1 = path.getPropertyComponent(1);
|
||||
const ObjectIdentifier::Component& c1 = path.getPropertyComponent(1);
|
||||
double dvalue;
|
||||
|
||||
if (value.type() == typeid(double))
|
||||
@@ -501,18 +506,18 @@ void PropertyConstraintList::setPathValue(const ObjectIdentifier &path, const bo
|
||||
else if (value.type() == typeid(int))
|
||||
dvalue = App::any_cast<int>(value);
|
||||
else if (value.type() == typeid(Quantity))
|
||||
dvalue = (App::any_cast<const Quantity &>(value)).getValue();
|
||||
dvalue = (App::any_cast<const Quantity&>(value)).getValue();
|
||||
else
|
||||
throw std::bad_cast();
|
||||
|
||||
if (c1.isArray()) {
|
||||
size_t index = c1.getIndex(_lValueList.size());
|
||||
switch (_lValueList[index]->Type) {
|
||||
case Angle:
|
||||
dvalue = Base::toRadians<double>(dvalue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case Angle:
|
||||
dvalue = Base::toRadians<double>(dvalue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
aboutToSetValue();
|
||||
_lValueList[index]->setValue(dvalue);
|
||||
@@ -520,16 +525,18 @@ void PropertyConstraintList::setPathValue(const ObjectIdentifier &path, const bo
|
||||
return;
|
||||
}
|
||||
else if (c1.isSimple()) {
|
||||
for (std::vector<Constraint *>::const_iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) {
|
||||
for (std::vector<Constraint*>::const_iterator it = _lValueList.begin();
|
||||
it != _lValueList.end();
|
||||
++it) {
|
||||
int index = it - _lValueList.begin();
|
||||
|
||||
if ((*it)->Name == c1.getName()) {
|
||||
switch (_lValueList[index]->Type) {
|
||||
case Angle:
|
||||
dvalue = Base::toRadians<double>(dvalue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case Angle:
|
||||
dvalue = Base::toRadians<double>(dvalue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
aboutToSetValue();
|
||||
_lValueList[index]->setValue(dvalue);
|
||||
@@ -538,15 +545,15 @@ void PropertyConstraintList::setPathValue(const ObjectIdentifier &path, const bo
|
||||
}
|
||||
}
|
||||
}
|
||||
FC_THROWM(Base::ValueError,"invalid constraint path " << path.toString());
|
||||
FC_THROWM(Base::ValueError, "invalid constraint path " << path.toString());
|
||||
}
|
||||
|
||||
const Constraint * PropertyConstraintList::getConstraint(const ObjectIdentifier &path) const
|
||||
const Constraint* PropertyConstraintList::getConstraint(const ObjectIdentifier& path) const
|
||||
{
|
||||
if(path.numSubComponents()!=2 || path.getPropertyComponent(0).getName()!=getName())
|
||||
FC_THROWM(Base::ValueError,"Invalid constraint path " << path.toString());
|
||||
if (path.numSubComponents() != 2 || path.getPropertyComponent(0).getName() != getName())
|
||||
FC_THROWM(Base::ValueError, "Invalid constraint path " << path.toString());
|
||||
|
||||
const ObjectIdentifier::Component & c1 = path.getPropertyComponent(1);
|
||||
const ObjectIdentifier::Component& c1 = path.getPropertyComponent(1);
|
||||
|
||||
if (c1.isArray()) {
|
||||
return _lValueList[c1.getIndex(_lValueList.size())];
|
||||
@@ -554,44 +561,49 @@ const Constraint * PropertyConstraintList::getConstraint(const ObjectIdentifier
|
||||
else if (c1.isSimple()) {
|
||||
ObjectIdentifier::Component c1 = path.getPropertyComponent(1);
|
||||
|
||||
for (std::vector<Constraint *>::const_iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) {
|
||||
for (std::vector<Constraint*>::const_iterator it = _lValueList.begin();
|
||||
it != _lValueList.end();
|
||||
++it) {
|
||||
if ((*it)->Name == c1.getName())
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
FC_THROWM(Base::ValueError,"Invalid constraint path " << path.toString());
|
||||
FC_THROWM(Base::ValueError, "Invalid constraint path " << path.toString());
|
||||
}
|
||||
|
||||
const boost::any PropertyConstraintList::getPathValue(const ObjectIdentifier &path) const
|
||||
const boost::any PropertyConstraintList::getPathValue(const ObjectIdentifier& path) const
|
||||
{
|
||||
return boost::any(getConstraint(path)->getPresentationValue());
|
||||
}
|
||||
|
||||
ObjectIdentifier PropertyConstraintList::canonicalPath(const ObjectIdentifier &p) const
|
||||
ObjectIdentifier PropertyConstraintList::canonicalPath(const ObjectIdentifier& p) const
|
||||
{
|
||||
if(p.numSubComponents()!=2 || p.getPropertyComponent(0).getName()!=getName())
|
||||
FC_THROWM(Base::ValueError,"Invalid constraint path " << p.toString());
|
||||
if (p.numSubComponents() != 2 || p.getPropertyComponent(0).getName() != getName())
|
||||
FC_THROWM(Base::ValueError, "Invalid constraint path " << p.toString());
|
||||
|
||||
const ObjectIdentifier::Component & c1 = p.getPropertyComponent(1);
|
||||
const ObjectIdentifier::Component& c1 = p.getPropertyComponent(1);
|
||||
|
||||
if (c1.isArray()) {
|
||||
size_t idx = c1.getIndex();
|
||||
if (idx < _lValueList.size() && !_lValueList[idx]->Name.empty())
|
||||
return ObjectIdentifier(*this) << ObjectIdentifier::SimpleComponent(_lValueList[idx]->Name);
|
||||
return ObjectIdentifier(*this)
|
||||
<< ObjectIdentifier::SimpleComponent(_lValueList[idx]->Name);
|
||||
return p;
|
||||
}
|
||||
else if (c1.isSimple()) {
|
||||
return p;
|
||||
}
|
||||
FC_THROWM(Base::ValueError,"Invalid constraint path " << p.toString());
|
||||
FC_THROWM(Base::ValueError, "Invalid constraint path " << p.toString());
|
||||
}
|
||||
|
||||
void PropertyConstraintList::getPaths(std::vector<ObjectIdentifier> &paths) const
|
||||
void PropertyConstraintList::getPaths(std::vector<ObjectIdentifier>& paths) const
|
||||
{
|
||||
for (std::vector<Constraint *>::const_iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) {
|
||||
for (std::vector<Constraint*>::const_iterator it = _lValueList.begin(); it != _lValueList.end();
|
||||
++it) {
|
||||
if (!(*it)->Name.empty())
|
||||
paths.push_back(ObjectIdentifier(*this) << ObjectIdentifier::SimpleComponent((*it)->Name));
|
||||
paths.push_back(ObjectIdentifier(*this)
|
||||
<< ObjectIdentifier::SimpleComponent((*it)->Name));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Constraint *> PropertyConstraintList::_emptyValueList(0);
|
||||
std::vector<Constraint*> PropertyConstraintList::_emptyValueList(0);
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost_signals2.hpp>
|
||||
#include <boost/unordered/unordered_map.hpp>
|
||||
#include <boost_signals2.hpp>
|
||||
|
||||
#include <App/Property.h>
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
@@ -35,7 +35,8 @@
|
||||
#include "Constraint.h"
|
||||
|
||||
|
||||
namespace Base {
|
||||
namespace Base
|
||||
{
|
||||
class Writer;
|
||||
}
|
||||
|
||||
@@ -43,7 +44,7 @@ namespace Sketcher
|
||||
{
|
||||
class Constraint;
|
||||
|
||||
class SketcherExport PropertyConstraintList : public App::PropertyLists
|
||||
class SketcherExport PropertyConstraintList: public App::PropertyLists
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -63,7 +64,8 @@ public:
|
||||
void setSize(int newSize) override;
|
||||
int getSize() const override;
|
||||
|
||||
const char* getEditorName() const override {
|
||||
const char* getEditorName() const override
|
||||
{
|
||||
return "SketcherGui::PropertyConstraintListItem";
|
||||
}
|
||||
|
||||
@@ -98,67 +100,76 @@ public:
|
||||
\note If the geometry is invalid then the index operator
|
||||
returns null. This must be checked by the caller.
|
||||
*/
|
||||
const Constraint *operator[] (const int idx) const {
|
||||
const Constraint* operator[](const int idx) const
|
||||
{
|
||||
return (invalidGeometry || invalidIndices) ? nullptr : _lValueList[idx];
|
||||
}
|
||||
|
||||
const std::vector<Constraint*> &getValues() const {
|
||||
const std::vector<Constraint*>& getValues() const
|
||||
{
|
||||
return (invalidGeometry || invalidIndices) ? _emptyValueList : _lValueList;
|
||||
}
|
||||
const std::vector<Constraint*> &getValuesForce() const {//to suppress check for invalid geometry, to be used for sketch repairing.
|
||||
return _lValueList;
|
||||
|
||||
// to suppress check for invalid geometry, to be used for sketch repairing.
|
||||
const std::vector<Constraint*>& getValuesForce() const
|
||||
{
|
||||
return _lValueList;
|
||||
}
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
void setPyObject(PyObject *) override;
|
||||
PyObject* getPyObject() override;
|
||||
void setPyObject(PyObject*) override;
|
||||
|
||||
void Save(Base::Writer &writer) const override;
|
||||
void Restore(Base::XMLReader &reader) override;
|
||||
void Save(Base::Writer& writer) const override;
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
Property *Copy() const override;
|
||||
void Paste(const App::Property &from) override;
|
||||
Property* Copy() const override;
|
||||
void Paste(const App::Property& from) override;
|
||||
|
||||
unsigned int getMemSize() const override;
|
||||
|
||||
void acceptGeometry(const std::vector<Part::Geometry *> &GeoList);
|
||||
bool checkGeometry(const std::vector<Part::Geometry *> &GeoList);
|
||||
bool scanGeometry(const std::vector<Part::Geometry *> &GeoList) const;
|
||||
void acceptGeometry(const std::vector<Part::Geometry*>& GeoList);
|
||||
bool checkGeometry(const std::vector<Part::Geometry*>& GeoList);
|
||||
bool scanGeometry(const std::vector<Part::Geometry*>& GeoList) const;
|
||||
|
||||
bool checkConstraintIndices(int geomax, int geomin);
|
||||
|
||||
/// Return status of geometry for better error reporting
|
||||
bool hasInvalidGeometry() const { return invalidGeometry; }
|
||||
bool hasInvalidGeometry() const
|
||||
{
|
||||
return invalidGeometry;
|
||||
}
|
||||
|
||||
|
||||
const Constraint *getConstraint(const App::ObjectIdentifier &path) const;
|
||||
void setPathValue(const App::ObjectIdentifier & path, const boost::any & value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier & path) const override;
|
||||
App::ObjectIdentifier canonicalPath(const App::ObjectIdentifier & p) const override;
|
||||
void getPaths(std::vector<App::ObjectIdentifier> & paths) const override;
|
||||
const Constraint* getConstraint(const App::ObjectIdentifier& path) const;
|
||||
void setPathValue(const App::ObjectIdentifier& path, const boost::any& value) override;
|
||||
const boost::any getPathValue(const App::ObjectIdentifier& path) const override;
|
||||
App::ObjectIdentifier canonicalPath(const App::ObjectIdentifier& p) const override;
|
||||
void getPaths(std::vector<App::ObjectIdentifier>& paths) const override;
|
||||
|
||||
bool getPyPathValue(const App::ObjectIdentifier &path, Py::Object &res) const override;
|
||||
bool getPyPathValue(const App::ObjectIdentifier& path, Py::Object& res) const override;
|
||||
|
||||
using ConstraintInfo = std::pair<int, const Constraint*> ;
|
||||
using ConstraintInfo = std::pair<int, const Constraint*>;
|
||||
|
||||
boost::signals2::signal<void (const std::map<App::ObjectIdentifier, App::ObjectIdentifier> &)> signalConstraintsRenamed;
|
||||
boost::signals2::signal<void (const std::set<App::ObjectIdentifier> &)> signalConstraintsRemoved;
|
||||
boost::signals2::signal<void(const std::map<App::ObjectIdentifier, App::ObjectIdentifier>&)>
|
||||
signalConstraintsRenamed;
|
||||
boost::signals2::signal<void(const std::set<App::ObjectIdentifier>&)> signalConstraintsRemoved;
|
||||
|
||||
static std::string getConstraintName(const std::string &name, int i);
|
||||
static std::string getConstraintName(const std::string& name, int i);
|
||||
|
||||
static std::string getConstraintName(int i);
|
||||
|
||||
static int getIndexFromConstraintName(const std::string & name);
|
||||
static int getIndexFromConstraintName(const std::string& name);
|
||||
|
||||
static bool validConstraintName(const std::string &name);
|
||||
static bool validConstraintName(const std::string& name);
|
||||
|
||||
App::ObjectIdentifier createPath(int ConstrNbr) const;
|
||||
|
||||
private:
|
||||
App::ObjectIdentifier makeArrayPath(int idx);
|
||||
App::ObjectIdentifier makeSimplePath(const Constraint *c);
|
||||
App::ObjectIdentifier makePath(int idx, const Constraint *c);
|
||||
App::ObjectIdentifier makeSimplePath(const Constraint* c);
|
||||
App::ObjectIdentifier makePath(int idx, const Constraint* c);
|
||||
|
||||
std::vector<Constraint *> _lValueList;
|
||||
std::vector<Constraint*> _lValueList;
|
||||
boost::unordered_map<boost::uuids::uuid, std::size_t> valueMap;
|
||||
|
||||
std::vector<unsigned int> validGeometryKeys;
|
||||
@@ -167,12 +178,12 @@ private:
|
||||
bool invalidIndices;
|
||||
|
||||
void applyValues(std::vector<Constraint*>&&);
|
||||
void applyValidGeometryKeys(const std::vector<unsigned int> &keys);
|
||||
void applyValidGeometryKeys(const std::vector<unsigned int>& keys);
|
||||
|
||||
static std::vector<Constraint *> _emptyValueList;
|
||||
static std::vector<Constraint*> _emptyValueList;
|
||||
};
|
||||
|
||||
} // namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
#endif // APP_PropertyConstraintList_H
|
||||
#endif// APP_PropertyConstraintList_H
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <boost/format.hpp>
|
||||
#endif // #ifndef _PreComp_
|
||||
#include <boost/format.hpp>
|
||||
#endif// #ifndef _PreComp_
|
||||
|
||||
#include <Base/Exception.h>
|
||||
#include <Mod/Sketcher/App/Constraint.h>
|
||||
@@ -34,20 +34,20 @@
|
||||
|
||||
using namespace Sketcher;
|
||||
|
||||
std::string PythonConverter::convert(const Part::Geometry * geo)
|
||||
std::string PythonConverter::convert(const Part::Geometry* geo)
|
||||
{
|
||||
// "addGeometry(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)),%s)"
|
||||
|
||||
std::string command;
|
||||
auto sg = process(geo);
|
||||
|
||||
command = boost::str(boost::format("addGeometry(%s,%s)\n") %
|
||||
sg.creation % (sg.construction ? "True":"False"));
|
||||
command = boost::str(boost::format("addGeometry(%s,%s)\n") % sg.creation
|
||||
% (sg.construction ? "True" : "False"));
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
std::string PythonConverter::convert(const Sketcher::Constraint * constraint)
|
||||
std::string PythonConverter::convert(const Sketcher::Constraint* constraint)
|
||||
{
|
||||
// addConstraint(Sketcher.Constraint('Distance',%d,%f))
|
||||
std::string command;
|
||||
@@ -58,41 +58,42 @@ std::string PythonConverter::convert(const Sketcher::Constraint * constraint)
|
||||
return command;
|
||||
}
|
||||
|
||||
std::string PythonConverter::convert(const std::string & doc, const std::vector<Part::Geometry *> & geos)
|
||||
std::string PythonConverter::convert(const std::string& doc,
|
||||
const std::vector<Part::Geometry*>& geos)
|
||||
{
|
||||
std::string geolist = "geoList = []\n";
|
||||
std::string constrgeolist = "constrGeoList = []\n";
|
||||
|
||||
int ngeo = 0, nconstr = 0;
|
||||
|
||||
for(auto geo : geos) {
|
||||
for (auto geo : geos) {
|
||||
auto sg = process(geo);
|
||||
|
||||
if (sg.construction) {
|
||||
constrgeolist = boost::str(boost::format("%s\nconstrGeoList.append(%s)\n") %
|
||||
constrgeolist % sg.creation);
|
||||
constrgeolist = boost::str(boost::format("%s\nconstrGeoList.append(%s)\n")
|
||||
% constrgeolist % sg.creation);
|
||||
nconstr++;
|
||||
}
|
||||
else {
|
||||
geolist = boost::str(boost::format("%s\ngeoList.append(%s)\n") %
|
||||
geolist % sg.creation);
|
||||
geolist = boost::str(boost::format("%s\ngeoList.append(%s)\n") % geolist % sg.creation);
|
||||
ngeo++;
|
||||
}
|
||||
}
|
||||
|
||||
if(ngeo > 0) {
|
||||
geolist = boost::str(boost::format("%s\n%s.addGeometry(geoList,%s)\ndel geoList\n") %
|
||||
geolist % doc % "False");
|
||||
if (ngeo > 0) {
|
||||
geolist = boost::str(boost::format("%s\n%s.addGeometry(geoList,%s)\ndel geoList\n")
|
||||
% geolist % doc % "False");
|
||||
}
|
||||
|
||||
if(nconstr > 0) {
|
||||
constrgeolist = boost::str(boost::format("%s\n%s.addGeometry(constrGeoList,%s)\ndel constrGeoList") %
|
||||
constrgeolist % doc % "True");
|
||||
if (nconstr > 0) {
|
||||
constrgeolist =
|
||||
boost::str(boost::format("%s\n%s.addGeometry(constrGeoList,%s)\ndel constrGeoList")
|
||||
% constrgeolist % doc % "True");
|
||||
}
|
||||
|
||||
std::string command;
|
||||
|
||||
if(ngeo > 0 && nconstr > 0)
|
||||
if (ngeo > 0 && nconstr > 0)
|
||||
command = geolist + constrgeolist;
|
||||
else if (ngeo > 0)
|
||||
command = std::move(geolist);
|
||||
@@ -102,95 +103,107 @@ std::string PythonConverter::convert(const std::string & doc, const std::vector<
|
||||
return command;
|
||||
}
|
||||
|
||||
std::string PythonConverter::convert(const std::string & doc, const std::vector<Sketcher::Constraint *> & constraints)
|
||||
std::string PythonConverter::convert(const std::string& doc,
|
||||
const std::vector<Sketcher::Constraint*>& constraints)
|
||||
{
|
||||
if(constraints.size() == 1) {
|
||||
if (constraints.size() == 1) {
|
||||
auto cg = convert(constraints[0]);
|
||||
|
||||
return boost::str(boost::format("%s.%s\n") %
|
||||
doc % cg);
|
||||
return boost::str(boost::format("%s.%s\n") % doc % cg);
|
||||
}
|
||||
|
||||
std::string constraintlist = "constraintList = []";
|
||||
|
||||
for(auto constraint : constraints) {
|
||||
for (auto constraint : constraints) {
|
||||
auto cg = process(constraint);
|
||||
|
||||
constraintlist = boost::str(boost::format("%s\nconstraintList.append(%s)") %
|
||||
constraintlist % cg);
|
||||
constraintlist =
|
||||
boost::str(boost::format("%s\nconstraintList.append(%s)") % constraintlist % cg);
|
||||
}
|
||||
|
||||
if(!constraints.empty()) {
|
||||
constraintlist = boost::str(boost::format("%s\n%s.addConstraint(constraintList)\ndel constraintList\n") %
|
||||
constraintlist % doc);
|
||||
if (!constraints.empty()) {
|
||||
constraintlist =
|
||||
boost::str(boost::format("%s\n%s.addConstraint(constraintList)\ndel constraintList\n")
|
||||
% constraintlist % doc);
|
||||
}
|
||||
|
||||
return constraintlist;
|
||||
}
|
||||
|
||||
PythonConverter::SingleGeometry PythonConverter::process(const Part::Geometry * geo)
|
||||
PythonConverter::SingleGeometry PythonConverter::process(const Part::Geometry* geo)
|
||||
{
|
||||
static std::map<const Base::Type, std::function<SingleGeometry(const Part::Geometry * geo)>> converterMap = {
|
||||
{ Part::GeomLineSegment::getClassTypeId(),
|
||||
[](const Part::Geometry * geo){
|
||||
auto sgeo = static_cast<const Part::GeomLineSegment *>(geo);
|
||||
SingleGeometry sg;
|
||||
sg.creation = boost::str(boost::format("Part.LineSegment(App.Vector(%f,%f,%f),App.Vector(%f,%f,%f))") %
|
||||
sgeo->getStartPoint().x % sgeo->getStartPoint().y % sgeo->getStartPoint().z %
|
||||
sgeo->getEndPoint().x % sgeo->getEndPoint().y % sgeo->getEndPoint().z);
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
{ Part::GeomArcOfCircle::getClassTypeId(),
|
||||
[](const Part::Geometry * geo){
|
||||
auto arc = static_cast<const Part::GeomArcOfCircle *>(geo);
|
||||
SingleGeometry sg;
|
||||
sg.creation = boost::str(boost::format("Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, %f), App.Vector(%f, %f, %f), %f), %f, %f)") %
|
||||
arc->getCenter().x % arc->getCenter().y % arc->getCenter().z %
|
||||
arc->getAxisDirection().x % arc->getAxisDirection().y % arc->getAxisDirection().z %
|
||||
arc->getRadius() % arc->getFirstParameter() % arc->getLastParameter());
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
{ Part::GeomPoint::getClassTypeId(),
|
||||
[](const Part::Geometry* geo) {
|
||||
auto sgeo = static_cast<const Part::GeomPoint*>(geo);
|
||||
SingleGeometry sg;
|
||||
sg.creation = boost::str(boost::format("Part.Point(App.Vector(%f,%f,%f))") %
|
||||
sgeo->getPoint().x % sgeo->getPoint().y % sgeo->getPoint().z);
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
{ Part::GeomEllipse::getClassTypeId(),
|
||||
[](const Part::Geometry * geo){
|
||||
auto ellipse = static_cast<const Part::GeomEllipse *>(geo);
|
||||
SingleGeometry sg;
|
||||
auto periapsis = ellipse->getCenter() + ellipse->getMajorAxisDir() * ellipse->getMajorRadius();
|
||||
auto positiveB = ellipse->getCenter() + ellipse->getMinorAxisDir() * ellipse->getMinorRadius();
|
||||
auto center = ellipse->getCenter();
|
||||
sg.creation = boost::str(boost::format("Part.Ellipse(App.Vector(%f, %f, %f), App.Vector(%f, %f, %f), App.Vector(%f, %f, %f))") %
|
||||
periapsis.x % periapsis.y % periapsis.z %
|
||||
positiveB.x % positiveB.y % positiveB.z %
|
||||
center.x % center.y % center.z);
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
{ Part::GeomCircle::getClassTypeId(),
|
||||
[](const Part::Geometry * geo){
|
||||
auto circle = static_cast<const Part::GeomCircle *>(geo);
|
||||
SingleGeometry sg;
|
||||
sg.creation = boost::str(boost::format("Part.Circle(App.Vector(%f, %f, %f), App.Vector(%f, %f, %f), %f)") %
|
||||
circle->getCenter().x % circle->getCenter().y % circle->getCenter().z %
|
||||
circle->getAxisDirection().x % circle->getAxisDirection().y % circle->getAxisDirection().z %
|
||||
circle->getRadius());
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
};
|
||||
static std::map<const Base::Type, std::function<SingleGeometry(const Part::Geometry* geo)>>
|
||||
converterMap = {
|
||||
{Part::GeomLineSegment::getClassTypeId(),
|
||||
[](const Part::Geometry* geo) {
|
||||
auto sgeo = static_cast<const Part::GeomLineSegment*>(geo);
|
||||
SingleGeometry sg;
|
||||
sg.creation = boost::str(
|
||||
boost::format("Part.LineSegment(App.Vector(%f,%f,%f),App.Vector(%f,%f,%f))")
|
||||
% sgeo->getStartPoint().x % sgeo->getStartPoint().y % sgeo->getStartPoint().z
|
||||
% sgeo->getEndPoint().x % sgeo->getEndPoint().y % sgeo->getEndPoint().z);
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
{Part::GeomArcOfCircle::getClassTypeId(),
|
||||
[](const Part::Geometry* geo) {
|
||||
auto arc = static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
SingleGeometry sg;
|
||||
sg.creation =
|
||||
boost::str(boost::format("Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, "
|
||||
"%f), App.Vector(%f, %f, %f), %f), %f, %f)")
|
||||
% arc->getCenter().x % arc->getCenter().y % arc->getCenter().z
|
||||
% arc->getAxisDirection().x % arc->getAxisDirection().y
|
||||
% arc->getAxisDirection().z % arc->getRadius()
|
||||
% arc->getFirstParameter() % arc->getLastParameter());
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
{Part::GeomPoint::getClassTypeId(),
|
||||
[](const Part::Geometry* geo) {
|
||||
auto sgeo = static_cast<const Part::GeomPoint*>(geo);
|
||||
SingleGeometry sg;
|
||||
sg.creation =
|
||||
boost::str(boost::format("Part.Point(App.Vector(%f,%f,%f))")
|
||||
% sgeo->getPoint().x % sgeo->getPoint().y % sgeo->getPoint().z);
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
{Part::GeomEllipse::getClassTypeId(),
|
||||
[](const Part::Geometry* geo) {
|
||||
auto ellipse = static_cast<const Part::GeomEllipse*>(geo);
|
||||
SingleGeometry sg;
|
||||
auto periapsis =
|
||||
ellipse->getCenter() + ellipse->getMajorAxisDir() * ellipse->getMajorRadius();
|
||||
auto positiveB =
|
||||
ellipse->getCenter() + ellipse->getMinorAxisDir() * ellipse->getMinorRadius();
|
||||
auto center = ellipse->getCenter();
|
||||
sg.creation =
|
||||
boost::str(boost::format("Part.Ellipse(App.Vector(%f, %f, %f), App.Vector(%f, "
|
||||
"%f, %f), App.Vector(%f, %f, %f))")
|
||||
% periapsis.x % periapsis.y % periapsis.z % positiveB.x
|
||||
% positiveB.y % positiveB.z % center.x % center.y % center.z);
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
{Part::GeomCircle::getClassTypeId(),
|
||||
[](const Part::Geometry* geo) {
|
||||
auto circle = static_cast<const Part::GeomCircle*>(geo);
|
||||
SingleGeometry sg;
|
||||
sg.creation = boost::str(
|
||||
boost::format(
|
||||
"Part.Circle(App.Vector(%f, %f, %f), App.Vector(%f, %f, %f), %f)")
|
||||
% circle->getCenter().x % circle->getCenter().y % circle->getCenter().z
|
||||
% circle->getAxisDirection().x % circle->getAxisDirection().y
|
||||
% circle->getAxisDirection().z % circle->getRadius());
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
};
|
||||
|
||||
auto result = converterMap.find(geo->getTypeId());
|
||||
|
||||
if( result == converterMap.end())
|
||||
if (result == converterMap.end())
|
||||
THROWM(Base::ValueError, "PythonConverter: Geometry Type not supported")
|
||||
|
||||
auto creator = result->second;
|
||||
@@ -198,210 +211,248 @@ PythonConverter::SingleGeometry PythonConverter::process(const Part::Geometry *
|
||||
return creator(geo);
|
||||
}
|
||||
|
||||
std::string PythonConverter::process(const Sketcher::Constraint * constraint)
|
||||
std::string PythonConverter::process(const Sketcher::Constraint* constraint)
|
||||
{
|
||||
static std::map<const Sketcher::ConstraintType, std::function<std::string(const Sketcher::Constraint *)>> converterMap = {
|
||||
{ Sketcher::Coincident,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Coincident', %i, %i, %i, %i)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second % static_cast<int>(constr->SecondPos));
|
||||
}},
|
||||
{ Sketcher::Horizontal,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
if(constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Horizontal', %i)") % constr->First);
|
||||
}
|
||||
else {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Horizontal', %i, %i, %i, %i)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second % static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{ Sketcher::Vertical,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
if(constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Vertical', %i)") % constr->First);
|
||||
}
|
||||
else {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Vertical', %i, %i, %i, %i)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second % static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{ Sketcher::Block,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Block', %i)") % constr->First);
|
||||
}},
|
||||
{ Sketcher::Tangent,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
if(constr->FirstPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Tangent', %i, %i)") %
|
||||
constr->First % constr->Second);
|
||||
}
|
||||
else if(constr->SecondPos == Sketcher::PointPos::none){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Tangent', %i, %i, %i)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second);
|
||||
}
|
||||
else {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Tangent', %i, %i, %i, %i)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second % static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{ Sketcher::Parallel,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Parallel', %i, %i)") %
|
||||
constr->First % constr->Second);
|
||||
}},
|
||||
{ Sketcher::Perpendicular,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
if(constr->FirstPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Perpendicular', %i, %i)") %
|
||||
constr->First % constr->Second);
|
||||
}
|
||||
else if(constr->SecondPos == Sketcher::PointPos::none){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Perpendicular', %i, %i, %i)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second);
|
||||
}
|
||||
else {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Perpendicular', %i, %i, %i, %i)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second % static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{ Sketcher::Equal,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Equal', %i, %i)") %
|
||||
constr->First % constr->Second);
|
||||
}},
|
||||
{ Sketcher::InternalAlignment,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
if(constr->InternalAlignmentIndex == EllipseMajorDiameter ||
|
||||
constr->InternalAlignmentIndex == EllipseMinorDiameter) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('InternalAlignment:%s', %i, %i)") %
|
||||
constr->internalAlignmentTypeToString() % constr->First % constr->Second);
|
||||
}
|
||||
else if(constr->InternalAlignmentIndex == EllipseFocus1 ||
|
||||
constr->InternalAlignmentIndex == EllipseFocus2) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('InternalAlignment:%s', %i, %i, %i)") %
|
||||
constr->internalAlignmentTypeToString() % constr->First % static_cast<int>(constr->FirstPos) % constr->Second);
|
||||
}
|
||||
else if(constr->InternalAlignmentIndex == BSplineControlPoint) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('InternalAlignment:%s', %i, %i, %i, %i)") %
|
||||
constr->internalAlignmentTypeToString() % constr->First % static_cast<int>(constr->FirstPos) %
|
||||
constr->Second % constr->InternalAlignmentIndex);
|
||||
}
|
||||
static std::map<const Sketcher::ConstraintType,
|
||||
std::function<std::string(const Sketcher::Constraint*)>>
|
||||
converterMap = {
|
||||
{Sketcher::Coincident,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Coincident', %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos));
|
||||
}},
|
||||
{Sketcher::Horizontal,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Horizontal', %i)")
|
||||
% constr->First);
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Horizontal', %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{Sketcher::Vertical,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Vertical', %i)")
|
||||
% constr->First);
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Vertical', %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{Sketcher::Block,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Block', %i)")
|
||||
% constr->First);
|
||||
}},
|
||||
{Sketcher::Tangent,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
if (constr->FirstPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Tangent', %i, %i)")
|
||||
% constr->First % constr->Second);
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Tangent', %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos)
|
||||
% constr->Second);
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Tangent', %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{Sketcher::Parallel,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Parallel', %i, %i)")
|
||||
% constr->First % constr->Second);
|
||||
}},
|
||||
{Sketcher::Perpendicular,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
if (constr->FirstPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Perpendicular', %i, %i)")
|
||||
% constr->First % constr->Second);
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Perpendicular', %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second);
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Perpendicular', %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{Sketcher::Equal,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Equal', %i, %i)")
|
||||
% constr->First % constr->Second);
|
||||
}},
|
||||
{Sketcher::InternalAlignment,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
if (constr->InternalAlignmentIndex == EllipseMajorDiameter
|
||||
|| constr->InternalAlignmentIndex == EllipseMinorDiameter) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('InternalAlignment:%s', %i, %i)")
|
||||
% constr->internalAlignmentTypeToString() % constr->First
|
||||
% constr->Second);
|
||||
}
|
||||
else if (constr->InternalAlignmentIndex == EllipseFocus1
|
||||
|| constr->InternalAlignmentIndex == EllipseFocus2) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('InternalAlignment:%s', %i, %i, %i)")
|
||||
% constr->internalAlignmentTypeToString() % constr->First
|
||||
% static_cast<int>(constr->FirstPos) % constr->Second);
|
||||
}
|
||||
else if (constr->InternalAlignmentIndex == BSplineControlPoint) {
|
||||
return boost::str(
|
||||
boost::format(
|
||||
"Sketcher.Constraint('InternalAlignment:%s', %i, %i, %i, %i)")
|
||||
% constr->internalAlignmentTypeToString() % constr->First
|
||||
% static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% constr->InternalAlignmentIndex);
|
||||
}
|
||||
|
||||
THROWM(Base::ValueError, "PythonConverter: Constraint Alignment Type not supported")
|
||||
}},
|
||||
{ Sketcher::Distance,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
if(constr->Second == GeoEnum::GeoUndef){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Distance', %i, %f)") %
|
||||
constr->First % constr->getValue());
|
||||
}
|
||||
else if(constr->FirstPos == Sketcher::PointPos::none){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Distance', %i, %i, %f)") %
|
||||
constr->First % constr->Second % constr->getValue());
|
||||
}
|
||||
else if(constr->SecondPos == Sketcher::PointPos::none){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Distance', %i, %i, %i, %f)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second % constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Distance', %i, %i, %i, %i, %f)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second %
|
||||
static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{ Sketcher::Angle,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
if(constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Angle', %i, %f)") %
|
||||
constr->First % constr->getValue());
|
||||
}
|
||||
else if(constr->SecondPos == Sketcher::PointPos::none){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Angle', %i, %i, %f)") %
|
||||
constr->First % constr->Second % constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Angle', %i, %i, %i, %i, %f)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second %
|
||||
static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{ Sketcher::DistanceX,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
if(constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceX', %i, %f)") %
|
||||
constr->First % constr->getValue());
|
||||
}
|
||||
else if(constr->SecondPos == Sketcher::PointPos::none){
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceX', %i, %i, %f)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceX', %i, %i, %i, %i, %f)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second %
|
||||
static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{ Sketcher::DistanceY,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
if(constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceY', %i, %f)") %
|
||||
constr->First % constr->getValue());
|
||||
}
|
||||
else if(constr->SecondPos == Sketcher::PointPos::none){
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceY', %i, %i, %f)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceY', %i, %i, %i, %i, %f)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second %
|
||||
static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{ Sketcher::Radius,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Radius', %i, %f)") %
|
||||
constr->First % constr->getValue());
|
||||
}},
|
||||
{ Sketcher::Diameter,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Diameter', %i, %f)") %
|
||||
constr->First % constr->getValue());
|
||||
}},
|
||||
{ Sketcher::Weight,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
return boost::str(boost::format("Sketcher.Constraint('Weight', %i, %f)") %
|
||||
constr->First % constr->getValue());
|
||||
}},
|
||||
{ Sketcher::PointOnObject,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
return boost::str(boost::format("Sketcher.Constraint('PointOnObject', %i, %i, %i)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second);
|
||||
}},
|
||||
{ Sketcher::Symmetric,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
if(constr->ThirdPos==Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Symmetric', %i, %i, %i, %i, %i)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second % static_cast<int>(constr->SecondPos) %
|
||||
constr->Third);
|
||||
}
|
||||
else {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Symmetric', %i, %i, %i, %i, %i, %i)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second % static_cast<int>(constr->SecondPos) %
|
||||
constr->Third % static_cast<int>(constr->ThirdPos));
|
||||
}
|
||||
}},
|
||||
{ Sketcher::SnellsLaw,
|
||||
[](const Sketcher::Constraint * constr){
|
||||
return boost::str(boost::format("Sketcher.Constraint('SnellsLaw', %i, %i, %i, %i, %i, %f)") %
|
||||
constr->First % static_cast<int>(constr->FirstPos) % constr->Second % static_cast<int>(constr->SecondPos) %
|
||||
constr->Third % constr->getValue());
|
||||
}},
|
||||
};
|
||||
THROWM(Base::ValueError,
|
||||
"PythonConverter: Constraint Alignment Type not supported")
|
||||
}},
|
||||
{Sketcher::Distance,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Distance', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
}
|
||||
else if (constr->FirstPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Distance', %i, %i, %f)")
|
||||
% constr->First % constr->Second % constr->getValue());
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Distance', %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Distance', %i, %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{Sketcher::Angle,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Angle', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Angle', %i, %i, %f)")
|
||||
% constr->First % constr->Second % constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Angle', %i, %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{Sketcher::DistanceX,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceX', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceX', %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos)
|
||||
% constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('DistanceX', %i, %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{Sketcher::DistanceY,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceY', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceY', %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos)
|
||||
% constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('DistanceY', %i, %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{Sketcher::Radius,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Radius', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
}},
|
||||
{Sketcher::Diameter,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Diameter', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
}},
|
||||
{Sketcher::Weight,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Weight', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
}},
|
||||
{Sketcher::PointOnObject,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('PointOnObject', %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos)
|
||||
% constr->Second);
|
||||
}},
|
||||
{Sketcher::Symmetric,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
if (constr->ThirdPos == Sketcher::PointPos::none) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Symmetric', %i, %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->Third);
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Symmetric', %i, %i, %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->Third
|
||||
% static_cast<int>(constr->ThirdPos));
|
||||
}
|
||||
}},
|
||||
{Sketcher::SnellsLaw,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('SnellsLaw', %i, %i, %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->Third % constr->getValue());
|
||||
}},
|
||||
};
|
||||
|
||||
auto result = converterMap.find(constraint->Type);
|
||||
|
||||
if( result == converterMap.end())
|
||||
if (result == converterMap.end())
|
||||
THROWM(Base::ValueError, "PythonConverter: Constraint Type not supported")
|
||||
|
||||
auto creator = result->second;
|
||||
|
||||
@@ -24,12 +24,14 @@
|
||||
#ifndef SKETCHER_PythonConverter_H
|
||||
#define SKETCHER_PythonConverter_H
|
||||
|
||||
namespace Part {
|
||||
class Geometry;
|
||||
namespace Part
|
||||
{
|
||||
class Geometry;
|
||||
}
|
||||
|
||||
namespace Sketcher {
|
||||
class Constraint;
|
||||
namespace Sketcher
|
||||
{
|
||||
class Constraint;
|
||||
|
||||
/** @brief Class for generating python code
|
||||
* @details
|
||||
@@ -37,38 +39,38 @@ namespace Sketcher {
|
||||
* create such objects.
|
||||
*/
|
||||
|
||||
class SketcherExport PythonConverter {
|
||||
class SketcherExport PythonConverter
|
||||
{
|
||||
|
||||
class SingleGeometry {
|
||||
class SingleGeometry
|
||||
{
|
||||
public:
|
||||
std::string creation;
|
||||
bool construction;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
explicit PythonConverter() = delete;
|
||||
~PythonConverter() = delete;
|
||||
|
||||
/// Convert a geometry into the string representing the command creating it
|
||||
static std::string convert(const Part::Geometry * geo);
|
||||
static std::string convert(const Part::Geometry* geo);
|
||||
|
||||
/// Convert a vector of geometries into the string representing the command creating them
|
||||
static std::string convert(const std::string & doc, const std::vector<Part::Geometry *> & geos);
|
||||
static std::string convert(const std::string& doc, const std::vector<Part::Geometry*>& geos);
|
||||
|
||||
static std::string convert(const Sketcher::Constraint * constraint);
|
||||
static std::string convert(const Sketcher::Constraint* constraint);
|
||||
|
||||
static std::string convert(const std::string & doc, const std::vector<Sketcher::Constraint *> & constraints);
|
||||
static std::string convert(const std::string& doc,
|
||||
const std::vector<Sketcher::Constraint*>& constraints);
|
||||
|
||||
private:
|
||||
static SingleGeometry process(const Part::Geometry * geo);
|
||||
|
||||
static std::string process(const Sketcher::Constraint * constraint);
|
||||
static SingleGeometry process(const Part::Geometry* geo);
|
||||
|
||||
static std::string process(const Sketcher::Constraint* constraint);
|
||||
};
|
||||
|
||||
} // namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCHER_PythonConverter_H
|
||||
|
||||
#endif// SKETCHER_PythonConverter_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,10 +34,10 @@
|
||||
|
||||
namespace Sketcher
|
||||
{
|
||||
// Forward declarations
|
||||
class SolverGeometryExtension;
|
||||
// Forward declarations
|
||||
class SolverGeometryExtension;
|
||||
|
||||
class SketcherExport Sketch :public Base::Persistence
|
||||
class SketcherExport Sketch: public Base::Persistence
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
@@ -47,52 +47,56 @@ public:
|
||||
|
||||
// from base class
|
||||
unsigned int getMemSize() const override;
|
||||
void Save(Base::Writer &/*writer*/) const override;
|
||||
void Restore(Base::XMLReader &/*reader*/) override;
|
||||
void Save(Base::Writer& /*writer*/) const override;
|
||||
void Restore(Base::XMLReader& /*reader*/) override;
|
||||
|
||||
/// solve the actual set up sketch
|
||||
int solve();
|
||||
/// resets the solver
|
||||
int resetSolver();
|
||||
/// get standard (aka fine) solver precision
|
||||
double getSolverPrecision(){ return GCSsys.getFinePrecision(); }
|
||||
double getSolverPrecision()
|
||||
{
|
||||
return GCSsys.getFinePrecision();
|
||||
}
|
||||
/// delete all geometry and constraints, leave an empty sketch
|
||||
void clear();
|
||||
/** set the sketch up with geoms and constraints
|
||||
*
|
||||
* returns the degree of freedom of a sketch and calculates a list of
|
||||
* conflicting constraints
|
||||
*
|
||||
* 0 degrees of freedom correspond to a fully constrained sketch
|
||||
* -1 degrees of freedom correspond to an over-constrained sketch
|
||||
* positive degrees of freedom correspond to an under-constrained sketch
|
||||
*
|
||||
* an over-constrained sketch will always contain conflicting constraints
|
||||
* a fully constrained or under-constrained sketch may contain conflicting
|
||||
* constraints or may not
|
||||
*/
|
||||
int setUpSketch(const std::vector<Part::Geometry *> &GeoList, const std::vector<Constraint *> &ConstraintList,
|
||||
int extGeoCount=0);
|
||||
*
|
||||
* returns the degree of freedom of a sketch and calculates a list of
|
||||
* conflicting constraints
|
||||
*
|
||||
* 0 degrees of freedom correspond to a fully constrained sketch
|
||||
* -1 degrees of freedom correspond to an over-constrained sketch
|
||||
* positive degrees of freedom correspond to an under-constrained sketch
|
||||
*
|
||||
* an over-constrained sketch will always contain conflicting constraints
|
||||
* a fully constrained or under-constrained sketch may contain conflicting
|
||||
* constraints or may not
|
||||
*/
|
||||
int setUpSketch(const std::vector<Part::Geometry*>& GeoList,
|
||||
const std::vector<Constraint*>& ConstraintList, int extGeoCount = 0);
|
||||
/// return the actual geometry of the sketch a TopoShape
|
||||
Part::TopoShape toShape() const;
|
||||
/// add unspecified geometry
|
||||
int addGeometry(const Part::Geometry *geo, bool fixed=false);
|
||||
int addGeometry(const Part::Geometry* geo, bool fixed = false);
|
||||
/// add unspecified geometry
|
||||
int addGeometry(const std::vector<Part::Geometry *> &geo, bool fixed=false);
|
||||
/// add unspecified geometry, where each element's "fixed" status is given by the blockedGeometry array
|
||||
int addGeometry(const std::vector<Part::Geometry *> &geo,
|
||||
const std::vector<bool> &blockedGeometry);
|
||||
int addGeometry(const std::vector<Part::Geometry*>& geo, bool fixed = false);
|
||||
/// add unspecified geometry, where each element's "fixed" status is given by the
|
||||
/// blockedGeometry array
|
||||
int addGeometry(const std::vector<Part::Geometry*>& geo,
|
||||
const std::vector<bool>& blockedGeometry);
|
||||
/// get boolean list indicating whether the geometry is to be blocked or not
|
||||
void getBlockedGeometry(std::vector<bool> & blockedGeometry,
|
||||
std::vector<bool> & unenforceableConstraints,
|
||||
const std::vector<Constraint *> &ConstraintList) const;
|
||||
void getBlockedGeometry(std::vector<bool>& blockedGeometry,
|
||||
std::vector<bool>& unenforceableConstraints,
|
||||
const std::vector<Constraint*>& ConstraintList) const;
|
||||
/// returns the actual geometry
|
||||
std::vector<Part::Geometry *> extractGeometry(bool withConstructionElements=true,
|
||||
bool withExternalElements=false) const;
|
||||
std::vector<Part::Geometry*> extractGeometry(bool withConstructionElements = true,
|
||||
bool withExternalElements = false) const;
|
||||
|
||||
GeoListFacade extractGeoListFacade() const;
|
||||
|
||||
void updateExtension(int geoId, std::unique_ptr<Part::GeometryExtension> && ext);
|
||||
void updateExtension(int geoId, std::unique_ptr<Part::GeometryExtension>&& ext);
|
||||
/// get the geometry as python objects
|
||||
Py::Tuple getPyGeometry() const;
|
||||
|
||||
@@ -102,39 +106,67 @@ public:
|
||||
Base::Vector3d getPoint(int geoId, PointPos pos) const;
|
||||
|
||||
// Inline methods
|
||||
inline bool hasConflicts() const { return !Conflicting.empty(); }
|
||||
inline const std::vector<int> &getConflicting() const { return Conflicting; }
|
||||
inline bool hasRedundancies() const { return !Redundant.empty(); }
|
||||
inline const std::vector<int> &getRedundant() const { return Redundant; }
|
||||
inline bool hasPartialRedundancies() const { return !PartiallyRedundant.empty(); }
|
||||
inline const std::vector<int> &getPartiallyRedundant() const { return PartiallyRedundant; }
|
||||
inline bool hasConflicts() const
|
||||
{
|
||||
return !Conflicting.empty();
|
||||
}
|
||||
inline const std::vector<int>& getConflicting() const
|
||||
{
|
||||
return Conflicting;
|
||||
}
|
||||
inline bool hasRedundancies() const
|
||||
{
|
||||
return !Redundant.empty();
|
||||
}
|
||||
inline const std::vector<int>& getRedundant() const
|
||||
{
|
||||
return Redundant;
|
||||
}
|
||||
inline bool hasPartialRedundancies() const
|
||||
{
|
||||
return !PartiallyRedundant.empty();
|
||||
}
|
||||
inline const std::vector<int>& getPartiallyRedundant() const
|
||||
{
|
||||
return PartiallyRedundant;
|
||||
}
|
||||
|
||||
inline float getSolveTime() const { return SolveTime; }
|
||||
inline float getSolveTime() const
|
||||
{
|
||||
return SolveTime;
|
||||
}
|
||||
|
||||
inline bool hasMalformedConstraints() const
|
||||
{
|
||||
return !MalformedConstraints.empty();
|
||||
}
|
||||
inline const std::vector<int>& getMalformedConstraints() const
|
||||
{
|
||||
return MalformedConstraints;
|
||||
}
|
||||
|
||||
inline bool hasMalformedConstraints() const { return !MalformedConstraints.empty(); }
|
||||
inline const std::vector<int> &getMalformedConstraints() const { return MalformedConstraints; }
|
||||
public:
|
||||
std::set < std::pair< int, Sketcher::PointPos>> getDependencyGroup(int geoId, PointPos pos) const;
|
||||
std::set<std::pair<int, Sketcher::PointPos>> getDependencyGroup(int geoId, PointPos pos) const;
|
||||
|
||||
std::shared_ptr<SolverGeometryExtension> getSolverExtension(int geoId) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/** set the datum of a distance or angle constraint to a certain value and solve
|
||||
* This can cause the solving to fail!
|
||||
*/
|
||||
* This can cause the solving to fail!
|
||||
*/
|
||||
int setDatum(int constrId, double value);
|
||||
|
||||
/** initializes a point (or curve) drag by setting the current
|
||||
* sketch status as a reference
|
||||
*/
|
||||
int initMove(int geoId, PointPos pos, bool fine=true);
|
||||
* sketch status as a reference
|
||||
*/
|
||||
int initMove(int geoId, PointPos pos, bool fine = true);
|
||||
|
||||
/** Initializes a B-spline piece drag by setting the current
|
||||
* sketch status as a reference. Only moves piece around `firstPoint`.
|
||||
*/
|
||||
int initBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint, bool fine=true);
|
||||
* sketch status as a reference. Only moves piece around `firstPoint`.
|
||||
*/
|
||||
int initBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint,
|
||||
bool fine = true);
|
||||
|
||||
/** Resets the initialization of a point or curve drag
|
||||
*/
|
||||
@@ -145,105 +177,112 @@ public:
|
||||
int limitBSplineMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint);
|
||||
|
||||
/** move this point (or curve) to a new location and solve.
|
||||
* This will introduce some additional weak constraints expressing
|
||||
* a condition for satisfying the new point location!
|
||||
* The relative flag permits moving relatively to the current position
|
||||
*/
|
||||
int movePoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool relative=false);
|
||||
* This will introduce some additional weak constraints expressing
|
||||
* a condition for satisfying the new point location!
|
||||
* The relative flag permits moving relatively to the current position
|
||||
*/
|
||||
int movePoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool relative = false);
|
||||
|
||||
/**
|
||||
* Sets whether the initial solution should be recalculated while dragging after a certain distance from the previous drag point
|
||||
* for smoother dragging operation.
|
||||
* Sets whether the initial solution should be recalculated while dragging after a certain
|
||||
* distance from the previous drag point for smoother dragging operation.
|
||||
*/
|
||||
bool getRecalculateInitialSolutionWhileMovingPoint() const
|
||||
{return RecalculateInitialSolutionWhileMovingPoint;}
|
||||
{
|
||||
return RecalculateInitialSolutionWhileMovingPoint;
|
||||
}
|
||||
|
||||
void setRecalculateInitialSolutionWhileMovingPoint(bool recalculateInitialSolutionWhileMovingPoint)
|
||||
{RecalculateInitialSolutionWhileMovingPoint = recalculateInitialSolutionWhileMovingPoint;}
|
||||
void
|
||||
setRecalculateInitialSolutionWhileMovingPoint(bool recalculateInitialSolutionWhileMovingPoint)
|
||||
{
|
||||
RecalculateInitialSolutionWhileMovingPoint = recalculateInitialSolutionWhileMovingPoint;
|
||||
}
|
||||
|
||||
/// add dedicated geometry
|
||||
//@{
|
||||
/// add a point
|
||||
int addPoint(const Part::GeomPoint &point, bool fixed=false);
|
||||
int addPoint(const Part::GeomPoint& point, bool fixed = false);
|
||||
/// add an infinite line
|
||||
int addLine(const Part::GeomLineSegment &line, bool fixed=false);
|
||||
int addLine(const Part::GeomLineSegment& line, bool fixed = false);
|
||||
/// add a line segment
|
||||
int addLineSegment(const Part::GeomLineSegment &lineSegment, bool fixed=false);
|
||||
int addLineSegment(const Part::GeomLineSegment& lineSegment, bool fixed = false);
|
||||
/// add a arc (circle segment)
|
||||
int addArc(const Part::GeomArcOfCircle &circleSegment, bool fixed=false);
|
||||
int addArc(const Part::GeomArcOfCircle& circleSegment, bool fixed = false);
|
||||
/// add a circle
|
||||
int addCircle(const Part::GeomCircle &circle, bool fixed=false);
|
||||
int addCircle(const Part::GeomCircle& circle, bool fixed = false);
|
||||
/// add an ellipse
|
||||
int addEllipse(const Part::GeomEllipse &ellipse, bool fixed=false);
|
||||
int addEllipse(const Part::GeomEllipse& ellipse, bool fixed = false);
|
||||
/// add an arc of ellipse
|
||||
int addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool fixed=false);
|
||||
int addArcOfEllipse(const Part::GeomArcOfEllipse& ellipseSegment, bool fixed = false);
|
||||
/// add an arc of hyperbola
|
||||
int addArcOfHyperbola(const Part::GeomArcOfHyperbola &hyperbolaSegment, bool fixed=false);
|
||||
int addArcOfHyperbola(const Part::GeomArcOfHyperbola& hyperbolaSegment, bool fixed = false);
|
||||
/// add an arc of parabola
|
||||
int addArcOfParabola(const Part::GeomArcOfParabola ¶bolaSegment, bool fixed=false);
|
||||
int addArcOfParabola(const Part::GeomArcOfParabola& parabolaSegment, bool fixed = false);
|
||||
/// add a BSpline
|
||||
int addBSpline(const Part::GeomBSplineCurve &spline, bool fixed=false);
|
||||
int addBSpline(const Part::GeomBSplineCurve& spline, bool fixed = false);
|
||||
//@}
|
||||
|
||||
|
||||
/// constraints
|
||||
//@{
|
||||
/// add all constraints in the list
|
||||
int addConstraints(const std::vector<Constraint *> &ConstraintList);
|
||||
int addConstraints(const std::vector<Constraint*>& ConstraintList);
|
||||
/// add all constraints in the list, provided that are enforceable
|
||||
int addConstraints(const std::vector<Constraint *> &ConstraintList,
|
||||
const std::vector<bool> & unenforceableConstraints);
|
||||
int addConstraints(const std::vector<Constraint*>& ConstraintList,
|
||||
const std::vector<bool>& unenforceableConstraints);
|
||||
/// add one constraint to the sketch
|
||||
int addConstraint(const Constraint *constraint);
|
||||
int addConstraint(const Constraint* constraint);
|
||||
|
||||
/**
|
||||
* add a fixed X coordinate constraint to a point
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addCoordinateXConstraint(int geoId, PointPos pos, double * value, bool driving = true);
|
||||
* add a fixed X coordinate constraint to a point
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addCoordinateXConstraint(int geoId, PointPos pos, double* value, bool driving = true);
|
||||
/**
|
||||
* add a fixed Y coordinate constraint to a point
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addCoordinateYConstraint(int geoId, PointPos pos, double * value, bool driving = true);
|
||||
* add a fixed Y coordinate constraint to a point
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addCoordinateYConstraint(int geoId, PointPos pos, double* value, bool driving = true);
|
||||
/**
|
||||
* add a horizontal distance constraint to two points or line ends
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceXConstraint(int geoId, double * value, bool driving = true);
|
||||
* add a horizontal distance constraint to two points or line ends
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceXConstraint(int geoId, double* value, bool driving = true);
|
||||
/**
|
||||
* add a horizontal distance constraint to two points or line ends
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceXConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double * value, bool driving = true);
|
||||
* add a horizontal distance constraint to two points or line ends
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceXConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double* value,
|
||||
bool driving = true);
|
||||
/**
|
||||
* add a vertical distance constraint to two points or line ends
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceYConstraint(int geoId, double * value, bool driving = true);
|
||||
* add a vertical distance constraint to two points or line ends
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceYConstraint(int geoId, double* value, bool driving = true);
|
||||
/**
|
||||
* add a vertical distance constraint to two points or line ends
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceYConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double * value, bool driving = true);
|
||||
* add a vertical distance constraint to two points or line ends
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceYConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double* value,
|
||||
bool driving = true);
|
||||
/// add a horizontal constraint to a geometry
|
||||
int addHorizontalConstraint(int geoId);
|
||||
int addHorizontalConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2);
|
||||
@@ -253,37 +292,39 @@ public:
|
||||
/// add a coincident constraint to two points of two geometries
|
||||
int addPointCoincidentConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2);
|
||||
/**
|
||||
* add a length or distance constraint
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceConstraint(int geoId1, double * value, bool driving = true);
|
||||
* add a length or distance constraint
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceConstraint(int geoId1, double* value, bool driving = true);
|
||||
/**
|
||||
* add a length or distance constraint
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, double * value, bool driving = true);
|
||||
* add a length or distance constraint
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, double* value,
|
||||
bool driving = true);
|
||||
/**
|
||||
* add a length or distance constraint
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double * value, bool driving = true);
|
||||
* add a length or distance constraint
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double* value,
|
||||
bool driving = true);
|
||||
/**
|
||||
* add a length or distance constraint
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceConstraint(int geoId1, int geoId2, double * value, bool driving = true);
|
||||
* add a length or distance constraint
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDistanceConstraint(int geoId1, int geoId2, double* value, bool driving = true);
|
||||
|
||||
/// add a parallel constraint between two lines
|
||||
int addParallelConstraint(int geoId1, int geoId2);
|
||||
@@ -291,22 +332,14 @@ public:
|
||||
int addPerpendicularConstraint(int geoId1, int geoId2);
|
||||
/// add a tangency constraint between two geometries
|
||||
int addTangentConstraint(int geoId1, int geoId2);
|
||||
int addTangentLineAtBSplineKnotConstraint(int checkedlinegeoId, int checkedbsplinegeoId, int checkedknotgeoid);
|
||||
int addTangentLineEndpointAtBSplineKnotConstraint(int checkedlinegeoId, PointPos endpointPos, int checkedbsplinegeoId, int checkedknotgeoid);
|
||||
int addAngleAtPointConstraint(
|
||||
int geoId1, PointPos pos1,
|
||||
int geoId2, PointPos pos2,
|
||||
int geoId3, PointPos pos3,
|
||||
double * value,
|
||||
ConstraintType cTyp, bool driving = true);
|
||||
/**
|
||||
* add a radius constraint on a circle or an arc
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addRadiusConstraint(int geoId, double * value, bool driving = true);
|
||||
int addTangentLineAtBSplineKnotConstraint(int checkedlinegeoId, int checkedbsplinegeoId,
|
||||
int checkedknotgeoid);
|
||||
int addTangentLineEndpointAtBSplineKnotConstraint(int checkedlinegeoId, PointPos endpointPos,
|
||||
int checkedbsplinegeoId,
|
||||
int checkedknotgeoid);
|
||||
int addAngleAtPointConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, int geoId3,
|
||||
PointPos pos3, double* value, ConstraintType cTyp,
|
||||
bool driving = true);
|
||||
/**
|
||||
* add a radius constraint on a circle or an arc
|
||||
*
|
||||
@@ -314,65 +347,75 @@ public:
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDiameterConstraint(int geoId, double * value, bool driving = true);
|
||||
int addRadiusConstraint(int geoId, double* value, bool driving = true);
|
||||
/**
|
||||
* add an angle constraint on a line or between two lines
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addAngleConstraint(int geoId, double * value, bool driving = true);
|
||||
* add a radius constraint on a circle or an arc
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addDiameterConstraint(int geoId, double* value, bool driving = true);
|
||||
/**
|
||||
* add an angle constraint on a line or between two lines
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addAngleConstraint(int geoId1, int geoId2, double * value, bool driving = true);
|
||||
* add an angle constraint on a line or between two lines
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addAngleConstraint(int geoId, double* value, bool driving = true);
|
||||
/**
|
||||
* add an angle constraint on a line or between two lines
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addAngleConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double * value, bool driving = true);
|
||||
* add an angle constraint on a line or between two lines
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addAngleConstraint(int geoId1, int geoId2, double* value, bool driving = true);
|
||||
/**
|
||||
* add angle-via-point constraint between any two curves
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addAngleViaPointConstraint(int geoId1, int geoId2, int geoId3, PointPos pos3, double value, bool driving = true);
|
||||
* add an angle constraint on a line or between two lines
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addAngleConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double* value,
|
||||
bool driving = true);
|
||||
/**
|
||||
* add angle-via-point constraint between any two curves
|
||||
*
|
||||
* double * value is a pointer to double allocated in the heap, containing the
|
||||
* constraint value and already inserted into either the FixParameters or
|
||||
* Parameters array, as the case may be.
|
||||
*/
|
||||
int addAngleViaPointConstraint(int geoId1, int geoId2, int geoId3, PointPos pos3, double value,
|
||||
bool driving = true);
|
||||
/// add an equal length or radius constraints between two lines or between circles and arcs
|
||||
int addEqualConstraint(int geoId1, int geoId2);
|
||||
/// add a point on line constraint
|
||||
int addPointOnObjectConstraint(int geoId1, PointPos pos1, int geoId2, bool driving = true);
|
||||
/// add a point on B-spline constraint: needs a parameter
|
||||
int addPointOnObjectConstraint(int geoId1, PointPos pos1, int geoId2,double* pointparam, bool driving = true);
|
||||
int addPointOnObjectConstraint(int geoId1, PointPos pos1, int geoId2, double* pointparam,
|
||||
bool driving = true);
|
||||
/// add a symmetric constraint between two points with respect to a line
|
||||
int addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, int geoId3);
|
||||
/// add a symmetric constraint between three points, the last point is in the middle of the first two
|
||||
int addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, int geoId3, PointPos pos3);
|
||||
/// add a symmetric constraint between three points, the last point is in the middle of the
|
||||
/// first two
|
||||
int addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, int geoId3,
|
||||
PointPos pos3);
|
||||
/**
|
||||
* add a snell's law constraint
|
||||
*
|
||||
* double * value and double * second are each a pointer to double
|
||||
* allocated in the heap and already inserted into either the
|
||||
* FixParameters or Parameters array, as the case may be.
|
||||
*
|
||||
* value must contain the constraint value (the ratio of n2/n1)
|
||||
* second may be initialized to any value, however the solver will
|
||||
* provide n1 in value and n2 in second.
|
||||
*/
|
||||
int addSnellsLawConstraint(int geoIdRay1, PointPos posRay1,
|
||||
int geoIdRay2, PointPos posRay2,
|
||||
int geoIdBnd,
|
||||
double * value,
|
||||
double * second, bool driving = true);
|
||||
* add a snell's law constraint
|
||||
*
|
||||
* double * value and double * second are each a pointer to double
|
||||
* allocated in the heap and already inserted into either the
|
||||
* FixParameters or Parameters array, as the case may be.
|
||||
*
|
||||
* value must contain the constraint value (the ratio of n2/n1)
|
||||
* second may be initialized to any value, however the solver will
|
||||
* provide n1 in value and n2 in second.
|
||||
*/
|
||||
int addSnellsLawConstraint(int geoIdRay1, PointPos posRay1, int geoIdRay2, PointPos posRay2,
|
||||
int geoIdBnd, double* value, double* second, bool driving = true);
|
||||
//@}
|
||||
|
||||
/// Internal Alignment constraints
|
||||
@@ -392,29 +435,37 @@ public:
|
||||
int addInternalAlignmentKnotPoint(int geoId1, int geoId2, int knotindex);
|
||||
//@}
|
||||
public:
|
||||
//This func is to be used during angle-via-point constraint creation. It calculates
|
||||
//the angle between geoId1,geoId2 at point px,py. The point should be on both curves,
|
||||
//otherwise the result will be systematically off (but smoothly approach the correct
|
||||
//value as the point approaches intersection of curves).
|
||||
double calculateAngleViaPoint(int geoId1, int geoId2, double px, double py );
|
||||
// This func is to be used during angle-via-point constraint creation. It calculates
|
||||
// the angle between geoId1,geoId2 at point px,py. The point should be on both curves,
|
||||
// otherwise the result will be systematically off (but smoothly approach the correct
|
||||
// value as the point approaches intersection of curves).
|
||||
double calculateAngleViaPoint(int geoId1, int geoId2, double px, double py);
|
||||
|
||||
//This is to be used for rendering of angle-via-point constraint.
|
||||
// This is to be used for rendering of angle-via-point constraint.
|
||||
Base::Vector3d calculateNormalAtPoint(int geoIdCurve, double px, double py) const;
|
||||
|
||||
//icstr should be the value returned by addXXXXConstraint
|
||||
//see more info in respective function in GCS.
|
||||
double calculateConstraintError(int icstr) { return GCSsys.calculateConstraintErrorByTag(icstr);}
|
||||
// icstr should be the value returned by addXXXXConstraint
|
||||
// see more info in respective function in GCS.
|
||||
double calculateConstraintError(int icstr)
|
||||
{
|
||||
return GCSsys.calculateConstraintErrorByTag(icstr);
|
||||
}
|
||||
|
||||
/// Returns the size of the Geometry
|
||||
int getGeometrySize() const {return Geoms.size();}
|
||||
int getGeometrySize() const
|
||||
{
|
||||
return Geoms.size();
|
||||
}
|
||||
|
||||
enum GeoType {
|
||||
None = 0,
|
||||
Point = 1, // 1 Point(start), 2 Parameters(x,y)
|
||||
Line = 2, // 2 Points(start,end), 4 Parameters(x1,y1,x2,y2)
|
||||
Arc = 3, // 3 Points(start,end,mid), (4)+5 Parameters((x1,y1,x2,y2),x,y,r,a1,a2)
|
||||
Circle = 4, // 1 Point(mid), 3 Parameters(x,y,r)
|
||||
Ellipse = 5, // 1 Point(mid), 5 Parameters(x,y,r1,r2,phi) phi=angle xaxis of ellipse with respect of sketch xaxis
|
||||
enum GeoType
|
||||
{
|
||||
None = 0,
|
||||
Point = 1, // 1 Point(start), 2 Parameters(x,y)
|
||||
Line = 2, // 2 Points(start,end), 4 Parameters(x1,y1,x2,y2)
|
||||
Arc = 3, // 3 Points(start,end,mid), (4)+5 Parameters((x1,y1,x2,y2),x,y,r,a1,a2)
|
||||
Circle = 4, // 1 Point(mid), 3 Parameters(x,y,r)
|
||||
Ellipse = 5,// 1 Point(mid), 5 Parameters(x,y,r1,r2,phi)
|
||||
// phi=angle xaxis of ellipse with respect of sketch xaxis
|
||||
ArcOfEllipse = 6,
|
||||
ArcOfHyperbola = 7,
|
||||
ArcOfParabola = 8,
|
||||
@@ -425,33 +476,45 @@ protected:
|
||||
float SolveTime;
|
||||
bool RecalculateInitialSolutionWhileMovingPoint;
|
||||
|
||||
// regulates a second solve for cases where there result of having update the geometry (e.g. via OCCT)
|
||||
// needs to be taken into account by the solver (for example to provide the right value of non-driving constraints)
|
||||
// regulates a second solve for cases where there result of having update the geometry (e.g. via
|
||||
// OCCT) needs to be taken into account by the solver (for example to provide the right value of
|
||||
// non-driving constraints)
|
||||
bool resolveAfterGeometryUpdated;
|
||||
|
||||
protected:
|
||||
/// container element to store and work with the geometric elements of this sketch
|
||||
struct GeoDef {
|
||||
GeoDef() : geo(nullptr),type(None),external(false),index(-1),
|
||||
startPointId(-1),midPointId(-1),endPointId(-1) {}
|
||||
Part::Geometry * geo; // pointer to the geometry
|
||||
GeoType type; // type of the geometry
|
||||
bool external; // flag for external geometries
|
||||
int index; // index in the corresponding storage vector (Lines, Arcs, Circles, ...)
|
||||
int startPointId; // index in Points of the start point of this geometry
|
||||
int midPointId; // index in Points of the start point of this geometry
|
||||
int endPointId; // index in Points of the end point of this geometry
|
||||
struct GeoDef
|
||||
{
|
||||
GeoDef()
|
||||
: geo(nullptr),
|
||||
type(None),
|
||||
external(false),
|
||||
index(-1),
|
||||
startPointId(-1),
|
||||
midPointId(-1),
|
||||
endPointId(-1)
|
||||
{}
|
||||
Part::Geometry* geo;// pointer to the geometry
|
||||
GeoType type; // type of the geometry
|
||||
bool external; // flag for external geometries
|
||||
int index; // index in the corresponding storage vector (Lines, Arcs, Circles, ...)
|
||||
int startPointId; // index in Points of the start point of this geometry
|
||||
int midPointId; // index in Points of the start point of this geometry
|
||||
int endPointId; // index in Points of the end point of this geometry
|
||||
};
|
||||
/// container element to store and work with the constraints of this sketch
|
||||
struct ConstrDef {
|
||||
ConstrDef() : constr(nullptr)
|
||||
, driving(true)
|
||||
, value(nullptr)
|
||||
, secondvalue(nullptr) {}
|
||||
Constraint * constr; // pointer to the constraint
|
||||
bool driving;
|
||||
double * value;
|
||||
double * secondvalue; // this is needed for SnellsLaw
|
||||
struct ConstrDef
|
||||
{
|
||||
ConstrDef()
|
||||
: constr(nullptr),
|
||||
driving(true),
|
||||
value(nullptr),
|
||||
secondvalue(nullptr)
|
||||
{}
|
||||
Constraint* constr;// pointer to the constraint
|
||||
bool driving;
|
||||
double* value;
|
||||
double* secondvalue;// this is needed for SnellsLaw
|
||||
};
|
||||
|
||||
std::vector<GeoDef> Geoms;
|
||||
@@ -463,27 +526,30 @@ protected:
|
||||
std::vector<int> PartiallyRedundant;
|
||||
std::vector<int> MalformedConstraints;
|
||||
|
||||
std::vector<double *> pDependentParametersList;
|
||||
std::vector<double*> pDependentParametersList;
|
||||
|
||||
// map of geoIds to corresponding solverextensions. This is useful when solved geometry is NOT to be assigned to the SketchObject
|
||||
// map of geoIds to corresponding solverextensions. This is useful when solved geometry is NOT
|
||||
// to be assigned to the SketchObject
|
||||
std::vector<std::shared_ptr<SolverGeometryExtension>> solverExtensions;
|
||||
|
||||
// maps a geoid corresponding to an internalgeometry (focus,knot,pole) to the geometry it defines (ellipse, hyperbola, B-Spline)
|
||||
std::map< int, int > internalAlignmentGeometryMap;
|
||||
// maps a geoid corresponding to an internalgeometry (focus,knot,pole) to the geometry it
|
||||
// defines (ellipse, hyperbola, B-Spline)
|
||||
std::map<int, int> internalAlignmentGeometryMap;
|
||||
|
||||
std::vector < std::set < std::pair< int, Sketcher::PointPos>>> pDependencyGroups;
|
||||
std::vector<std::set<std::pair<int, Sketcher::PointPos>>> pDependencyGroups;
|
||||
|
||||
// this map is intended to convert a parameter (double *) into a GeoId/PointPos and parameter number
|
||||
std::map<double *, std::tuple<int, Sketcher::PointPos, int>> param2geoelement;
|
||||
// this map is intended to convert a parameter (double *) into a GeoId/PointPos and parameter
|
||||
// number
|
||||
std::map<double*, std::tuple<int, Sketcher::PointPos, int>> param2geoelement;
|
||||
|
||||
// solving parameters
|
||||
std::vector<double*> Parameters; // with memory allocation
|
||||
std::vector<double*> DrivenParameters; // with memory allocation
|
||||
std::vector<double*> FixParameters; // with memory allocation
|
||||
std::vector<double*> Parameters; // with memory allocation
|
||||
std::vector<double*> DrivenParameters;// with memory allocation
|
||||
std::vector<double*> FixParameters; // with memory allocation
|
||||
std::vector<double> MoveParameters, InitParameters;
|
||||
std::vector<GCS::Point> Points;
|
||||
std::vector<GCS::Line> Lines;
|
||||
std::vector<GCS::Arc> Arcs;
|
||||
std::vector<GCS::Point> Points;
|
||||
std::vector<GCS::Line> Lines;
|
||||
std::vector<GCS::Arc> Arcs;
|
||||
std::vector<GCS::Circle> Circles;
|
||||
std::vector<GCS::Ellipse> Ellipses;
|
||||
std::vector<GCS::ArcOfEllipse> ArcsOfEllipse;
|
||||
@@ -499,36 +565,108 @@ protected:
|
||||
public:
|
||||
GCS::Algorithm defaultSolver;
|
||||
GCS::Algorithm defaultSolverRedundant;
|
||||
inline void setDogLegGaussStep(GCS::DogLegGaussStep mode){GCSsys.dogLegGaussStep=mode;}
|
||||
inline void setDebugMode(GCS::DebugMode mode) {debugMode=mode;GCSsys.debugMode=mode;}
|
||||
inline GCS::DebugMode getDebugMode() {return debugMode;}
|
||||
inline void setMaxIter(int maxiter){GCSsys.maxIter=maxiter;}
|
||||
inline void setMaxIterRedundant(int maxiter){GCSsys.maxIterRedundant=maxiter;}
|
||||
inline void setSketchSizeMultiplier(bool mult){GCSsys.sketchSizeMultiplier=mult;}
|
||||
inline void setSketchSizeMultiplierRedundant(bool mult){GCSsys.sketchSizeMultiplierRedundant=mult;}
|
||||
inline void setConvergence(double conv){GCSsys.convergence=conv;}
|
||||
inline void setConvergenceRedundant(double conv){GCSsys.convergenceRedundant=conv;}
|
||||
inline void setQRAlgorithm(GCS::QRAlgorithm alg){GCSsys.qrAlgorithm=alg;}
|
||||
inline GCS::QRAlgorithm getQRAlgorithm(){return GCSsys.qrAlgorithm;}
|
||||
inline void setQRPivotThreshold(double val){GCSsys.qrpivotThreshold=val;}
|
||||
inline void setLM_eps(double val){GCSsys.LM_eps=val;}
|
||||
inline void setLM_eps1(double val){GCSsys.LM_eps1=val;}
|
||||
inline void setLM_tau(double val){GCSsys.LM_tau=val;}
|
||||
inline void setDL_tolg(double val){GCSsys.DL_tolg=val;}
|
||||
inline void setDL_tolx(double val){GCSsys.DL_tolx=val;}
|
||||
inline void setDL_tolf(double val){GCSsys.DL_tolf=val;}
|
||||
inline void setLM_epsRedundant(double val){GCSsys.LM_epsRedundant=val;}
|
||||
inline void setLM_eps1Redundant(double val){GCSsys.LM_eps1Redundant=val;}
|
||||
inline void setLM_tauRedundant(double val){GCSsys.LM_tauRedundant=val;}
|
||||
inline void setDL_tolgRedundant(double val){GCSsys.DL_tolgRedundant=val;}
|
||||
inline void setDL_tolxRedundant(double val){GCSsys.DL_tolxRedundant=val;}
|
||||
inline void setDL_tolfRedundant(double val){GCSsys.DL_tolfRedundant=val;}
|
||||
inline void setDogLegGaussStep(GCS::DogLegGaussStep mode)
|
||||
{
|
||||
GCSsys.dogLegGaussStep = mode;
|
||||
}
|
||||
inline void setDebugMode(GCS::DebugMode mode)
|
||||
{
|
||||
debugMode = mode;
|
||||
GCSsys.debugMode = mode;
|
||||
}
|
||||
inline GCS::DebugMode getDebugMode()
|
||||
{
|
||||
return debugMode;
|
||||
}
|
||||
inline void setMaxIter(int maxiter)
|
||||
{
|
||||
GCSsys.maxIter = maxiter;
|
||||
}
|
||||
inline void setMaxIterRedundant(int maxiter)
|
||||
{
|
||||
GCSsys.maxIterRedundant = maxiter;
|
||||
}
|
||||
inline void setSketchSizeMultiplier(bool mult)
|
||||
{
|
||||
GCSsys.sketchSizeMultiplier = mult;
|
||||
}
|
||||
inline void setSketchSizeMultiplierRedundant(bool mult)
|
||||
{
|
||||
GCSsys.sketchSizeMultiplierRedundant = mult;
|
||||
}
|
||||
inline void setConvergence(double conv)
|
||||
{
|
||||
GCSsys.convergence = conv;
|
||||
}
|
||||
inline void setConvergenceRedundant(double conv)
|
||||
{
|
||||
GCSsys.convergenceRedundant = conv;
|
||||
}
|
||||
inline void setQRAlgorithm(GCS::QRAlgorithm alg)
|
||||
{
|
||||
GCSsys.qrAlgorithm = alg;
|
||||
}
|
||||
inline GCS::QRAlgorithm getQRAlgorithm()
|
||||
{
|
||||
return GCSsys.qrAlgorithm;
|
||||
}
|
||||
inline void setQRPivotThreshold(double val)
|
||||
{
|
||||
GCSsys.qrpivotThreshold = val;
|
||||
}
|
||||
inline void setLM_eps(double val)
|
||||
{
|
||||
GCSsys.LM_eps = val;
|
||||
}
|
||||
inline void setLM_eps1(double val)
|
||||
{
|
||||
GCSsys.LM_eps1 = val;
|
||||
}
|
||||
inline void setLM_tau(double val)
|
||||
{
|
||||
GCSsys.LM_tau = val;
|
||||
}
|
||||
inline void setDL_tolg(double val)
|
||||
{
|
||||
GCSsys.DL_tolg = val;
|
||||
}
|
||||
inline void setDL_tolx(double val)
|
||||
{
|
||||
GCSsys.DL_tolx = val;
|
||||
}
|
||||
inline void setDL_tolf(double val)
|
||||
{
|
||||
GCSsys.DL_tolf = val;
|
||||
}
|
||||
inline void setLM_epsRedundant(double val)
|
||||
{
|
||||
GCSsys.LM_epsRedundant = val;
|
||||
}
|
||||
inline void setLM_eps1Redundant(double val)
|
||||
{
|
||||
GCSsys.LM_eps1Redundant = val;
|
||||
}
|
||||
inline void setLM_tauRedundant(double val)
|
||||
{
|
||||
GCSsys.LM_tauRedundant = val;
|
||||
}
|
||||
inline void setDL_tolgRedundant(double val)
|
||||
{
|
||||
GCSsys.DL_tolgRedundant = val;
|
||||
}
|
||||
inline void setDL_tolxRedundant(double val)
|
||||
{
|
||||
GCSsys.DL_tolxRedundant = val;
|
||||
}
|
||||
inline void setDL_tolfRedundant(double val)
|
||||
{
|
||||
GCSsys.DL_tolfRedundant = val;
|
||||
}
|
||||
|
||||
protected:
|
||||
GCS::DebugMode debugMode;
|
||||
|
||||
private:
|
||||
|
||||
bool updateGeometry();
|
||||
bool updateNonDrivingConstraints();
|
||||
|
||||
@@ -536,9 +674,9 @@ private:
|
||||
|
||||
void clearTemporaryConstraints();
|
||||
|
||||
void buildInternalAlignmentGeometryMap(const std::vector<Constraint *> &constraintList);
|
||||
void buildInternalAlignmentGeometryMap(const std::vector<Constraint*>& constraintList);
|
||||
|
||||
int internalSolve(std::string & solvername, int level = 0);
|
||||
int internalSolve(std::string& solvername, int level = 0);
|
||||
|
||||
/// checks if the index bounds and converts negative indices to positive
|
||||
int checkGeoId(int geoId) const;
|
||||
@@ -555,63 +693,71 @@ private:
|
||||
*
|
||||
* This is important because 1) can be pre-fixed when creating geometry and constraints
|
||||
* before GCS::diagnose() via initSolution(). This is important because if no other constraint
|
||||
* affect the geometry, the geometry parameters won't even appear in the Jacobian, and they won't
|
||||
* be reported as dependent parameters.
|
||||
* affect the geometry, the geometry parameters won't even appear in the Jacobian, and they
|
||||
* won't be reported as dependent parameters.
|
||||
*
|
||||
* On the contrary 2) cannot be pre-fixed because it would lead to redundant constraints and requires
|
||||
* a post-analysis, see analyseBlockedConstraintDependentParameters, to fix just the parameters that
|
||||
* fulfil the dependacy groups.
|
||||
* On the contrary 2) cannot be pre-fixed because it would lead to redundant constraints and
|
||||
* requires a post-analysis, see analyseBlockedConstraintDependentParameters, to fix just the
|
||||
* parameters that fulfil the dependacy groups.
|
||||
*/
|
||||
bool analyseBlockedGeometry( const std::vector<Part::Geometry *> &internalGeoList,
|
||||
const std::vector<Constraint *> &constraintList,
|
||||
std::vector<bool> &onlyblockedGeometry,
|
||||
std::vector<int> &blockedGeoIds) const;
|
||||
bool analyseBlockedGeometry(const std::vector<Part::Geometry*>& internalGeoList,
|
||||
const std::vector<Constraint*>& constraintList,
|
||||
std::vector<bool>& onlyblockedGeometry,
|
||||
std::vector<int>& blockedGeoIds) const;
|
||||
|
||||
/* This function performs a post-analysis of blocked geometries (see analyseBlockedGeometry for more detail
|
||||
* on the pre-analysis).
|
||||
/* This function performs a post-analysis of blocked geometries (see analyseBlockedGeometry for
|
||||
* more detail on the pre-analysis).
|
||||
*
|
||||
* Basically identifies which parameters shall be fixed to make geometries having blocking constraints fixed,
|
||||
* while not leading to redundant/conflicting constraints. These parameters must belong to blocked geometry. This
|
||||
* is, groups may comprise parameters belonging to blocked geometry and parameters belonging to unconstrained geometry.
|
||||
* It is licit that the latter remain as dependent parameters. The former are referred to as "blockable parameters".
|
||||
* Basically identifies which parameters shall be fixed to make geometries having blocking
|
||||
* constraints fixed, while not leading to redundant/conflicting constraints. These parameters
|
||||
* must belong to blocked geometry. This is, groups may comprise parameters belonging to blocked
|
||||
* geometry and parameters belonging to unconstrained geometry. It is licit that the latter
|
||||
* remain as dependent parameters. The former are referred to as "blockable parameters".
|
||||
*
|
||||
* Extending this concept, there may be unsatisfiable groups (because they do not comprise any bloackable parameter),
|
||||
* and it is the desired outcome NOT to satisfy such groups.
|
||||
* Extending this concept, there may be unsatisfiable groups (because they do not comprise any
|
||||
* bloackable parameter), and it is the desired outcome NOT to satisfy such groups.
|
||||
*
|
||||
* There is not a single combination of fixed parameters from the blockable parameters that satisfy all the dependency
|
||||
* groups. However:
|
||||
* There is not a single combination of fixed parameters from the blockable parameters that
|
||||
* satisfy all the dependency groups. However:
|
||||
*
|
||||
* 1) some combinations do not satisfy all the dependency groups that must be satisfied (e.g. fixing one
|
||||
* group containing two blockable parameters with a given one may result in another group, fixable only by the former, not
|
||||
* to be satisfied). This leads, in a subsequent diagnosis, to satisfiable unsatisfied groups.
|
||||
* 1) some combinations do not satisfy all the dependency groups that must be satisfied (e.g.
|
||||
* fixing one group containing two blockable parameters with a given one may result in another
|
||||
* group, fixable only by the former, not to be satisfied). This leads, in a subsequent
|
||||
* diagnosis, to satisfiable unsatisfied groups.
|
||||
*
|
||||
* 2) some combinations lead to partially redundant constraints, that the solver will silently drop in a subsequent diagnosis,
|
||||
* thereby reducing the rank of the system fixing less than it should.
|
||||
* 2) some combinations lead to partially redundant constraints, that the solver will silently
|
||||
* drop in a subsequent diagnosis, thereby reducing the rank of the system fixing less than it
|
||||
* should.
|
||||
*
|
||||
* Implementation rationale (at this time):
|
||||
*
|
||||
* The implementation is on the order of the groups provided by the QR decomposition used to reveal the parameters
|
||||
* (see System::identifyDependentParameters in GCS). Zeros are made over the pilot of the full R matrix of the QR decomposition,
|
||||
* which is a top triangular matrix.This, together with the permutation matrix, allow to know groups of dependent parameters
|
||||
* (cols between rank and full size). Each group refers to a new parameter not affected by the rank in combination with other free
|
||||
* parameters intervening in the rank (because of the triangular shape of the R matrix). This results in that each the first column
|
||||
* between the rank and the full size, may only depend on a number of parameters, while the last full size column may be dependent on
|
||||
* any amount of previously introduced parameters.
|
||||
* The implementation is on the order of the groups provided by the QR decomposition used to
|
||||
* reveal the parameters (see System::identifyDependentParameters in GCS). Zeros are made over
|
||||
* the pilot of the full R matrix of the QR decomposition, which is a top triangular
|
||||
* matrix.This, together with the permutation matrix, allow to know groups of dependent
|
||||
* parameters (cols between rank and full size). Each group refers to a new parameter not
|
||||
* affected by the rank in combination with other free parameters intervening in the rank
|
||||
* (because of the triangular shape of the R matrix). This results in that each the first column
|
||||
* between the rank and the full size, may only depend on a number of parameters, while the last
|
||||
* full size column may be dependent on any amount of previously introduced parameters.
|
||||
*
|
||||
* Thus the rationale is: start from the last group (having **potentially** the larger amount of parameters) and selecting as blocking
|
||||
* for that group the latest blockable parameter. Because previous groups do not have access to the last parameter, this can never
|
||||
* interfere with previous groups. However, because the last parameter may not be a blockable one, there is a risk of selecting a parameter
|
||||
* common with other group, albeit the probability is reduced and probably (I have not demonstrated it though and I am not sure), it leads
|
||||
* to the right solution in one iteration.
|
||||
* Thus the rationale is: start from the last group (having **potentially** the larger amount of
|
||||
* parameters) and selecting as blocking for that group the latest blockable parameter. Because
|
||||
* previous groups do not have access to the last parameter, this can never interfere with
|
||||
* previous groups. However, because the last parameter may not be a blockable one, there is a
|
||||
* risk of selecting a parameter common with other group, albeit the probability is reduced and
|
||||
* probably (I have not demonstrated it though and I am not sure), it leads to the right
|
||||
* solution in one iteration.
|
||||
*
|
||||
*/
|
||||
bool analyseBlockedConstraintDependentParameters(std::vector<int> &blockedGeoIds, std::vector<double *> ¶ms_to_block) const;
|
||||
bool analyseBlockedConstraintDependentParameters(std::vector<int>& blockedGeoIds,
|
||||
std::vector<double*>& params_to_block) const;
|
||||
|
||||
/// utility function refactoring fixing the provided parameters and running a new diagnose
|
||||
void fixParametersAndDiagnose(std::vector<double *> ¶ms_to_block);
|
||||
void fixParametersAndDiagnose(std::vector<double*>& params_to_block);
|
||||
};
|
||||
|
||||
} //namespace Part
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCHER_SKETCH_H
|
||||
#endif// SKETCHER_SKETCH_H
|
||||
|
||||
@@ -23,40 +23,37 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <cmath>
|
||||
#include <cmath>
|
||||
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <gp_Pnt.hxx>
|
||||
# include <Precision.hxx>
|
||||
# include <TopExp.hxx>
|
||||
# include <TopoDS.hxx>
|
||||
# include <TopoDS_Shape.hxx>
|
||||
# include <TopoDS_Vertex.hxx>
|
||||
# include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#endif
|
||||
|
||||
#include <App/Document.h>
|
||||
#include <Base/Console.h>
|
||||
|
||||
#include "SketchAnalysis.h"
|
||||
#include "GeometryFacade.h"
|
||||
#include "SketchAnalysis.h"
|
||||
#include "SketchObject.h"
|
||||
|
||||
|
||||
using namespace Sketcher;
|
||||
|
||||
SketchAnalysis::SketchAnalysis(Sketcher::SketchObject* Obj)
|
||||
: sketch(Obj)
|
||||
{
|
||||
|
||||
}
|
||||
: sketch(Obj)
|
||||
{}
|
||||
|
||||
SketchAnalysis::~SketchAnalysis()
|
||||
{}
|
||||
|
||||
struct SketchAnalysis::VertexIds
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct SketchAnalysis::VertexIds {
|
||||
Base::Vector3d v;
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
@@ -64,98 +61,108 @@ struct SketchAnalysis::VertexIds {
|
||||
|
||||
struct SketchAnalysis::Vertex_Less
|
||||
{
|
||||
explicit Vertex_Less(double tolerance) : tolerance(tolerance){}
|
||||
bool operator()(const VertexIds& x,
|
||||
const VertexIds& y) const
|
||||
explicit Vertex_Less(double tolerance)
|
||||
: tolerance(tolerance)
|
||||
{}
|
||||
bool operator()(const VertexIds& x, const VertexIds& y) const
|
||||
{
|
||||
if (fabs (x.v.x - y.v.x) > tolerance)
|
||||
if (fabs(x.v.x - y.v.x) > tolerance)
|
||||
return x.v.x < y.v.x;
|
||||
if (fabs (x.v.y - y.v.y) > tolerance)
|
||||
if (fabs(x.v.y - y.v.y) > tolerance)
|
||||
return x.v.y < y.v.y;
|
||||
if (fabs (x.v.z - y.v.z) > tolerance)
|
||||
if (fabs(x.v.z - y.v.z) > tolerance)
|
||||
return x.v.z < y.v.z;
|
||||
return false; // points are considered to be equal
|
||||
return false;// points are considered to be equal
|
||||
}
|
||||
|
||||
private:
|
||||
double tolerance;
|
||||
};
|
||||
|
||||
struct SketchAnalysis::VertexID_Less
|
||||
{
|
||||
bool operator()(const VertexIds& x,
|
||||
const VertexIds& y) const
|
||||
bool operator()(const VertexIds& x, const VertexIds& y) const
|
||||
{
|
||||
return (x.GeoId < y.GeoId || ((x.GeoId == y.GeoId) && (x.PosId < y. PosId)));
|
||||
return (x.GeoId < y.GeoId || ((x.GeoId == y.GeoId) && (x.PosId < y.PosId)));
|
||||
}
|
||||
};
|
||||
|
||||
struct SketchAnalysis::Vertex_EqualTo
|
||||
{
|
||||
explicit Vertex_EqualTo(double tolerance) : tolerance(tolerance){}
|
||||
bool operator()(const VertexIds& x,
|
||||
const VertexIds& y) const
|
||||
explicit Vertex_EqualTo(double tolerance)
|
||||
: tolerance(tolerance)
|
||||
{}
|
||||
bool operator()(const VertexIds& x, const VertexIds& y) const
|
||||
{
|
||||
if (fabs (x.v.x - y.v.x) <= tolerance) {
|
||||
if (fabs (x.v.y - y.v.y) <= tolerance) {
|
||||
if (fabs (x.v.z - y.v.z) <= tolerance) {
|
||||
if (fabs(x.v.x - y.v.x) <= tolerance) {
|
||||
if (fabs(x.v.y - y.v.y) <= tolerance) {
|
||||
if (fabs(x.v.z - y.v.z) <= tolerance) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
double tolerance;
|
||||
};
|
||||
|
||||
struct SketchAnalysis::EdgeIds {
|
||||
struct SketchAnalysis::EdgeIds
|
||||
{
|
||||
double l;
|
||||
int GeoId;
|
||||
};
|
||||
|
||||
struct SketchAnalysis::Edge_Less
|
||||
{
|
||||
explicit Edge_Less(double tolerance) : tolerance(tolerance){}
|
||||
bool operator()(const EdgeIds& x,
|
||||
const EdgeIds& y) const
|
||||
{
|
||||
if (fabs (x.l - y.l) > tolerance)
|
||||
return x.l < y.l;
|
||||
return false; // points are considered to be equal
|
||||
}
|
||||
explicit Edge_Less(double tolerance)
|
||||
: tolerance(tolerance)
|
||||
{}
|
||||
bool operator()(const EdgeIds& x, const EdgeIds& y) const
|
||||
{
|
||||
if (fabs(x.l - y.l) > tolerance)
|
||||
return x.l < y.l;
|
||||
return false;// points are considered to be equal
|
||||
}
|
||||
|
||||
private:
|
||||
double tolerance;
|
||||
};
|
||||
|
||||
struct SketchAnalysis::Edge_EqualTo
|
||||
{
|
||||
explicit Edge_EqualTo(double tolerance) : tolerance(tolerance){}
|
||||
bool operator()(const EdgeIds& x,
|
||||
const EdgeIds& y) const
|
||||
{
|
||||
if (fabs (x.l - y.l) <= tolerance) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
explicit Edge_EqualTo(double tolerance)
|
||||
: tolerance(tolerance)
|
||||
{}
|
||||
bool operator()(const EdgeIds& x, const EdgeIds& y) const
|
||||
{
|
||||
if (fabs(x.l - y.l) <= tolerance) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
double tolerance;
|
||||
};
|
||||
|
||||
int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool includeconstruction /*=true*/)
|
||||
int SketchAnalysis::detectMissingPointOnPointConstraints(double precision,
|
||||
bool includeconstruction /*=true*/)
|
||||
{
|
||||
std::vector<VertexIds> vertexIds; // Holds a list of all vertices in the sketch
|
||||
std::vector<VertexIds> vertexIds;// Holds a list of all vertices in the sketch
|
||||
|
||||
// Build the list of sketch vertices
|
||||
const std::vector<Part::Geometry *>& geom = sketch->getInternalGeometry();
|
||||
for (std::size_t i=0; i<geom.size(); i++) {
|
||||
const std::vector<Part::Geometry*>& geom = sketch->getInternalGeometry();
|
||||
for (std::size_t i = 0; i < geom.size(); i++) {
|
||||
auto gf = GeometryFacade::getFacade(geom[i]);
|
||||
|
||||
if(gf->getConstruction() && !includeconstruction)
|
||||
if (gf->getConstruction() && !includeconstruction)
|
||||
continue;
|
||||
|
||||
if (gf->getGeometry()->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
const Part::GeomLineSegment *segm = static_cast<const Part::GeomLineSegment*>(gf->getGeometry());
|
||||
const Part::GeomLineSegment* segm =
|
||||
static_cast<const Part::GeomLineSegment*>(gf->getGeometry());
|
||||
VertexIds id;
|
||||
id.GeoId = (int)i;
|
||||
id.PosId = Sketcher::PointPos::start;
|
||||
@@ -167,7 +174,8 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
vertexIds.push_back(id);
|
||||
}
|
||||
else if (gf->getGeometry()->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
const Part::GeomArcOfCircle *segm = static_cast<const Part::GeomArcOfCircle*>(gf->getGeometry());
|
||||
const Part::GeomArcOfCircle* segm =
|
||||
static_cast<const Part::GeomArcOfCircle*>(gf->getGeometry());
|
||||
VertexIds id;
|
||||
id.GeoId = (int)i;
|
||||
id.PosId = Sketcher::PointPos::start;
|
||||
@@ -179,7 +187,8 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
vertexIds.push_back(id);
|
||||
}
|
||||
else if (gf->getGeometry()->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
const Part::GeomArcOfEllipse *segm = static_cast<const Part::GeomArcOfEllipse*>(gf->getGeometry());
|
||||
const Part::GeomArcOfEllipse* segm =
|
||||
static_cast<const Part::GeomArcOfEllipse*>(gf->getGeometry());
|
||||
VertexIds id;
|
||||
id.GeoId = (int)i;
|
||||
id.PosId = Sketcher::PointPos::start;
|
||||
@@ -191,7 +200,8 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
vertexIds.push_back(id);
|
||||
}
|
||||
else if (gf->getGeometry()->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId()) {
|
||||
const Part::GeomArcOfHyperbola *segm = static_cast<const Part::GeomArcOfHyperbola*>(gf->getGeometry());
|
||||
const Part::GeomArcOfHyperbola* segm =
|
||||
static_cast<const Part::GeomArcOfHyperbola*>(gf->getGeometry());
|
||||
VertexIds id;
|
||||
id.GeoId = (int)i;
|
||||
id.PosId = Sketcher::PointPos::start;
|
||||
@@ -203,7 +213,8 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
vertexIds.push_back(id);
|
||||
}
|
||||
else if (gf->getGeometry()->getTypeId() == Part::GeomArcOfParabola::getClassTypeId()) {
|
||||
const Part::GeomArcOfParabola *segm = static_cast<const Part::GeomArcOfParabola*>(gf->getGeometry());
|
||||
const Part::GeomArcOfParabola* segm =
|
||||
static_cast<const Part::GeomArcOfParabola*>(gf->getGeometry());
|
||||
VertexIds id;
|
||||
id.GeoId = (int)i;
|
||||
id.PosId = Sketcher::PointPos::start;
|
||||
@@ -215,7 +226,8 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
vertexIds.push_back(id);
|
||||
}
|
||||
else if (gf->getGeometry()->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
|
||||
const Part::GeomBSplineCurve *segm = static_cast<const Part::GeomBSplineCurve*>(gf->getGeometry());
|
||||
const Part::GeomBSplineCurve* segm =
|
||||
static_cast<const Part::GeomBSplineCurve*>(gf->getGeometry());
|
||||
VertexIds id;
|
||||
id.GeoId = (int)i;
|
||||
id.PosId = Sketcher::PointPos::start;
|
||||
@@ -229,22 +241,22 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
// TODO take into account single vertices ?
|
||||
}
|
||||
|
||||
std::sort(vertexIds.begin(), vertexIds.end(), Vertex_Less(precision)); // Sort points in geographic order
|
||||
// Sort points in geographic order
|
||||
std::sort(vertexIds.begin(), vertexIds.end(), Vertex_Less(precision));
|
||||
|
||||
// Build a list of all coincidence in the sketch
|
||||
|
||||
std::vector<Sketcher::Constraint*> coincidences = sketch->Constraints.getValues();
|
||||
|
||||
for (auto &constraint:sketch->Constraints.getValues()) {
|
||||
if (constraint->Type == Sketcher::Coincident ||
|
||||
constraint->Type == Sketcher::Tangent ||
|
||||
constraint->Type == Sketcher::Perpendicular) {
|
||||
for (auto& constraint : sketch->Constraints.getValues()) {
|
||||
if (constraint->Type == Sketcher::Coincident || constraint->Type == Sketcher::Tangent
|
||||
|| constraint->Type == Sketcher::Perpendicular) {
|
||||
coincidences.push_back(constraint);
|
||||
}
|
||||
// TODO optimizing by removing constraints not applying on vertices ?
|
||||
}
|
||||
|
||||
std::list<ConstraintIds> missingCoincidences; //Holds the list of missing coincidences
|
||||
std::list<ConstraintIds> missingCoincidences;// Holds the list of missing coincidences
|
||||
|
||||
std::vector<VertexIds>::iterator vt = vertexIds.begin();
|
||||
Vertex_EqualTo pred(precision);
|
||||
@@ -254,13 +266,14 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
while (vt < vertexIds.end()) {
|
||||
// Seeking for adjacent group of vertices
|
||||
vt = std::adjacent_find(vt, vertexIds.end(), pred);
|
||||
if (vt < vertexIds.end()) { // If one found
|
||||
if (vt < vertexIds.end()) {// If one found
|
||||
std::vector<VertexIds>::iterator vn;
|
||||
std::set<VertexIds, VertexID_Less> vertexGrp; // Holds a single group of adjacent vertices
|
||||
// Holds a single group of adjacent vertices
|
||||
std::set<VertexIds, VertexID_Less> vertexGrp;
|
||||
// Extract the group of adjacent vertices
|
||||
vertexGrp.insert(*vt);
|
||||
for (vn = vt+1; vn < vertexIds.end(); ++vn) {
|
||||
if (pred(*vt,*vn)) {
|
||||
for (vn = vt + 1; vn < vertexIds.end(); ++vn) {
|
||||
if (pred(*vt, *vn)) {
|
||||
vertexGrp.insert(*vn);
|
||||
}
|
||||
else {
|
||||
@@ -268,10 +281,12 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::set<VertexIds, VertexID_Less>> coincVertexGrps; // Holds groups of coincident vertices
|
||||
// Holds groups of coincident vertices
|
||||
std::vector<std::set<VertexIds, VertexID_Less>> coincVertexGrps;
|
||||
|
||||
// Decompose the group of adjacent vertices into groups of coincident vertices
|
||||
for (auto &coincidence:coincidences) { // Going through existent coincidences
|
||||
// Going through existent coincidences
|
||||
for (auto& coincidence : coincidences) {
|
||||
VertexIds v1, v2;
|
||||
v1.GeoId = coincidence->First;
|
||||
v1.PosId = coincidence->FirstPos;
|
||||
@@ -285,9 +300,9 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
// Maybe if both empty, they already have been extracted by other coincidences
|
||||
// We have to check in existing coincident groups and eventually merge
|
||||
if (nv1.empty() && nv2.empty()) {
|
||||
std::set<VertexIds, VertexID_Less> *tempGrp = nullptr;
|
||||
std::set<VertexIds, VertexID_Less>* tempGrp = nullptr;
|
||||
for (auto it = coincVertexGrps.begin(); it < coincVertexGrps.end(); ++it) {
|
||||
if ( (it->find(v1) != it->end()) || (it->find(v2) != it->end()) ) {
|
||||
if ((it->find(v1) != it->end()) || (it->find(v2) != it->end())) {
|
||||
if (!tempGrp) {
|
||||
tempGrp = &*it;
|
||||
}
|
||||
@@ -301,17 +316,21 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
continue;
|
||||
}
|
||||
|
||||
// Look if one of the constrained vertices is already in a group of coincident vertices
|
||||
for (std::set<VertexIds, VertexID_Less> &grp:coincVertexGrps) {
|
||||
if ( (grp.find(v1) != grp.end()) || (grp.find(v2) != grp.end()) ) {
|
||||
// Look if one of the constrained vertices is already in a group of coincident
|
||||
// vertices
|
||||
for (std::set<VertexIds, VertexID_Less>& grp : coincVertexGrps) {
|
||||
if ((grp.find(v1) != grp.end()) || (grp.find(v2) != grp.end())) {
|
||||
// If yes add them to the existing group
|
||||
if (!nv1.empty()) grp.insert(nv1.value());
|
||||
if (!nv2.empty()) grp.insert(nv2.value());
|
||||
if (!nv1.empty())
|
||||
grp.insert(nv1.value());
|
||||
if (!nv2.empty())
|
||||
grp.insert(nv2.value());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (nv1.empty() || nv2.empty()) continue;
|
||||
if (nv1.empty() || nv2.empty())
|
||||
continue;
|
||||
|
||||
// If no, create a new group of coincident vertices
|
||||
std::set<VertexIds, VertexID_Less> newGrp;
|
||||
@@ -320,26 +339,26 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
coincVertexGrps.push_back(newGrp);
|
||||
}
|
||||
|
||||
// If there are remaining vertices in the adjacent group (not in any existing constraint)
|
||||
// add them as being each a separate coincident group
|
||||
for (auto &lonept: vertexGrp) {
|
||||
// If there are remaining vertices in the adjacent group (not in any existing
|
||||
// constraint) add them as being each a separate coincident group
|
||||
for (auto& lonept : vertexGrp) {
|
||||
std::set<VertexIds, VertexID_Less> newGrp;
|
||||
newGrp.insert(lonept);
|
||||
coincVertexGrps.push_back(newGrp);
|
||||
}
|
||||
|
||||
// If there is more than 1 coincident group into adjacent group, constraint(s) is(are) missing
|
||||
// Virtually generate the missing constraint(s)
|
||||
// If there is more than 1 coincident group into adjacent group, constraint(s) is(are)
|
||||
// missing Virtually generate the missing constraint(s)
|
||||
if (coincVertexGrps.size() > 1) {
|
||||
std::vector<std::set<VertexIds, VertexID_Less>>::iterator vn;
|
||||
// Starting from the 2nd coincident group, generate a constraint between
|
||||
// this group first vertex, and previous group first vertex
|
||||
for (vn = coincVertexGrps.begin()+1; vn < coincVertexGrps.end(); ++vn) {
|
||||
for (vn = coincVertexGrps.begin() + 1; vn < coincVertexGrps.end(); ++vn) {
|
||||
ConstraintIds id;
|
||||
id.Type = Coincident; // default point on point restriction
|
||||
id.v = (vn-1)->begin()->v;
|
||||
id.First = (vn-1)->begin()->GeoId;
|
||||
id.FirstPos = (vn-1)->begin()->PosId;
|
||||
id.Type = Coincident;// default point on point restriction
|
||||
id.v = (vn - 1)->begin()->v;
|
||||
id.First = (vn - 1)->begin()->GeoId;
|
||||
id.FirstPos = (vn - 1)->begin()->PosId;
|
||||
id.Second = vn->begin()->GeoId;
|
||||
id.SecondPos = vn->begin()->PosId;
|
||||
missingCoincidences.push_back(id);
|
||||
@@ -354,7 +373,7 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
this->vertexConstraints.clear();
|
||||
this->vertexConstraints.reserve(missingCoincidences.size());
|
||||
|
||||
for (auto &coincidence:missingCoincidences) {
|
||||
for (auto& coincidence : missingCoincidences) {
|
||||
this->vertexConstraints.push_back(coincidence);
|
||||
}
|
||||
|
||||
@@ -364,28 +383,31 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision, bool
|
||||
|
||||
void SketchAnalysis::analyseMissingPointOnPointCoincident(double angleprecision)
|
||||
{
|
||||
for(auto & vc : vertexConstraints) {
|
||||
for (auto& vc : vertexConstraints) {
|
||||
|
||||
auto geo1 = sketch->getGeometry(vc.First);
|
||||
auto geo2 = sketch->getGeometry(vc.Second);
|
||||
|
||||
// tangency point-on-point
|
||||
const Part::GeomCurve * curve1 = dynamic_cast<const Part::GeomCurve *>(geo1);
|
||||
const Part::GeomCurve * curve2 = dynamic_cast<const Part::GeomCurve *>(geo2);
|
||||
const Part::GeomCurve* curve1 = dynamic_cast<const Part::GeomCurve*>(geo1);
|
||||
const Part::GeomCurve* curve2 = dynamic_cast<const Part::GeomCurve*>(geo2);
|
||||
|
||||
if(curve1 && curve2) {
|
||||
if (curve1 && curve2) {
|
||||
|
||||
if( geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
|
||||
geo2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId()
|
||||
&& geo2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
|
||||
const Part::GeomLineSegment *segm1 = static_cast<const Part::GeomLineSegment*>(geo1);
|
||||
const Part::GeomLineSegment *segm2 = static_cast<const Part::GeomLineSegment*>(geo2);
|
||||
const Part::GeomLineSegment* segm1 =
|
||||
static_cast<const Part::GeomLineSegment*>(geo1);
|
||||
const Part::GeomLineSegment* segm2 =
|
||||
static_cast<const Part::GeomLineSegment*>(geo2);
|
||||
|
||||
Base::Vector3d dir1 = segm1->getEndPoint() - segm1->getStartPoint();
|
||||
Base::Vector3d dir2 = segm2->getEndPoint() - segm2->getStartPoint();
|
||||
|
||||
if( (checkVertical(dir1,angleprecision) || checkHorizontal(dir1,angleprecision)) &&
|
||||
(checkVertical(dir2,angleprecision) || checkHorizontal(dir2,angleprecision)) ) {
|
||||
if ((checkVertical(dir1, angleprecision) || checkHorizontal(dir1, angleprecision))
|
||||
&& (checkVertical(dir2, angleprecision)
|
||||
|| checkHorizontal(dir2, angleprecision))) {
|
||||
// this is a job for horizontal/vertical constraints alone
|
||||
continue;
|
||||
}
|
||||
@@ -394,26 +416,24 @@ void SketchAnalysis::analyseMissingPointOnPointCoincident(double angleprecision)
|
||||
try {
|
||||
double u1, u2;
|
||||
|
||||
curve1->closestParameter(vc.v,u1);
|
||||
curve2->closestParameter(vc.v,u2);
|
||||
curve1->closestParameter(vc.v, u1);
|
||||
curve2->closestParameter(vc.v, u2);
|
||||
|
||||
Base::Vector3d tgv1 = curve1->firstDerivativeAtParameter(u1).Normalize();
|
||||
Base::Vector3d tgv2 = curve2->firstDerivativeAtParameter(u2).Normalize();
|
||||
|
||||
if(fabs(tgv1*tgv2)>fabs(cos(angleprecision))) {
|
||||
if (fabs(tgv1 * tgv2) > fabs(cos(angleprecision))) {
|
||||
vc.Type = Sketcher::Tangent;
|
||||
}
|
||||
else if(fabs(tgv1*tgv2)<fabs(cos(M_PI/2 - angleprecision))) {
|
||||
else if (fabs(tgv1 * tgv2) < fabs(cos(M_PI / 2 - angleprecision))) {
|
||||
vc.Type = Sketcher::Perpendicular;
|
||||
}
|
||||
|
||||
}
|
||||
catch(Base::Exception &) {
|
||||
Base::Console().Warning("Point-On-Point Coincidence analysis: unable to obtain derivative. Detection ignored.\n");
|
||||
catch (Base::Exception&) {
|
||||
Base::Console().Warning("Point-On-Point Coincidence analysis: unable to obtain "
|
||||
"derivative. Detection ignored.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -424,7 +444,9 @@ void SketchAnalysis::makeMissingPointOnPointCoincident(bool onebyone)
|
||||
int status, dofs;
|
||||
std::vector<Sketcher::Constraint*> constr;
|
||||
|
||||
for (std::vector<Sketcher::ConstraintIds>::iterator it = vertexConstraints.begin(); it != vertexConstraints.end(); ++it) {
|
||||
for (std::vector<Sketcher::ConstraintIds>::iterator it = vertexConstraints.begin();
|
||||
it != vertexConstraints.end();
|
||||
++it) {
|
||||
Sketcher::Constraint* c = new Sketcher::Constraint();
|
||||
c->Type = it->Type;
|
||||
c->First = it->First;
|
||||
@@ -432,21 +454,24 @@ void SketchAnalysis::makeMissingPointOnPointCoincident(bool onebyone)
|
||||
c->FirstPos = it->FirstPos;
|
||||
c->SecondPos = it->SecondPos;
|
||||
|
||||
if(onebyone) {
|
||||
if (onebyone) {
|
||||
// addConstraint() creates a clone
|
||||
sketch->addConstraint(c);
|
||||
delete c;
|
||||
|
||||
solvesketch(status,dofs,true);
|
||||
solvesketch(status, dofs, true);
|
||||
|
||||
if(status == -2) { //redundant constraints
|
||||
if (status == -2) {// redundant constraints
|
||||
sketch->autoRemoveRedundants(false);
|
||||
|
||||
solvesketch(status,dofs,false);
|
||||
solvesketch(status, dofs, false);
|
||||
}
|
||||
|
||||
if(status) {
|
||||
THROWMT(Base::RuntimeError, QT_TRANSLATE_NOOP("Exceptions", "Autoconstrain error: Unsolvable sketch while applying coincident constraints."));
|
||||
if (status) {
|
||||
THROWMT(Base::RuntimeError,
|
||||
QT_TRANSLATE_NOOP("Exceptions",
|
||||
"Autoconstrain error: Unsolvable sketch while applying "
|
||||
"coincident constraints."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -454,27 +479,28 @@ void SketchAnalysis::makeMissingPointOnPointCoincident(bool onebyone)
|
||||
}
|
||||
}
|
||||
|
||||
if(!onebyone)
|
||||
if (!onebyone)
|
||||
sketch->addConstraints(constr);
|
||||
|
||||
vertexConstraints.clear();
|
||||
|
||||
for (std::vector<Sketcher::Constraint*>::iterator it = constr.begin(); it != constr.end(); ++it) {
|
||||
for (std::vector<Sketcher::Constraint*>::iterator it = constr.begin(); it != constr.end();
|
||||
++it) {
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
int SketchAnalysis::detectMissingVerticalHorizontalConstraints(double angleprecision)
|
||||
{
|
||||
const std::vector<Part::Geometry *>& geom = sketch->getInternalGeometry();
|
||||
const std::vector<Part::Geometry*>& geom = sketch->getInternalGeometry();
|
||||
|
||||
verthorizConstraints.clear();
|
||||
|
||||
for (std::size_t i=0; i<geom.size(); i++) {
|
||||
for (std::size_t i = 0; i < geom.size(); i++) {
|
||||
Part::Geometry* g = geom[i];
|
||||
|
||||
if (g->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
const Part::GeomLineSegment *segm = static_cast<const Part::GeomLineSegment*>(g);
|
||||
const Part::GeomLineSegment* segm = static_cast<const Part::GeomLineSegment*>(g);
|
||||
|
||||
Base::Vector3d dir = segm->getEndPoint() - segm->getStartPoint();
|
||||
|
||||
@@ -486,11 +512,11 @@ int SketchAnalysis::detectMissingVerticalHorizontalConstraints(double anglepreci
|
||||
id.Second = GeoEnum::GeoUndef;
|
||||
id.SecondPos = Sketcher::PointPos::none;
|
||||
|
||||
if( checkVertical(dir, angleprecision) ) {
|
||||
if (checkVertical(dir, angleprecision)) {
|
||||
id.Type = Sketcher::Vertical;
|
||||
verthorizConstraints.push_back(id);
|
||||
}
|
||||
else if (checkHorizontal(dir, angleprecision) ) {
|
||||
else if (checkHorizontal(dir, angleprecision)) {
|
||||
id.Type = Sketcher::Horizontal;
|
||||
verthorizConstraints.push_back(id);
|
||||
}
|
||||
@@ -505,7 +531,9 @@ void SketchAnalysis::makeMissingVerticalHorizontal(bool onebyone)
|
||||
int status, dofs;
|
||||
std::vector<Sketcher::Constraint*> constr;
|
||||
|
||||
for (std::vector<Sketcher::ConstraintIds>::iterator it = verthorizConstraints.begin(); it != verthorizConstraints.end(); ++it) {
|
||||
for (std::vector<Sketcher::ConstraintIds>::iterator it = verthorizConstraints.begin();
|
||||
it != verthorizConstraints.end();
|
||||
++it) {
|
||||
Sketcher::Constraint* c = new Sketcher::Constraint();
|
||||
c->Type = it->Type;
|
||||
c->First = it->First;
|
||||
@@ -513,21 +541,24 @@ void SketchAnalysis::makeMissingVerticalHorizontal(bool onebyone)
|
||||
c->FirstPos = it->FirstPos;
|
||||
c->SecondPos = it->SecondPos;
|
||||
|
||||
if(onebyone) {
|
||||
if (onebyone) {
|
||||
// addConstraint() creates a clone
|
||||
sketch->addConstraint(c);
|
||||
delete c;
|
||||
|
||||
solvesketch(status,dofs,true);
|
||||
solvesketch(status, dofs, true);
|
||||
|
||||
if(status == -2) { //redundant constraints
|
||||
if (status == -2) {// redundant constraints
|
||||
sketch->autoRemoveRedundants(false);
|
||||
|
||||
solvesketch(status,dofs,false);
|
||||
solvesketch(status, dofs, false);
|
||||
}
|
||||
|
||||
if(status) {
|
||||
THROWMT(Base::RuntimeError, QT_TRANSLATE_NOOP("Exceptions", "Autoconstrain error: Unsolvable sketch while applying vertical/horizontal constraints."));
|
||||
if (status) {
|
||||
THROWMT(Base::RuntimeError,
|
||||
QT_TRANSLATE_NOOP("Exceptions",
|
||||
"Autoconstrain error: Unsolvable sketch while applying "
|
||||
"vertical/horizontal constraints."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -535,24 +566,25 @@ void SketchAnalysis::makeMissingVerticalHorizontal(bool onebyone)
|
||||
}
|
||||
}
|
||||
|
||||
if(!onebyone)
|
||||
if (!onebyone)
|
||||
sketch->addConstraints(constr);
|
||||
|
||||
verthorizConstraints.clear();
|
||||
|
||||
for (std::vector<Sketcher::Constraint*>::iterator it = constr.begin(); it != constr.end(); ++it) {
|
||||
for (std::vector<Sketcher::Constraint*>::iterator it = constr.begin(); it != constr.end();
|
||||
++it) {
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
bool SketchAnalysis::checkVertical(Base::Vector3d dir, double angleprecision)
|
||||
{
|
||||
return (dir.x == 0. && dir.y != 0.) || ( fabs(dir.y/dir.x) > tan(M_PI/2 - angleprecision));
|
||||
return (dir.x == 0. && dir.y != 0.) || (fabs(dir.y / dir.x) > tan(M_PI / 2 - angleprecision));
|
||||
}
|
||||
|
||||
bool SketchAnalysis::checkHorizontal(Base::Vector3d dir, double angleprecision)
|
||||
{
|
||||
return (dir.y == 0. && dir.x != 0.) || ( fabs(dir.x/dir.y) > (1/tan(angleprecision)));
|
||||
return (dir.y == 0. && dir.x != 0.) || (fabs(dir.x / dir.y) > (1 / tan(angleprecision)));
|
||||
}
|
||||
|
||||
int SketchAnalysis::detectMissingEqualityConstraints(double precision)
|
||||
@@ -560,26 +592,26 @@ int SketchAnalysis::detectMissingEqualityConstraints(double precision)
|
||||
std::vector<EdgeIds> lineedgeIds;
|
||||
std::vector<EdgeIds> radiusedgeIds;
|
||||
|
||||
const std::vector<Part::Geometry *>& geom = sketch->getInternalGeometry();
|
||||
for (std::size_t i=0; i<geom.size(); i++) {
|
||||
const std::vector<Part::Geometry*>& geom = sketch->getInternalGeometry();
|
||||
for (std::size_t i = 0; i < geom.size(); i++) {
|
||||
Part::Geometry* g = geom[i];
|
||||
|
||||
if (g->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
const Part::GeomLineSegment *segm = static_cast<const Part::GeomLineSegment*>(g);
|
||||
const Part::GeomLineSegment* segm = static_cast<const Part::GeomLineSegment*>(g);
|
||||
EdgeIds id;
|
||||
id.GeoId = (int)i;
|
||||
id.l = (segm->getEndPoint()-segm->getStartPoint()).Length();
|
||||
id.l = (segm->getEndPoint() - segm->getStartPoint()).Length();
|
||||
lineedgeIds.push_back(id);
|
||||
}
|
||||
else if (g->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
const Part::GeomArcOfCircle *segm = static_cast<const Part::GeomArcOfCircle*>(g);
|
||||
const Part::GeomArcOfCircle* segm = static_cast<const Part::GeomArcOfCircle*>(g);
|
||||
EdgeIds id;
|
||||
id.GeoId = (int)i;
|
||||
id.l = segm->getRadius();
|
||||
radiusedgeIds.push_back(id);
|
||||
}
|
||||
else if (g->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
const Part::GeomCircle *segm = static_cast<const Part::GeomCircle*>(g);
|
||||
const Part::GeomCircle* segm = static_cast<const Part::GeomCircle*>(g);
|
||||
EdgeIds id;
|
||||
id.GeoId = (int)i;
|
||||
id.l = segm->getRadius();
|
||||
@@ -598,8 +630,8 @@ int SketchAnalysis::detectMissingEqualityConstraints(double precision)
|
||||
vt = std::adjacent_find(vt, lineedgeIds.end(), pred);
|
||||
if (vt < lineedgeIds.end()) {
|
||||
std::vector<EdgeIds>::iterator vn;
|
||||
for (vn = vt+1; vn != lineedgeIds.end(); ++vn) {
|
||||
if (pred(*vt,*vn)) {
|
||||
for (vn = vt + 1; vn != lineedgeIds.end(); ++vn) {
|
||||
if (pred(*vt, *vn)) {
|
||||
ConstraintIds id;
|
||||
id.Type = Equal;
|
||||
id.v.x = vt->l;
|
||||
@@ -628,8 +660,8 @@ int SketchAnalysis::detectMissingEqualityConstraints(double precision)
|
||||
vt = std::adjacent_find(vt, radiusedgeIds.end(), pred);
|
||||
if (vt < radiusedgeIds.end()) {
|
||||
std::vector<EdgeIds>::iterator vn;
|
||||
for (vn = vt+1; vn != radiusedgeIds.end(); ++vn) {
|
||||
if (pred(*vt,*vn)) {
|
||||
for (vn = vt + 1; vn != radiusedgeIds.end(); ++vn) {
|
||||
if (pred(*vt, *vn)) {
|
||||
ConstraintIds id;
|
||||
id.Type = Equal;
|
||||
id.v.x = vt->l;
|
||||
@@ -653,26 +685,25 @@ int SketchAnalysis::detectMissingEqualityConstraints(double precision)
|
||||
// and check which of them is forcing two vertexes to be coincident.
|
||||
// If there is none but two vertexes can be considered equal a coincident constraint is missing.
|
||||
std::vector<Sketcher::Constraint*> constraint = sketch->Constraints.getValues();
|
||||
for (std::vector<Sketcher::Constraint*>::iterator it = constraint.begin(); it != constraint.end(); ++it) {
|
||||
for (std::vector<Sketcher::Constraint*>::iterator it = constraint.begin();
|
||||
it != constraint.end();
|
||||
++it) {
|
||||
if ((*it)->Type == Sketcher::Equal) {
|
||||
ConstraintIds id {
|
||||
Base::Vector3d{},
|
||||
(*it)->First,
|
||||
(*it)->Second,
|
||||
(*it)->FirstPos,
|
||||
(*it)->SecondPos,
|
||||
(*it)->Type
|
||||
};
|
||||
ConstraintIds id {Base::Vector3d {},
|
||||
(*it)->First,
|
||||
(*it)->Second,
|
||||
(*it)->FirstPos,
|
||||
(*it)->SecondPos,
|
||||
(*it)->Type};
|
||||
|
||||
std::list<ConstraintIds>::iterator pos = std::find_if
|
||||
(equallines.begin(), equallines.end(), Constraint_Equal(id));
|
||||
std::list<ConstraintIds>::iterator pos =
|
||||
std::find_if(equallines.begin(), equallines.end(), Constraint_Equal(id));
|
||||
|
||||
if (pos != equallines.end()) {
|
||||
equallines.erase(pos);
|
||||
}
|
||||
|
||||
pos = std::find_if
|
||||
(equalradius.begin(), equalradius.end(), Constraint_Equal(id));
|
||||
pos = std::find_if(equalradius.begin(), equalradius.end(), Constraint_Equal(id));
|
||||
|
||||
if (pos != equalradius.end()) {
|
||||
equalradius.erase(pos);
|
||||
@@ -690,7 +721,8 @@ int SketchAnalysis::detectMissingEqualityConstraints(double precision)
|
||||
this->radiusequalityConstraints.clear();
|
||||
this->radiusequalityConstraints.reserve(equalradius.size());
|
||||
|
||||
for (std::list<ConstraintIds>::iterator it = equalradius.begin(); it != equalradius.end(); ++it) {
|
||||
for (std::list<ConstraintIds>::iterator it = equalradius.begin(); it != equalradius.end();
|
||||
++it) {
|
||||
this->radiusequalityConstraints.push_back(*it);
|
||||
}
|
||||
|
||||
@@ -703,9 +735,12 @@ void SketchAnalysis::makeMissingEquality(bool onebyone)
|
||||
std::vector<Sketcher::Constraint*> constr;
|
||||
|
||||
std::vector<Sketcher::ConstraintIds> equalities(lineequalityConstraints);
|
||||
equalities.insert(equalities.end(),radiusequalityConstraints.begin(), radiusequalityConstraints.end());
|
||||
equalities.insert(
|
||||
equalities.end(), radiusequalityConstraints.begin(), radiusequalityConstraints.end());
|
||||
|
||||
for (std::vector<Sketcher::ConstraintIds>::iterator it = equalities.begin(); it != equalities.end(); ++it) {
|
||||
for (std::vector<Sketcher::ConstraintIds>::iterator it = equalities.begin();
|
||||
it != equalities.end();
|
||||
++it) {
|
||||
Sketcher::Constraint* c = new Sketcher::Constraint();
|
||||
c->Type = it->Type;
|
||||
c->First = it->First;
|
||||
@@ -713,21 +748,24 @@ void SketchAnalysis::makeMissingEquality(bool onebyone)
|
||||
c->FirstPos = it->FirstPos;
|
||||
c->SecondPos = it->SecondPos;
|
||||
|
||||
if(onebyone) {
|
||||
if (onebyone) {
|
||||
// addConstraint() creates a clone
|
||||
sketch->addConstraint(c);
|
||||
delete c;
|
||||
|
||||
solvesketch(status,dofs,true);
|
||||
solvesketch(status, dofs, true);
|
||||
|
||||
if(status == -2) { //redundant constraints
|
||||
if (status == -2) {// redundant constraints
|
||||
sketch->autoRemoveRedundants(false);
|
||||
|
||||
solvesketch(status,dofs,false);
|
||||
solvesketch(status, dofs, false);
|
||||
}
|
||||
|
||||
if(status) {
|
||||
THROWMT(Base::RuntimeError, QT_TRANSLATE_NOOP("Exceptions", "Autoconstrain error: Unsolvable sketch while applying equality constraints."));
|
||||
if (status) {
|
||||
THROWMT(Base::RuntimeError,
|
||||
QT_TRANSLATE_NOOP("Exceptions",
|
||||
"Autoconstrain error: Unsolvable sketch while applying "
|
||||
"equality constraints."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -735,39 +773,41 @@ void SketchAnalysis::makeMissingEquality(bool onebyone)
|
||||
}
|
||||
}
|
||||
|
||||
if(!onebyone)
|
||||
if (!onebyone)
|
||||
sketch->addConstraints(constr);
|
||||
|
||||
lineequalityConstraints.clear();
|
||||
radiusequalityConstraints.clear();
|
||||
|
||||
for (std::vector<Sketcher::Constraint*>::iterator it = constr.begin(); it != constr.end(); ++it) {
|
||||
for (std::vector<Sketcher::Constraint*>::iterator it = constr.begin(); it != constr.end();
|
||||
++it) {
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
void SketchAnalysis::solvesketch(int &status, int &dofs, bool updategeo)
|
||||
void SketchAnalysis::solvesketch(int& status, int& dofs, bool updategeo)
|
||||
{
|
||||
status = sketch->solve(updategeo);
|
||||
|
||||
if(updategeo)
|
||||
if (updategeo)
|
||||
dofs = sketch->setUpSketch();
|
||||
else
|
||||
dofs = sketch->getLastDoF();
|
||||
|
||||
if (sketch->getLastHasRedundancies()) { // redundant constraints
|
||||
if (sketch->getLastHasRedundancies()) {// redundant constraints
|
||||
status = -2;
|
||||
}
|
||||
|
||||
if (dofs < 0) { // over-constrained sketch
|
||||
if (dofs < 0) {// over-constrained sketch
|
||||
status = -4;
|
||||
}
|
||||
else if (sketch->getLastHasConflicts()) { // conflicting constraints
|
||||
else if (sketch->getLastHasConflicts()) {// conflicting constraints
|
||||
status = -3;
|
||||
}
|
||||
}
|
||||
|
||||
int SketchAnalysis::autoconstraint(double precision, double angleprecision, bool includeconstruction)
|
||||
int SketchAnalysis::autoconstraint(double precision, double angleprecision,
|
||||
bool includeconstruction)
|
||||
{
|
||||
App::Document* doc = sketch->getDocument();
|
||||
doc->openTransaction("delete all constraints");
|
||||
@@ -778,30 +818,38 @@ int SketchAnalysis::autoconstraint(double precision, double angleprecision, bool
|
||||
|
||||
int status, dofs;
|
||||
|
||||
solvesketch(status,dofs,true);
|
||||
solvesketch(status, dofs, true);
|
||||
|
||||
if(status) {// it should not be possible at this moment as we start from a clean situation
|
||||
THROWMT(Base::RuntimeError, QT_TRANSLATE_NOOP("Exceptions", "Autoconstrain error: Unsolvable sketch without constraints."));
|
||||
if (status) {// it should not be possible at this moment as we start from a clean situation
|
||||
THROWMT(Base::RuntimeError,
|
||||
QT_TRANSLATE_NOOP("Exceptions",
|
||||
"Autoconstrain error: Unsolvable sketch without constraints."));
|
||||
}
|
||||
|
||||
// STAGE 1: Vertical/Horizontal Line Segments
|
||||
int nhv = detectMissingVerticalHorizontalConstraints(angleprecision);
|
||||
|
||||
// STAGE 2: Point-on-Point constraint (Coincidents, endpoint perp, endpoint tangency)
|
||||
// Note: We do not apply the vertical/horizontal constraints before calculating the pointonpoint constraints
|
||||
// Note: We do not apply the vertical/horizontal constraints before calculating the pointonpoint
|
||||
// constraints
|
||||
// as the solver may move the geometry in the meantime and prevent correct detection
|
||||
int nc = detectMissingPointOnPointConstraints(precision, includeconstruction);
|
||||
|
||||
if (nc > 0) // STAGE 2a: Classify point-on-point into coincidents, endpoint perp, endpoint tangency
|
||||
if (nc
|
||||
> 0)// STAGE 2a: Classify point-on-point into coincidents, endpoint perp, endpoint tangency
|
||||
analyseMissingPointOnPointCoincident(angleprecision);
|
||||
|
||||
// STAGE 3: Equality constraint detection
|
||||
int ne = detectMissingEqualityConstraints(precision);
|
||||
|
||||
Base::Console().Log("Constraints: Vertical/Horizontal: %d found. Point-on-point: %d. Equality: %d\n", nhv, nc, ne);
|
||||
Base::Console().Log(
|
||||
"Constraints: Vertical/Horizontal: %d found. Point-on-point: %d. Equality: %d\n",
|
||||
nhv,
|
||||
nc,
|
||||
ne);
|
||||
|
||||
// Applying STAGE 1, if any
|
||||
if (nhv >0 ) {
|
||||
if (nhv > 0) {
|
||||
App::Document* doc = sketch->getDocument();
|
||||
doc->openTransaction("add vertical/horizontal constraints");
|
||||
|
||||
@@ -810,20 +858,23 @@ int SketchAnalysis::autoconstraint(double precision, double angleprecision, bool
|
||||
// finish the transaction and update
|
||||
doc->commitTransaction();
|
||||
|
||||
solvesketch(status,dofs,true);
|
||||
solvesketch(status, dofs, true);
|
||||
|
||||
if(status == -2) { // redundants
|
||||
if (status == -2) {// redundants
|
||||
sketch->autoRemoveRedundants(false);
|
||||
solvesketch(status,dofs,false);
|
||||
solvesketch(status, dofs, false);
|
||||
}
|
||||
|
||||
if(status) {
|
||||
THROWMT(Base::RuntimeError, QT_TRANSLATE_NOOP("Exceptions", "Autoconstrain error: Unsolvable sketch after applying horizontal and vertical constraints."));
|
||||
if (status) {
|
||||
THROWMT(Base::RuntimeError,
|
||||
QT_TRANSLATE_NOOP("Exceptions",
|
||||
"Autoconstrain error: Unsolvable sketch after applying "
|
||||
"horizontal and vertical constraints."));
|
||||
}
|
||||
}
|
||||
|
||||
// Applying STAGE 2
|
||||
if(nc > 0) {
|
||||
if (nc > 0) {
|
||||
App::Document* doc = sketch->getDocument();
|
||||
doc->openTransaction("add coincident constraint");
|
||||
|
||||
@@ -832,27 +883,30 @@ int SketchAnalysis::autoconstraint(double precision, double angleprecision, bool
|
||||
// finish the transaction and update
|
||||
doc->commitTransaction();
|
||||
|
||||
solvesketch(status,dofs,true);
|
||||
solvesketch(status, dofs, true);
|
||||
|
||||
if(status == -2) { // redundants
|
||||
if (status == -2) {// redundants
|
||||
sketch->autoRemoveRedundants(false);
|
||||
solvesketch(status,dofs,false);
|
||||
solvesketch(status, dofs, false);
|
||||
}
|
||||
|
||||
if(status) {
|
||||
THROWMT(Base::RuntimeError, QT_TRANSLATE_NOOP("Exceptions", "Autoconstrain error: Unsolvable sketch after applying point-on-point constraints."));
|
||||
if (status) {
|
||||
THROWMT(Base::RuntimeError,
|
||||
QT_TRANSLATE_NOOP("Exceptions",
|
||||
"Autoconstrain error: Unsolvable sketch after applying "
|
||||
"point-on-point constraints."));
|
||||
}
|
||||
}
|
||||
|
||||
// Applying STAGE 3
|
||||
if(ne > 0) {
|
||||
if (ne > 0) {
|
||||
App::Document* doc = sketch->getDocument();
|
||||
doc->openTransaction("add equality constraints");
|
||||
|
||||
try {
|
||||
makeMissingEquality();
|
||||
}
|
||||
catch(Base::RuntimeError &) {
|
||||
catch (Base::RuntimeError&) {
|
||||
doc->abortTransaction();
|
||||
throw;
|
||||
}
|
||||
@@ -860,15 +914,19 @@ int SketchAnalysis::autoconstraint(double precision, double angleprecision, bool
|
||||
// finish the transaction and update
|
||||
doc->commitTransaction();
|
||||
|
||||
solvesketch(status,dofs,true);
|
||||
solvesketch(status, dofs, true);
|
||||
|
||||
if(status == -2) { // redundants
|
||||
if (status == -2) {// redundants
|
||||
sketch->autoRemoveRedundants(false);
|
||||
solvesketch(status,dofs,false);
|
||||
solvesketch(status, dofs, false);
|
||||
}
|
||||
|
||||
if(status) {
|
||||
THROWMT(Base::RuntimeError, QT_TRANSLATE_NOOP("Exceptions", "Autoconstrain error: Unsolvable sketch after applying equality constraints."));
|
||||
if (status) {
|
||||
THROWMT(
|
||||
Base::RuntimeError,
|
||||
QT_TRANSLATE_NOOP(
|
||||
"Exceptions",
|
||||
"Autoconstrain error: Unsolvable sketch after applying equality constraints."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -889,13 +947,13 @@ std::vector<Base::Vector3d> SketchAnalysis::getOpenVertices() const
|
||||
// build up map vertex->edge
|
||||
TopTools_IndexedDataMapOfShapeListOfShape vertex2Edge;
|
||||
TopExp::MapShapesAndAncestors(shape, TopAbs_VERTEX, TopAbs_EDGE, vertex2Edge);
|
||||
for (int i=1; i<= vertex2Edge.Extent(); ++i) {
|
||||
for (int i = 1; i <= vertex2Edge.Extent(); ++i) {
|
||||
const TopTools_ListOfShape& los = vertex2Edge.FindFromIndex(i);
|
||||
if (los.Extent() != 2) {
|
||||
const TopoDS_Vertex& vertex = TopoDS::Vertex(vertex2Edge.FindKey(i));
|
||||
gp_Pnt pnt = BRep_Tool::Pnt(vertex);
|
||||
Base::Vector3d pos;
|
||||
invPlm.multVec(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()),pos);
|
||||
invPlm.multVec(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()), pos);
|
||||
points.push_back(pos);
|
||||
}
|
||||
}
|
||||
@@ -906,8 +964,8 @@ std::vector<Base::Vector3d> SketchAnalysis::getOpenVertices() const
|
||||
int SketchAnalysis::detectDegeneratedGeometries(double tolerance)
|
||||
{
|
||||
int countDegenerated = 0;
|
||||
const std::vector<Part::Geometry *>& geom = sketch->getInternalGeometry();
|
||||
for (std::size_t i=0; i<geom.size(); i++) {
|
||||
const std::vector<Part::Geometry*>& geom = sketch->getInternalGeometry();
|
||||
for (std::size_t i = 0; i < geom.size(); i++) {
|
||||
auto gf = GeometryFacade::getFacade(geom[i]);
|
||||
|
||||
if (gf->getConstruction())
|
||||
@@ -927,9 +985,9 @@ int SketchAnalysis::detectDegeneratedGeometries(double tolerance)
|
||||
int SketchAnalysis::removeDegeneratedGeometries(double tolerance)
|
||||
{
|
||||
std::set<int> delInternalGeometries;
|
||||
const std::vector<Part::Geometry *>& geom = sketch->getInternalGeometry();
|
||||
for (std::size_t i=0; i<geom.size(); i++) {
|
||||
auto gf = GeometryFacade::getFacade(geom[i]);
|
||||
const std::vector<Part::Geometry*>& geom = sketch->getInternalGeometry();
|
||||
for (std::size_t i = 0; i < geom.size(); i++) {
|
||||
auto gf = GeometryFacade::getFacade(geom[i]);
|
||||
|
||||
if (gf->getConstruction())
|
||||
continue;
|
||||
|
||||
@@ -32,76 +32,110 @@
|
||||
#include "Analyse.h"
|
||||
|
||||
|
||||
namespace Sketcher {
|
||||
namespace Sketcher
|
||||
{
|
||||
|
||||
class SketchObject;
|
||||
|
||||
class SketcherExport SketchAnalysis
|
||||
{
|
||||
public:
|
||||
/// Creates an instance of the SketchAnalysis object, taking as parameter a pointer to an SketchObject.
|
||||
/// Creates an instance of the SketchAnalysis object, taking as parameter a pointer to an
|
||||
/// SketchObject.
|
||||
///
|
||||
/// There is a first type of routines, simple routines, which work in the following order:
|
||||
/// Detect - (Analyse) - [Get] - [Set] - Make
|
||||
///
|
||||
/// The Detect step just identifies possible missing constraints.
|
||||
///
|
||||
/// The Analyse, which is not available for all the routines, operates in detected constraints of the same routine, to
|
||||
/// look for alternatives. For example, a general pointonpoint detection leads to a search for coincident constraints, which
|
||||
/// can be later run via Analyse if it is intended to convert endpoint coincidence to endpoint perpendicular and tangent constraints.
|
||||
/// The Analyse, which is not available for all the routines, operates in detected constraints
|
||||
/// of the same routine, to look for alternatives. For example, a general pointonpoint detection
|
||||
/// leads to a search for coincident constraints, which can be later run via Analyse if it is
|
||||
/// intended to convert endpoint coincidence to endpoint perpendicular and tangent constraints.
|
||||
///
|
||||
/// The Get retrieves the result of the analysis as a vector of ConstraintIds, indicating the suggested constraints. This step is intended
|
||||
/// for enabling the user to check the result of the analysis, rather than applying it. If only applying is intended, this step is not necessary
|
||||
/// as the Make will operate on the result of the Detect - Analyse directly.
|
||||
/// The Get retrieves the result of the analysis as a vector of ConstraintIds, indicating the
|
||||
/// suggested constraints. This step is intended for enabling the user to check the result of
|
||||
/// the analysis, rather than applying it. If only applying is intended, this step is not
|
||||
/// necessary as the Make will operate on the result of the Detect - Analyse directly.
|
||||
///
|
||||
/// The Set changes the detected result. It modifies the SketchAnalysis object. It only modifies the SketchObject as far as the SketchAnalysis is changed.
|
||||
/// It does not apply any changes to the sketch. It is intended so as to enable the user to change the result that will be applied.
|
||||
/// The Set changes the detected result. It modifies the SketchAnalysis object. It only modifies
|
||||
/// the SketchObject as far as the SketchAnalysis is changed. It does not apply any changes to
|
||||
/// the sketch. It is intended so as to enable the user to change the result that will be
|
||||
/// applied.
|
||||
///
|
||||
/// Neither the Detect, nor the Analyse, nor the Get steps modify the Sketch geometry.
|
||||
///
|
||||
/// Make applies the constraints stored internally in the SketchAnalysis object.
|
||||
///
|
||||
/// A second type of routines, complex routines, are thought for running fully automatic and they Detect, Analyse and Make.
|
||||
/// They may also apply a variety of constraint types.
|
||||
/// A second type of routines, complex routines, are thought for running fully automatic and
|
||||
/// they Detect, Analyse and Make. They may also apply a variety of constraint types.
|
||||
///
|
||||
/// A third type of routines do not relate to autoconstraining at all, and include validation methods for sketches.
|
||||
explicit SketchAnalysis(Sketcher::SketchObject * Obj);
|
||||
/// A third type of routines do not relate to autoconstraining at all, and include validation
|
||||
/// methods for sketches.
|
||||
explicit SketchAnalysis(Sketcher::SketchObject* Obj);
|
||||
~SketchAnalysis();
|
||||
|
||||
// Simple routines (see constructor)
|
||||
|
||||
/// Point on Point constraint simple routine Detect step (see constructor)
|
||||
/// Detect detects only coincident constraints, Analyse converts coincident to endpoint perpendicular/tangent where appropriate
|
||||
int detectMissingPointOnPointConstraints(double precision = Precision::Confusion() * 1000, bool includeconstruction = true);
|
||||
/// Detect detects only coincident constraints, Analyse converts coincident to endpoint
|
||||
/// perpendicular/tangent where appropriate
|
||||
int detectMissingPointOnPointConstraints(double precision = Precision::Confusion() * 1000,
|
||||
bool includeconstruction = true);
|
||||
/// Point on Point constraint simple routine Analyse step (see constructor)
|
||||
void analyseMissingPointOnPointCoincident(double angleprecision = M_PI/8);
|
||||
void analyseMissingPointOnPointCoincident(double angleprecision = M_PI / 8);
|
||||
/// Point on Point constraint simple routine Get step (see constructor)
|
||||
std::vector<ConstraintIds> &getMissingPointOnPointConstraints() {return vertexConstraints;}
|
||||
std::vector<ConstraintIds>& getMissingPointOnPointConstraints()
|
||||
{
|
||||
return vertexConstraints;
|
||||
}
|
||||
/// Vertical/Horizontal constraints simple routine Set step (see constructor)
|
||||
void setMissingPointOnPointConstraints(std::vector<ConstraintIds>& cl) {vertexConstraints = cl;}
|
||||
void setMissingPointOnPointConstraints(std::vector<ConstraintIds>& cl)
|
||||
{
|
||||
vertexConstraints = cl;
|
||||
}
|
||||
/// Point on Point constraint simple routine Make step (see constructor)
|
||||
/// if onebyone, then the sketch is solved after each individual constraint addition and any redundancy removed.
|
||||
/// if onebyone, then the sketch is solved after each individual constraint addition and any
|
||||
/// redundancy removed.
|
||||
void makeMissingPointOnPointCoincident(bool onebyone = false);
|
||||
|
||||
/// Vertical/Horizontal constraints simple routine Detect step (see constructor)
|
||||
int detectMissingVerticalHorizontalConstraints(double angleprecision = M_PI/8);
|
||||
int detectMissingVerticalHorizontalConstraints(double angleprecision = M_PI / 8);
|
||||
/// Vertical/Horizontal constraints simple routine Get step (see constructor)
|
||||
std::vector<ConstraintIds> &getMissingVerticalHorizontalConstraints() {return verthorizConstraints;}
|
||||
std::vector<ConstraintIds>& getMissingVerticalHorizontalConstraints()
|
||||
{
|
||||
return verthorizConstraints;
|
||||
}
|
||||
/// Vertical/Horizontal constraints simple routine Set step (see constructor)
|
||||
void setMissingVerticalHorizontalConstraints(std::vector<ConstraintIds>& cl) {verthorizConstraints = cl;}
|
||||
void setMissingVerticalHorizontalConstraints(std::vector<ConstraintIds>& cl)
|
||||
{
|
||||
verthorizConstraints = cl;
|
||||
}
|
||||
/// Vertical/Horizontal constraints simple routine Make step (see constructor)
|
||||
void makeMissingVerticalHorizontal(bool onebyone = false);
|
||||
|
||||
/// Equality constraints simple routine Detect step (see constructor)
|
||||
int detectMissingEqualityConstraints(double precision);
|
||||
/// Equality constraints simple routine Get step for line segments (see constructor)
|
||||
std::vector<ConstraintIds> &getMissingLineEqualityConstraints() {return lineequalityConstraints;}
|
||||
std::vector<ConstraintIds>& getMissingLineEqualityConstraints()
|
||||
{
|
||||
return lineequalityConstraints;
|
||||
}
|
||||
/// Equality constraints simple routine Get step for radii (see constructor)
|
||||
std::vector<ConstraintIds> &getMissingRadiusConstraints() {return radiusequalityConstraints;}
|
||||
std::vector<ConstraintIds>& getMissingRadiusConstraints()
|
||||
{
|
||||
return radiusequalityConstraints;
|
||||
}
|
||||
/// Equality constraints simple routine Set step for line segments (see constructor)
|
||||
void setMissingLineEqualityConstraints(std::vector<ConstraintIds>& cl) {lineequalityConstraints = cl;}
|
||||
void setMissingLineEqualityConstraints(std::vector<ConstraintIds>& cl)
|
||||
{
|
||||
lineequalityConstraints = cl;
|
||||
}
|
||||
/// Equality constraints simple routine Set step for radii (see constructor)
|
||||
void setMissingRadiusConstraints(std::vector<ConstraintIds>& cl) {radiusequalityConstraints = cl;}
|
||||
void setMissingRadiusConstraints(std::vector<ConstraintIds>& cl)
|
||||
{
|
||||
radiusequalityConstraints = cl;
|
||||
}
|
||||
/// Equality constraints simple routine Make step (see constructor)
|
||||
void makeMissingEquality(bool onebyone = true);
|
||||
|
||||
@@ -114,16 +148,20 @@ public:
|
||||
|
||||
/// Fully automated multi-constraint autoconstraining
|
||||
///
|
||||
/// It DELETES all the constraints currently present in the Sketcher. The reason is that it makes assumptions to avoid redundancies.
|
||||
/// It DELETES all the constraints currently present in the Sketcher. The reason is that it
|
||||
/// makes assumptions to avoid redundancies.
|
||||
///
|
||||
/// It applies coincidents - vertical/horizontal constraints and equality constraints.
|
||||
int autoconstraint(double precision = Precision::Confusion() * 1000, double angleprecision = M_PI/8, bool includeconstruction = true);
|
||||
int autoconstraint(double precision = Precision::Confusion() * 1000,
|
||||
double angleprecision = M_PI / 8, bool includeconstruction = true);
|
||||
|
||||
// helper functions, which may be used by more complex methods, and/or called directly by user space (python) methods
|
||||
// helper functions, which may be used by more complex methods, and/or called directly by user
|
||||
// space (python) methods
|
||||
|
||||
/// solves the sketch and retrieves the error status, and the degrees of freedom.
|
||||
/// It enables to solve updating the geometry (so moving the geometry to match the constraints) or preserving the geometry.
|
||||
void solvesketch(int &status, int &dofs, bool updategeo);
|
||||
/// It enables to solve updating the geometry (so moving the geometry to match the constraints)
|
||||
/// or preserving the geometry.
|
||||
void solvesketch(int& status, int& dofs, bool updategeo);
|
||||
|
||||
// third type of routines
|
||||
std::vector<Base::Vector3d> getOpenVertices() const;
|
||||
@@ -146,9 +184,8 @@ protected:
|
||||
protected:
|
||||
bool checkHorizontal(Base::Vector3d dir, double angleprecision);
|
||||
bool checkVertical(Base::Vector3d dir, double angleprecision);
|
||||
|
||||
};
|
||||
|
||||
} //namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
#endif // SKETCHER_SKETCHANALYSIS_H
|
||||
#endif// SKETCHER_SKETCHANALYSIS_H
|
||||
|
||||
@@ -32,62 +32,63 @@
|
||||
using namespace Sketcher;
|
||||
|
||||
//---------- Geometry Extension
|
||||
constexpr std::array<const char *, InternalType::NumInternalGeometryType> SketchGeometryExtension::internaltype2str;
|
||||
constexpr std::array<const char *,GeometryMode::NumGeometryMode> SketchGeometryExtension::geometrymode2str;
|
||||
constexpr std::array<const char*, InternalType::NumInternalGeometryType>
|
||||
SketchGeometryExtension::internaltype2str;
|
||||
constexpr std::array<const char*, GeometryMode::NumGeometryMode>
|
||||
SketchGeometryExtension::geometrymode2str;
|
||||
|
||||
TYPESYSTEM_SOURCE(Sketcher::SketchGeometryExtension,Part::GeometryPersistenceExtension)
|
||||
TYPESYSTEM_SOURCE(Sketcher::SketchGeometryExtension, Part::GeometryPersistenceExtension)
|
||||
|
||||
// scoped within the class, multithread ready
|
||||
std::atomic<long> SketchGeometryExtension::_GeometryID;
|
||||
|
||||
SketchGeometryExtension::SketchGeometryExtension(): Id(++SketchGeometryExtension::_GeometryID),
|
||||
InternalGeometryType(InternalType::None),
|
||||
GeometryLayer(0)
|
||||
{
|
||||
SketchGeometryExtension::SketchGeometryExtension()
|
||||
: Id(++SketchGeometryExtension::_GeometryID),
|
||||
InternalGeometryType(InternalType::None),
|
||||
GeometryLayer(0)
|
||||
{}
|
||||
|
||||
}
|
||||
SketchGeometryExtension::SketchGeometryExtension(long cid)
|
||||
: Id(cid),
|
||||
InternalGeometryType(InternalType::None),
|
||||
GeometryLayer(0)
|
||||
{}
|
||||
|
||||
SketchGeometryExtension::SketchGeometryExtension(long cid): Id(cid),
|
||||
InternalGeometryType(InternalType::None),
|
||||
GeometryLayer(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SketchGeometryExtension::copyAttributes(Part::GeometryExtension * cpy) const
|
||||
void SketchGeometryExtension::copyAttributes(Part::GeometryExtension* cpy) const
|
||||
{
|
||||
Part::GeometryPersistenceExtension::copyAttributes(cpy);
|
||||
|
||||
static_cast<SketchGeometryExtension *>(cpy)->Id = this->Id;
|
||||
static_cast<SketchGeometryExtension *>(cpy)->InternalGeometryType = this->InternalGeometryType;
|
||||
static_cast<SketchGeometryExtension *>(cpy)->GeometryModeFlags = this->GeometryModeFlags;
|
||||
static_cast<SketchGeometryExtension *>(cpy)->GeometryLayer = this->GeometryLayer;
|
||||
static_cast<SketchGeometryExtension*>(cpy)->Id = this->Id;
|
||||
static_cast<SketchGeometryExtension*>(cpy)->InternalGeometryType = this->InternalGeometryType;
|
||||
static_cast<SketchGeometryExtension*>(cpy)->GeometryModeFlags = this->GeometryModeFlags;
|
||||
static_cast<SketchGeometryExtension*>(cpy)->GeometryLayer = this->GeometryLayer;
|
||||
}
|
||||
|
||||
void SketchGeometryExtension::restoreAttributes(Base::XMLReader &reader)
|
||||
void SketchGeometryExtension::restoreAttributes(Base::XMLReader& reader)
|
||||
{
|
||||
Part::GeometryPersistenceExtension::restoreAttributes(reader);
|
||||
|
||||
if(reader.hasAttribute("id"))
|
||||
if (reader.hasAttribute("id"))
|
||||
Id = reader.getAttributeAsInteger("id");
|
||||
|
||||
InternalGeometryType = static_cast<InternalType::InternalType>(reader.getAttributeAsInteger("internalGeometryType"));
|
||||
InternalGeometryType = static_cast<InternalType::InternalType>(
|
||||
reader.getAttributeAsInteger("internalGeometryType"));
|
||||
|
||||
GeometryModeFlags = GeometryModeFlagType(reader.getAttribute("geometryModeFlags"));
|
||||
|
||||
if(reader.hasAttribute("geometryLayer"))
|
||||
if (reader.hasAttribute("geometryLayer"))
|
||||
GeometryLayer = reader.getAttributeAsInteger("geometryLayer");
|
||||
|
||||
}
|
||||
|
||||
void SketchGeometryExtension::saveAttributes(Base::Writer &writer) const
|
||||
void SketchGeometryExtension::saveAttributes(Base::Writer& writer) const
|
||||
{
|
||||
Part::GeometryPersistenceExtension::saveAttributes(writer);
|
||||
|
||||
writer.Stream() // << "\" id=\"" << Id // This is removed as the stored Id is not used and it may interfere with RT's future implementation
|
||||
<< "\" internalGeometryType=\"" << (int) InternalGeometryType
|
||||
<< "\" geometryModeFlags=\"" << GeometryModeFlags.to_string()
|
||||
<< "\" geometryLayer=\"" << GeometryLayer;
|
||||
// This is removed as the stored Id is not used and it may interfere with RT's future
|
||||
// implementation
|
||||
writer.Stream()// << "\" id=\"" << Id
|
||||
<< "\" internalGeometryType=\"" << (int)InternalGeometryType << "\" geometryModeFlags=\""
|
||||
<< GeometryModeFlags.to_string() << "\" geometryLayer=\"" << GeometryLayer;
|
||||
}
|
||||
|
||||
std::unique_ptr<Part::GeometryExtension> SketchGeometryExtension::copy() const
|
||||
@@ -96,53 +97,52 @@ std::unique_ptr<Part::GeometryExtension> SketchGeometryExtension::copy() const
|
||||
|
||||
copyAttributes(cpy.get());
|
||||
|
||||
#if defined (__GNUC__) && (__GNUC__ <=4)
|
||||
#if defined(__GNUC__) && (__GNUC__ <= 4)
|
||||
return std::move(cpy);
|
||||
#else
|
||||
return cpy;
|
||||
#endif
|
||||
}
|
||||
|
||||
PyObject * SketchGeometryExtension::getPyObject()
|
||||
PyObject* SketchGeometryExtension::getPyObject()
|
||||
{
|
||||
return new SketchGeometryExtensionPy(new SketchGeometryExtension(*this));
|
||||
}
|
||||
|
||||
bool SketchGeometryExtension::getInternalTypeFromName(std::string str, InternalType::InternalType &type)
|
||||
bool SketchGeometryExtension::getInternalTypeFromName(std::string str,
|
||||
InternalType::InternalType& type)
|
||||
{
|
||||
auto pos = std::find_if( SketchGeometryExtension::internaltype2str.begin(),
|
||||
SketchGeometryExtension::internaltype2str.end(),
|
||||
[str](const char * val) {
|
||||
return strcmp(val,str.c_str())==0;
|
||||
}
|
||||
);
|
||||
auto pos = std::find_if(SketchGeometryExtension::internaltype2str.begin(),
|
||||
SketchGeometryExtension::internaltype2str.end(),
|
||||
[str](const char* val) {
|
||||
return strcmp(val, str.c_str()) == 0;
|
||||
});
|
||||
|
||||
if( pos != SketchGeometryExtension::internaltype2str.end()) {
|
||||
int index = std::distance( SketchGeometryExtension::internaltype2str.begin(), pos );
|
||||
if (pos != SketchGeometryExtension::internaltype2str.end()) {
|
||||
int index = std::distance(SketchGeometryExtension::internaltype2str.begin(), pos);
|
||||
|
||||
type = static_cast<InternalType::InternalType>(index);
|
||||
return true;
|
||||
type = static_cast<InternalType::InternalType>(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SketchGeometryExtension::getGeometryModeFromName(std::string str, GeometryMode::GeometryMode &type)
|
||||
bool SketchGeometryExtension::getGeometryModeFromName(std::string str,
|
||||
GeometryMode::GeometryMode& type)
|
||||
{
|
||||
auto pos = std::find_if( SketchGeometryExtension::geometrymode2str.begin(),
|
||||
SketchGeometryExtension::geometrymode2str.end(),
|
||||
[str](const char * val) {
|
||||
return strcmp(val,str.c_str())==0;
|
||||
}
|
||||
);
|
||||
auto pos = std::find_if(SketchGeometryExtension::geometrymode2str.begin(),
|
||||
SketchGeometryExtension::geometrymode2str.end(),
|
||||
[str](const char* val) {
|
||||
return strcmp(val, str.c_str()) == 0;
|
||||
});
|
||||
|
||||
if( pos != SketchGeometryExtension::geometrymode2str.end()) {
|
||||
int index = std::distance( SketchGeometryExtension::geometrymode2str.begin(), pos );
|
||||
if (pos != SketchGeometryExtension::geometrymode2str.end()) {
|
||||
int index = std::distance(SketchGeometryExtension::geometrymode2str.begin(), pos);
|
||||
|
||||
type = static_cast<GeometryMode::GeometryMode>(index);
|
||||
return true;
|
||||
type = static_cast<GeometryMode::GeometryMode>(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,31 +34,35 @@
|
||||
namespace Sketcher
|
||||
{
|
||||
|
||||
namespace InternalType {
|
||||
enum InternalType {
|
||||
None = 0,
|
||||
EllipseMajorDiameter = 1,
|
||||
EllipseMinorDiameter = 2,
|
||||
EllipseFocus1 = 3,
|
||||
EllipseFocus2 = 4,
|
||||
HyperbolaMajor = 5,
|
||||
HyperbolaMinor = 6,
|
||||
HyperbolaFocus = 7,
|
||||
ParabolaFocus = 8,
|
||||
BSplineControlPoint = 9,
|
||||
BSplineKnotPoint = 10,
|
||||
ParabolaFocalAxis = 11,
|
||||
NumInternalGeometryType // Must be the last
|
||||
};
|
||||
}
|
||||
namespace InternalType
|
||||
{
|
||||
enum InternalType
|
||||
{
|
||||
None = 0,
|
||||
EllipseMajorDiameter = 1,
|
||||
EllipseMinorDiameter = 2,
|
||||
EllipseFocus1 = 3,
|
||||
EllipseFocus2 = 4,
|
||||
HyperbolaMajor = 5,
|
||||
HyperbolaMinor = 6,
|
||||
HyperbolaFocus = 7,
|
||||
ParabolaFocus = 8,
|
||||
BSplineControlPoint = 9,
|
||||
BSplineKnotPoint = 10,
|
||||
ParabolaFocalAxis = 11,
|
||||
NumInternalGeometryType// Must be the last
|
||||
};
|
||||
}
|
||||
|
||||
namespace GeometryMode {
|
||||
enum GeometryMode {
|
||||
Blocked = 0,
|
||||
Construction = 1,
|
||||
NumGeometryMode // Must be the last
|
||||
};
|
||||
}
|
||||
namespace GeometryMode
|
||||
{
|
||||
enum GeometryMode
|
||||
{
|
||||
Blocked = 0,
|
||||
Construction = 1,
|
||||
NumGeometryMode// Must be the last
|
||||
};
|
||||
}
|
||||
|
||||
class ISketchGeometryExtension
|
||||
{
|
||||
@@ -74,65 +78,103 @@ public:
|
||||
|
||||
// Geometry functional mode
|
||||
virtual bool testGeometryMode(int flag) const = 0;
|
||||
virtual void setGeometryMode(int flag, bool v=true) = 0;
|
||||
virtual void setGeometryMode(int flag, bool v = true) = 0;
|
||||
|
||||
virtual int getGeometryLayerId() const = 0;
|
||||
virtual void setGeometryLayerId(int geolayer) = 0;
|
||||
};
|
||||
|
||||
class SketcherExport SketchGeometryExtension : public Part::GeometryPersistenceExtension, private ISketchGeometryExtension
|
||||
class SketcherExport SketchGeometryExtension: public Part::GeometryPersistenceExtension,
|
||||
private ISketchGeometryExtension
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
public:
|
||||
|
||||
public:
|
||||
SketchGeometryExtension();
|
||||
explicit SketchGeometryExtension(long cid);
|
||||
~SketchGeometryExtension() override = default;
|
||||
|
||||
std::unique_ptr<Part::GeometryExtension> copy() const override;
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
long getId() const override {return Id;}
|
||||
void setId(long id) override {Id = id;}
|
||||
long getId() const override
|
||||
{
|
||||
return Id;
|
||||
}
|
||||
void setId(long id) override
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
|
||||
InternalType::InternalType getInternalType() const override {return InternalGeometryType;}
|
||||
void setInternalType(InternalType::InternalType type) override {InternalGeometryType = type;}
|
||||
InternalType::InternalType getInternalType() const override
|
||||
{
|
||||
return InternalGeometryType;
|
||||
}
|
||||
void setInternalType(InternalType::InternalType type) override
|
||||
{
|
||||
InternalGeometryType = type;
|
||||
}
|
||||
|
||||
bool testGeometryMode(int flag) const override { return GeometryModeFlags.test((size_t)(flag)); };
|
||||
void setGeometryMode(int flag, bool v=true) override { GeometryModeFlags.set((size_t)(flag), v); };
|
||||
bool testGeometryMode(int flag) const override
|
||||
{
|
||||
return GeometryModeFlags.test((size_t)(flag));
|
||||
};
|
||||
void setGeometryMode(int flag, bool v = true) override
|
||||
{
|
||||
GeometryModeFlags.set((size_t)(flag), v);
|
||||
};
|
||||
|
||||
int getGeometryLayerId() const override { return GeometryLayer;}
|
||||
void setGeometryLayerId(int geolayer) override { GeometryLayer = geolayer;}
|
||||
int getGeometryLayerId() const override
|
||||
{
|
||||
return GeometryLayer;
|
||||
}
|
||||
void setGeometryLayerId(int geolayer) override
|
||||
{
|
||||
GeometryLayer = geolayer;
|
||||
}
|
||||
|
||||
constexpr static std::array<const char *,InternalType::NumInternalGeometryType> internaltype2str {{ "None", "EllipseMajorDiameter", "EllipseMinorDiameter","EllipseFocus1", "EllipseFocus2", "HyperbolaMajor", "HyperbolaMinor", "HyperbolaFocus", "ParabolaFocus", "BSplineControlPoint", "BSplineKnotPoint", "ParabolaFocalAxis" }};
|
||||
constexpr static std::array<const char*, InternalType::NumInternalGeometryType>
|
||||
internaltype2str {{"None",
|
||||
"EllipseMajorDiameter",
|
||||
"EllipseMinorDiameter",
|
||||
"EllipseFocus1",
|
||||
"EllipseFocus2",
|
||||
"HyperbolaMajor",
|
||||
"HyperbolaMinor",
|
||||
"HyperbolaFocus",
|
||||
"ParabolaFocus",
|
||||
"BSplineControlPoint",
|
||||
"BSplineKnotPoint",
|
||||
"ParabolaFocalAxis"}};
|
||||
|
||||
constexpr static std::array<const char *,GeometryMode::NumGeometryMode> geometrymode2str {{ "Blocked", "Construction" }};
|
||||
constexpr static std::array<const char*, GeometryMode::NumGeometryMode> geometrymode2str {
|
||||
{"Blocked", "Construction"}};
|
||||
|
||||
static bool getInternalTypeFromName(std::string str, InternalType::InternalType &type);
|
||||
static bool getInternalTypeFromName(std::string str, InternalType::InternalType& type);
|
||||
|
||||
static bool getGeometryModeFromName(std::string str, GeometryMode::GeometryMode &type);
|
||||
static bool getGeometryModeFromName(std::string str, GeometryMode::GeometryMode& type);
|
||||
|
||||
protected:
|
||||
void copyAttributes(Part::GeometryExtension * cpy) const override;
|
||||
void restoreAttributes(Base::XMLReader &reader) override;
|
||||
void saveAttributes(Base::Writer &writer) const override;
|
||||
void copyAttributes(Part::GeometryExtension* cpy) const override;
|
||||
void restoreAttributes(Base::XMLReader& reader) override;
|
||||
void saveAttributes(Base::Writer& writer) const override;
|
||||
|
||||
private:
|
||||
SketchGeometryExtension(const SketchGeometryExtension&) = default;
|
||||
|
||||
private:
|
||||
using GeometryModeFlagType = std::bitset<32>;
|
||||
long Id;
|
||||
InternalType::InternalType InternalGeometryType;
|
||||
GeometryModeFlagType GeometryModeFlags;
|
||||
int GeometryLayer;
|
||||
long Id;
|
||||
InternalType::InternalType InternalGeometryType;
|
||||
GeometryModeFlagType GeometryModeFlags;
|
||||
int GeometryLayer;
|
||||
|
||||
private:
|
||||
static std::atomic<long> _GeometryID;
|
||||
};
|
||||
|
||||
} //namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCHER_SKETCHGEOMETRYEXTENSION_H
|
||||
#endif// SKETCHER_SKETCHGEOMETRYEXTENSION_H
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include "SketchGeometryExtensionPy.h"
|
||||
|
||||
#include "SketchGeometryExtensionPy.cpp"
|
||||
|
||||
|
||||
@@ -34,7 +35,7 @@ std::string SketchGeometryExtensionPy::representation() const
|
||||
std::stringstream str;
|
||||
str << "<SketchGeometryExtension (";
|
||||
|
||||
if(!getSketchGeometryExtensionPtr()->getName().empty())
|
||||
if (!getSketchGeometryExtensionPtr()->getName().empty())
|
||||
str << "\'" << getSketchGeometryExtensionPtr()->getName() << "\', ";
|
||||
|
||||
str << "\"";
|
||||
@@ -43,7 +44,8 @@ std::string SketchGeometryExtensionPy::representation() const
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *SketchGeometryExtensionPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
// Python wrapper
|
||||
PyObject* SketchGeometryExtensionPy::PyMake(struct _typeobject*, PyObject*, PyObject*)
|
||||
{
|
||||
// create a new instance of PointPy and the Twin object
|
||||
return new SketchGeometryExtensionPy(new SketchGeometryExtension);
|
||||
@@ -66,10 +68,10 @@ int SketchGeometryExtensionPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "SketchGeometryExtension constructor accepts:\n"
|
||||
"-- empty parameter list\n"
|
||||
"-- int\n");
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"SketchGeometryExtension constructor accepts:\n"
|
||||
"-- empty parameter list\n"
|
||||
"-- int\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -87,12 +89,13 @@ Py::String SketchGeometryExtensionPy::getInternalType() const
|
||||
{
|
||||
int internaltypeindex = (int)this->getSketchGeometryExtensionPtr()->getInternalType();
|
||||
|
||||
if(internaltypeindex >= InternalType::NumInternalGeometryType)
|
||||
if (internaltypeindex >= InternalType::NumInternalGeometryType)
|
||||
throw Py::NotImplementedError("String name of enum not implemented");
|
||||
|
||||
std::string typestr = this->getSketchGeometryExtensionPtr()->internaltype2str[internaltypeindex];
|
||||
std::string typestr =
|
||||
this->getSketchGeometryExtensionPtr()->internaltype2str[internaltypeindex];
|
||||
|
||||
return Py::String(typestr);
|
||||
return Py::String(typestr);
|
||||
}
|
||||
|
||||
void SketchGeometryExtensionPy::setInternalType(Py::String arg)
|
||||
@@ -100,7 +103,7 @@ void SketchGeometryExtensionPy::setInternalType(Py::String arg)
|
||||
std::string argstr = arg;
|
||||
InternalType::InternalType type;
|
||||
|
||||
if(SketchGeometryExtension::getInternalTypeFromName(argstr, type)) {
|
||||
if (SketchGeometryExtension::getInternalTypeFromName(argstr, type)) {
|
||||
this->getSketchGeometryExtensionPtr()->setInternalType(type);
|
||||
return;
|
||||
}
|
||||
@@ -120,7 +123,8 @@ void SketchGeometryExtensionPy::setBlocked(Py::Boolean arg)
|
||||
|
||||
Py::Boolean SketchGeometryExtensionPy::getConstruction() const
|
||||
{
|
||||
return Py::Boolean(getSketchGeometryExtensionPtr()->testGeometryMode(GeometryMode::Construction));
|
||||
return Py::Boolean(
|
||||
getSketchGeometryExtensionPtr()->testGeometryMode(GeometryMode::Construction));
|
||||
}
|
||||
|
||||
void SketchGeometryExtensionPy::setConstruction(Py::Boolean arg)
|
||||
@@ -128,15 +132,16 @@ void SketchGeometryExtensionPy::setConstruction(Py::Boolean arg)
|
||||
getSketchGeometryExtensionPtr()->setGeometryMode(GeometryMode::Construction, arg);
|
||||
}
|
||||
|
||||
PyObject* SketchGeometryExtensionPy::testGeometryMode(PyObject *args)
|
||||
PyObject* SketchGeometryExtensionPy::testGeometryMode(PyObject* args)
|
||||
{
|
||||
char* flag;
|
||||
if (PyArg_ParseTuple(args, "s",&flag)) {
|
||||
if (PyArg_ParseTuple(args, "s", &flag)) {
|
||||
|
||||
GeometryMode::GeometryMode mode;
|
||||
|
||||
if(getSketchGeometryExtensionPtr()->getGeometryModeFromName(flag, mode))
|
||||
return new_reference_to(Py::Boolean(getSketchGeometryExtensionPtr()->testGeometryMode(mode)));
|
||||
if (getSketchGeometryExtensionPtr()->getGeometryModeFromName(flag, mode))
|
||||
return new_reference_to(
|
||||
Py::Boolean(getSketchGeometryExtensionPtr()->testGeometryMode(mode)));
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Flag string does not exist.");
|
||||
return nullptr;
|
||||
@@ -146,15 +151,15 @@ PyObject* SketchGeometryExtensionPy::testGeometryMode(PyObject *args)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject* SketchGeometryExtensionPy::setGeometryMode(PyObject *args)
|
||||
PyObject* SketchGeometryExtensionPy::setGeometryMode(PyObject* args)
|
||||
{
|
||||
char * flag;
|
||||
PyObject * bflag = Py_True;
|
||||
char* flag;
|
||||
PyObject* bflag = Py_True;
|
||||
if (PyArg_ParseTuple(args, "s|O!", &flag, &PyBool_Type, &bflag)) {
|
||||
|
||||
GeometryMode::GeometryMode mode;
|
||||
|
||||
if(getSketchGeometryExtensionPtr()->getGeometryModeFromName(flag, mode)) {
|
||||
if (getSketchGeometryExtensionPtr()->getGeometryModeFromName(flag, mode)) {
|
||||
getSketchGeometryExtensionPtr()->setGeometryMode(mode, Base::asBoolean(bflag));
|
||||
Py_Return;
|
||||
}
|
||||
@@ -177,7 +182,7 @@ void SketchGeometryExtensionPy::setGeometryLayerId(Py::Long Id)
|
||||
this->getSketchGeometryExtensionPtr()->setGeometryLayerId(long(Id));
|
||||
}
|
||||
|
||||
PyObject *SketchGeometryExtensionPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* SketchGeometryExtensionPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -186,4 +191,3 @@ int SketchGeometryExtensionPy::setCustomAttributes(const char* /*attr*/, PyObjec
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -43,7 +43,7 @@ namespace Sketcher
|
||||
|
||||
class SketchAnalysis;
|
||||
|
||||
class SketcherExport SketchObject : public Part::Part2DObject
|
||||
class SketcherExport SketchObject: public Part::Part2DObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Sketcher::SketchObject);
|
||||
|
||||
@@ -56,34 +56,38 @@ public:
|
||||
The Geometry list contains the non-external Part::Geometry objects in the sketch. The list
|
||||
may be accessed directly, or indirectly via getInternalGeometry().
|
||||
|
||||
Many of the methods in this class take geoId and posId parameters. A GeoId is a unique identifier for
|
||||
geometry in the Sketch. geoId >= 0 means an index in the Geometry list. geoId < 0 refers to sketch
|
||||
axes and external geometry. posId is a PointPos enum, documented in Constraint.h.
|
||||
Many of the methods in this class take geoId and posId parameters. A GeoId is a unique
|
||||
identifier for geometry in the Sketch. geoId >= 0 means an index in the Geometry list. geoId <
|
||||
0 refers to sketch axes and external geometry. posId is a PointPos enum, documented in
|
||||
Constraint.h.
|
||||
*/
|
||||
Part ::PropertyGeometryList Geometry;
|
||||
Part ::PropertyGeometryList Geometry;
|
||||
Sketcher::PropertyConstraintList Constraints;
|
||||
App ::PropertyLinkSubList ExternalGeometry;
|
||||
App ::PropertyBool FullyConstrained;
|
||||
App ::PropertyLinkSubList ExternalGeometry;
|
||||
App ::PropertyBool FullyConstrained;
|
||||
/** @name methods override Feature */
|
||||
//@{
|
||||
short mustExecute() const override;
|
||||
/// recalculate the Feature (if no recompute is needed see also solve() and solverNeedsUpdate boolean)
|
||||
App::DocumentObjectExecReturn *execute() override;
|
||||
/// recalculate the Feature (if no recompute is needed see also solve() and solverNeedsUpdate
|
||||
/// boolean)
|
||||
App::DocumentObjectExecReturn* execute() override;
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName() const override {
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "SketcherGui::ViewProviderSketch";
|
||||
}
|
||||
//@}
|
||||
|
||||
/** SketchObject can work in two modes: Recompute Mode and noRecomputes Mode
|
||||
- In Recompute Mode, a recompute is necessary after each geometry addition to update the solver DoF (default)
|
||||
- In NoRecomputes Mode, no recompute is necessary after a geometry addition. If a recompute is triggered
|
||||
it is just less efficient.
|
||||
- In Recompute Mode, a recompute is necessary after each geometry addition to update the
|
||||
solver DoF (default)
|
||||
- In NoRecomputes Mode, no recompute is necessary after a geometry addition. If a recompute
|
||||
is triggered it is just less efficient.
|
||||
|
||||
This flag does not regulate whether this object will recompute or not if execute() or a recompute() is actually executed,
|
||||
it just regulates whether the solver is called or not (i.e. whether it relies on
|
||||
the solve of execute for the calculation)
|
||||
This flag does not regulate whether this object will recompute or not if execute() or a
|
||||
recompute() is actually executed, it just regulates whether the solver is called or not (i.e.
|
||||
whether it relies on the solve of execute for the calculation)
|
||||
*/
|
||||
bool noRecomputes;
|
||||
|
||||
@@ -92,24 +96,22 @@ public:
|
||||
\param geo - the geometry
|
||||
\retval bool - true if the geometry is supported
|
||||
*/
|
||||
bool isSupportedGeometry(const Part::Geometry *geo) const;
|
||||
bool isSupportedGeometry(const Part::Geometry* geo) const;
|
||||
/*!
|
||||
\brief Add geometry to a sketch - It adds a copy with a different uuid (internally uses copy() instead of clone())
|
||||
\param geo - geometry to add
|
||||
\param construction - true for construction lines
|
||||
\retval int - GeoId of added element
|
||||
\brief Add geometry to a sketch - It adds a copy with a different uuid (internally uses copy()
|
||||
instead of clone()) \param geo - geometry to add \param construction - true for construction
|
||||
lines \retval int - GeoId of added element
|
||||
*/
|
||||
int addGeometry(const Part::Geometry *geo, bool construction=false);
|
||||
int addGeometry(const Part::Geometry* geo, bool construction = false);
|
||||
|
||||
/*!
|
||||
\brief Add geometry to a sketch using up the provided newgeo. Caveat: It will use the provided newgeo with the uuid it has.
|
||||
This is different from the addGeometry method with a naked pointer, where a different uuid is ensured. The caller is responsible
|
||||
for provided a new or existing uuid, as necessary.
|
||||
\param geo - geometry to add
|
||||
\param construction - true for construction lines
|
||||
\retval int - GeoId of added element
|
||||
\brief Add geometry to a sketch using up the provided newgeo. Caveat: It will use the provided
|
||||
newgeo with the uuid it has. This is different from the addGeometry method with a naked
|
||||
pointer, where a different uuid is ensured. The caller is responsible for provided a new or
|
||||
existing uuid, as necessary. \param geo - geometry to add \param construction - true for
|
||||
construction lines \retval int - GeoId of added element
|
||||
*/
|
||||
int addGeometry(std::unique_ptr<Part::Geometry> newgeo, bool construction=false);
|
||||
int addGeometry(std::unique_ptr<Part::Geometry> newgeo, bool construction = false);
|
||||
|
||||
/*!
|
||||
\brief Add multiple geometry elements to a sketch
|
||||
@@ -117,12 +119,12 @@ public:
|
||||
\param construction - true for construction lines
|
||||
\retval int - GeoId of last added element
|
||||
*/
|
||||
int addGeometry(const std::vector<Part::Geometry *> &geoList, bool construction=false);
|
||||
int addGeometry(const std::vector<Part::Geometry*>& geoList, bool construction = false);
|
||||
/*!
|
||||
\brief Deletes indicated geometry (by geoid).
|
||||
\param GeoId - the geometry to delete
|
||||
\param deleteinternalgeo - if true deletes the associated and unconstraint internal geometry, otherwise deletes only the GeoId
|
||||
\retval int - 0 if successful
|
||||
\param deleteinternalgeo - if true deletes the associated and unconstraint internal geometry,
|
||||
otherwise deletes only the GeoId \retval int - 0 if successful
|
||||
*/
|
||||
int delGeometry(int GeoId, bool deleteinternalgeo = true);
|
||||
/// Deletes just the GeoIds indicated, it does not look for internal geometry
|
||||
@@ -134,25 +136,25 @@ public:
|
||||
/// deletes all the constraints of the sketch
|
||||
int deleteAllConstraints();
|
||||
/// add all constraints in the list
|
||||
int addConstraints(const std::vector<Constraint *> &ConstraintList);
|
||||
int addConstraints(const std::vector<Constraint*>& ConstraintList);
|
||||
/// Copy the constraints instead of cloning them and copying the expressions if any
|
||||
int addCopyOfConstraints(const SketchObject &orig);
|
||||
int addCopyOfConstraints(const SketchObject& orig);
|
||||
/// add constraint
|
||||
int addConstraint(const Constraint *constraint);
|
||||
int addConstraint(const Constraint* constraint);
|
||||
/// add constraint
|
||||
int addConstraint(std::unique_ptr<Constraint> constraint);
|
||||
/// delete constraint
|
||||
int delConstraint(int ConstrId);
|
||||
/** deletes a group of constraints at once, if norecomputes is active, the default behaviour is that
|
||||
* it will solve the sketch.
|
||||
/** deletes a group of constraints at once, if norecomputes is active, the default behaviour is
|
||||
* that it will solve the sketch.
|
||||
*
|
||||
* If updating the Geometry property as a consequence of a (successful) solve() is not wanted, updategeometry=false,
|
||||
* prevents the update. This allows to update the solve status (e.g. dof), without updating the geometry (i.e. make it
|
||||
* move to fulfil the constraints).
|
||||
* If updating the Geometry property as a consequence of a (successful) solve() is not wanted,
|
||||
* updategeometry=false, prevents the update. This allows to update the solve status (e.g. dof),
|
||||
* without updating the geometry (i.e. make it move to fulfil the constraints).
|
||||
*/
|
||||
int delConstraints(std::vector<int> ConstrIds, bool updategeometry=true);
|
||||
int delConstraintOnPoint(int GeoId, PointPos PosId, bool onlyCoincident=true);
|
||||
int delConstraintOnPoint(int VertexId, bool onlyCoincident=true);
|
||||
int delConstraints(std::vector<int> ConstrIds, bool updategeometry = true);
|
||||
int delConstraintOnPoint(int GeoId, PointPos PosId, bool onlyCoincident = true);
|
||||
int delConstraintOnPoint(int VertexId, bool onlyCoincident = true);
|
||||
/// Deletes all constraints referencing an external geometry
|
||||
int delConstraintsToExternal();
|
||||
/// transfers all constraints of a point to a new point
|
||||
@@ -160,9 +162,9 @@ public:
|
||||
bool doNotTransformTangencies = false);
|
||||
|
||||
/// Carbon copy another sketch geometry and constraints
|
||||
int carbonCopy(App::DocumentObject * pObj, bool construction = true);
|
||||
int carbonCopy(App::DocumentObject* pObj, bool construction = true);
|
||||
/// add an external geometry reference
|
||||
int addExternal(App::DocumentObject *Obj, const char* SubName);
|
||||
int addExternal(App::DocumentObject* Obj, const char* SubName);
|
||||
/** delete external
|
||||
* ExtGeoId >= 0 with 0 corresponding to the first user defined
|
||||
* external geometry
|
||||
@@ -178,23 +180,30 @@ public:
|
||||
* id==-2 for the vertical sketch axis
|
||||
* id<=-3 for user defined projected external geometries,
|
||||
*/
|
||||
template < typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<
|
||||
std::is_base_of<Part::Geometry, typename std::decay<GeometryT>::type>::value
|
||||
>::type
|
||||
>
|
||||
const GeometryT * getGeometry(int GeoId) const;
|
||||
template<typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<std::is_base_of<
|
||||
Part::Geometry, typename std::decay<GeometryT>::type>::value>::type>
|
||||
const GeometryT* getGeometry(int GeoId) const;
|
||||
|
||||
std::unique_ptr<const GeometryFacade> getGeometryFacade(int GeoId) const;
|
||||
|
||||
/// returns a list of all internal geometries
|
||||
const std::vector<Part::Geometry *> &getInternalGeometry() const { return Geometry.getValues(); }
|
||||
const std::vector<Part::Geometry*>& getInternalGeometry() const
|
||||
{
|
||||
return Geometry.getValues();
|
||||
}
|
||||
/// returns a list of projected external geometries
|
||||
const std::vector<Part::Geometry *> &getExternalGeometry() const { return ExternalGeo; }
|
||||
const std::vector<Part::Geometry*>& getExternalGeometry() const
|
||||
{
|
||||
return ExternalGeo;
|
||||
}
|
||||
/// rebuilds external geometry (projection onto the sketch plane)
|
||||
void rebuildExternalGeometry();
|
||||
/// returns the number of external Geometry entities
|
||||
int getExternalGeometryCount() const { return ExternalGeo.size(); }
|
||||
int getExternalGeometryCount() const
|
||||
{
|
||||
return ExternalGeo.size();
|
||||
}
|
||||
|
||||
/// retrieves a vector containing both normal and external Geometry (including the sketch axes)
|
||||
std::vector<Part::Geometry*> getCompleteGeometry() const;
|
||||
@@ -214,30 +223,35 @@ public:
|
||||
*/
|
||||
int setUpSketch();
|
||||
|
||||
/** Performs a full analysis of the addition of additional constraints without adding them to the sketch object */
|
||||
int diagnoseAdditionalConstraints(std::vector<Sketcher::Constraint *> additionalconstraints);
|
||||
/** Performs a full analysis of the addition of additional constraints without adding them to
|
||||
* the sketch object */
|
||||
int diagnoseAdditionalConstraints(std::vector<Sketcher::Constraint*> additionalconstraints);
|
||||
|
||||
/** solves the sketch and updates the geometry, but not all the dependent features (does not recompute)
|
||||
When a recompute is necessary, recompute triggers execute() which solves the sketch and updates all dependent features
|
||||
When a solve only is necessary (e.g. DoF changed), solve() solves the sketch and
|
||||
updates the geometry (if updateGeoAfterSolving==true), but does not trigger any recompute.
|
||||
@return 0 if no error, if error, the following codes in this order of priority: -4 if overconstrained,
|
||||
-3 if conflicting, -1 if solver error, -2 if redundant constraints
|
||||
/** solves the sketch and updates the geometry, but not all the dependent features (does not
|
||||
recompute) When a recompute is necessary, recompute triggers execute() which solves the
|
||||
sketch and updates all dependent features When a solve only is necessary (e.g. DoF changed),
|
||||
solve() solves the sketch and updates the geometry (if updateGeoAfterSolving==true), but does
|
||||
not trigger any recompute.
|
||||
@return 0 if no error, if error, the following codes in this order of priority: -4 if
|
||||
overconstrained, -3 if conflicting, -1 if solver error, -2 if redundant constraints
|
||||
*/
|
||||
int solve(bool updateGeoAfterSolving=true);
|
||||
int solve(bool updateGeoAfterSolving = true);
|
||||
/// set the datum of a Distance or Angle constraint and solve
|
||||
int setDatum(int ConstrId, double Datum);
|
||||
/// set the driving status of this constraint and solve
|
||||
int setDriving(int ConstrId, bool isdriving);
|
||||
/// get the driving status of this constraint
|
||||
int getDriving(int ConstrId, bool &isdriving);
|
||||
int getDriving(int ConstrId, bool& isdriving);
|
||||
/// toggle the driving status of this constraint
|
||||
int toggleDriving(int ConstrId) {return setDriving(ConstrId, !Constraints.getValues()[ConstrId]->isDriving);}
|
||||
int toggleDriving(int ConstrId)
|
||||
{
|
||||
return setDriving(ConstrId, !Constraints.getValues()[ConstrId]->isDriving);
|
||||
}
|
||||
|
||||
/// set the driving status of this constraint and solve
|
||||
int setActive(int ConstrId, bool isactive);
|
||||
/// get the driving status of this constraint
|
||||
int getActive(int ConstrId, bool &isactive);
|
||||
int getActive(int ConstrId, bool& isactive);
|
||||
/// toggle the driving status of this constraint
|
||||
int toggleActive(int ConstrId);
|
||||
|
||||
@@ -251,11 +265,12 @@ public:
|
||||
/// set the driving status of a group of constraints at once
|
||||
int setVirtualSpace(std::vector<int> constrIds, bool isinvirtualspace);
|
||||
/// get the driving status of this constraint
|
||||
int getVirtualSpace(int ConstrId, bool &isinvirtualspace) const;
|
||||
int getVirtualSpace(int ConstrId, bool& isinvirtualspace) const;
|
||||
/// toggle the driving status of this constraint
|
||||
int toggleVirtualSpace(int ConstrId);
|
||||
/// move this point to a new location and solve
|
||||
int movePoint(int GeoId, PointPos PosId, const Base::Vector3d& toPoint, bool relative=false, bool updateGeoBeforeMoving=false);
|
||||
int movePoint(int GeoId, PointPos PosId, const Base::Vector3d& toPoint, bool relative = false,
|
||||
bool updateGeoBeforeMoving = false);
|
||||
/// retrieves the coordinates of a point
|
||||
Base::Vector3d getPoint(int GeoId, PointPos PosId) const;
|
||||
|
||||
@@ -271,44 +286,46 @@ public:
|
||||
\param createCorner - keep geoId/pos as a Point and keep as many constraints as possible
|
||||
\retval - 0 on success, -1 on failure
|
||||
*/
|
||||
int fillet(int geoId, PointPos pos, double radius, bool trim=true, bool preserveCorner=false);
|
||||
int fillet(int geoId, PointPos pos, double radius, bool trim = true,
|
||||
bool preserveCorner = false);
|
||||
/*!
|
||||
\brief More general form of fillet
|
||||
\param geoId1, geoId2 - geoId for two lines (which don't necessarily have to coincide)
|
||||
\param refPnt1, refPnt2 - reference points on the input geometry, used to influence the free fillet variables
|
||||
\param radius - fillet radius
|
||||
\param trim - if false, leaves the original lines untouched
|
||||
\param preserveCorner - if the lines are coincident, place a Point where they meet and keep as many
|
||||
of the existing constraints as possible
|
||||
\retval - 0 on success, -1 on failure
|
||||
\param refPnt1, refPnt2 - reference points on the input geometry, used to influence the free
|
||||
fillet variables \param radius - fillet radius \param trim - if false, leaves the original
|
||||
lines untouched \param preserveCorner - if the lines are coincident, place a Point where they
|
||||
meet and keep as many of the existing constraints as possible \retval - 0 on success, -1 on
|
||||
failure
|
||||
*/
|
||||
int fillet(int geoId1, int geoId2,
|
||||
const Base::Vector3d& refPnt1, const Base::Vector3d& refPnt2,
|
||||
double radius, bool trim=true, bool createCorner=false);
|
||||
int fillet(int geoId1, int geoId2, const Base::Vector3d& refPnt1, const Base::Vector3d& refPnt2,
|
||||
double radius, bool trim = true, bool createCorner = false);
|
||||
|
||||
/// trim a curve
|
||||
int trim(int geoId, const Base::Vector3d& point);
|
||||
/// extend a curve
|
||||
int extend(int geoId, double increment, PointPos endPoint);
|
||||
/// split a curve
|
||||
int split(int geoId, const Base::Vector3d &point);
|
||||
int split(int geoId, const Base::Vector3d& point);
|
||||
/*!
|
||||
\brief Join one or two curves at the given end points
|
||||
\details The combined curve will be a b-spline
|
||||
\param geoId1, posId1, geoId2, posId2: the end points to join
|
||||
\retval - 0 on success, -1 on failure
|
||||
*/
|
||||
int join(int geoId1, Sketcher::PointPos posId1,
|
||||
int geoId2, Sketcher::PointPos posId2);
|
||||
int join(int geoId1, Sketcher::PointPos posId1, int geoId2, Sketcher::PointPos posId2);
|
||||
|
||||
/// adds symmetric geometric elements with respect to the refGeoId (line or point)
|
||||
int addSymmetric(const std::vector<int> &geoIdList, int refGeoId, Sketcher::PointPos refPosId=Sketcher::PointPos::none);
|
||||
/// with default parameters adds a copy of the geometric elements displaced by the displacement vector.
|
||||
/// It creates an array of csize elements in the direction of the displacement vector by rsize elements in the
|
||||
/// direction perpendicular to the displacement vector, wherein the modulus of this perpendicular vector is scaled by perpscale.
|
||||
int addCopy(const std::vector<int> &geoIdList, const Base::Vector3d& displacement, bool moveonly = false, bool clone=false, int csize=2, int rsize=1, bool constraindisplacement = false, double perpscale = 1.0);
|
||||
int addSymmetric(const std::vector<int>& geoIdList, int refGeoId,
|
||||
Sketcher::PointPos refPosId = Sketcher::PointPos::none);
|
||||
/// with default parameters adds a copy of the geometric elements displaced by the displacement
|
||||
/// vector. It creates an array of csize elements in the direction of the displacement vector by
|
||||
/// rsize elements in the direction perpendicular to the displacement vector, wherein the
|
||||
/// modulus of this perpendicular vector is scaled by perpscale.
|
||||
int addCopy(const std::vector<int>& geoIdList, const Base::Vector3d& displacement,
|
||||
bool moveonly = false, bool clone = false, int csize = 2, int rsize = 1,
|
||||
bool constraindisplacement = false, double perpscale = 1.0);
|
||||
|
||||
int removeAxesAlignment(const std::vector<int> &geoIdList);
|
||||
int removeAxesAlignment(const std::vector<int>& geoIdList);
|
||||
/// Exposes all internal geometry of an object supporting internal geometry
|
||||
/*!
|
||||
* \return -1 on error
|
||||
@@ -317,15 +334,16 @@ public:
|
||||
/*!
|
||||
\brief Deletes all unused (not further constrained) internal geometry
|
||||
\param GeoId - the geometry having the internal geometry to delete
|
||||
\param delgeoid - if true in addition to the unused internal geometry also deletes the GeoId geometry
|
||||
\retval int - returns -1 on error, otherwise the number of deleted elements
|
||||
\param delgeoid - if true in addition to the unused internal geometry also deletes the GeoId
|
||||
geometry \retval int - returns -1 on error, otherwise the number of deleted elements
|
||||
*/
|
||||
int deleteUnusedInternalGeometry(int GeoId, bool delgeoid=false);
|
||||
int deleteUnusedInternalGeometry(int GeoId, bool delgeoid = false);
|
||||
/*!
|
||||
\brief Approximates the given geometry with a B-spline
|
||||
\param GeoId - the geometry to approximate
|
||||
\param delgeoid - if true in addition to the unused internal geometry also deletes the GeoId geometry
|
||||
\retval bool - returns true if the approximation succeeded, or false if it did not succeed.
|
||||
\param delgeoid - if true in addition to the unused internal geometry also deletes the GeoId
|
||||
geometry \retval bool - returns true if the approximation succeeded, or false if it did not
|
||||
succeed.
|
||||
*/
|
||||
bool convertToNURBS(int GeoId);
|
||||
|
||||
@@ -333,7 +351,8 @@ public:
|
||||
\brief Increases the degree of a BSpline by degreeincrement, which defaults to 1
|
||||
\param GeoId - the geometry of type bspline to increase the degree
|
||||
\param degreeincrement - the increment in number of degrees to effect
|
||||
\retval bool - returns true if the increase in degree succeeded, or false if it did not succeed.
|
||||
\retval bool - returns true if the increase in degree succeeded, or false if it did not
|
||||
succeed.
|
||||
*/
|
||||
bool increaseBSplineDegree(int GeoId, int degreeincrement = 1);
|
||||
|
||||
@@ -341,32 +360,40 @@ public:
|
||||
\brief Decreases the degree of a BSpline by degreedecrement, which defaults to 1
|
||||
\param GeoId - the geometry of type bspline to increase the degree
|
||||
\param degreedecrement - the decrement in number of degrees to effect
|
||||
\retval bool - returns true if the decrease in degree succeeded, or false if it did not succeed.
|
||||
\retval bool - returns true if the decrease in degree succeeded, or false if it did not
|
||||
succeed.
|
||||
*/
|
||||
bool decreaseBSplineDegree(int GeoId, int degreedecrement = 1);
|
||||
|
||||
/*!
|
||||
\brief Increases or Decreases the multiplicity of a BSpline knot by the multiplicityincr param, which defaults to 1, if the result is multiplicity zero, the knot is removed
|
||||
\param GeoId - the geometry of type bspline to increase the degree
|
||||
\param knotIndex - the index of the knot to modify (note that index is OCC consistent, so 1<=knotindex<=knots)
|
||||
\param multiplicityincr - the increment (positive value) or decrement (negative value) of multiplicity of the knot
|
||||
\brief Increases or Decreases the multiplicity of a BSpline knot by the multiplicityincr param,
|
||||
which defaults to 1, if the result is multiplicity zero, the knot is removed \param GeoId - the
|
||||
geometry of type bspline to increase the degree \param knotIndex - the index of the knot to
|
||||
modify (note that index is OCC consistent, so 1<=knotindex<=knots) \param multiplicityincr -
|
||||
the increment (positive value) or decrement (negative value) of multiplicity of the knot
|
||||
\retval bool - returns true if the operation succeeded, or false if it did not succeed.
|
||||
*/
|
||||
bool modifyBSplineKnotMultiplicity(int GeoId, int knotIndex, int multiplicityincr = 1);
|
||||
|
||||
/*!
|
||||
\brief Inserts a knot in the BSpline at `param` with given `multiplicity`. If the knot already exists, its multiplicity is increased by `multiplicity`.
|
||||
\param GeoId - the geometry of type bspline to increase the degree
|
||||
\param param - the parameter value where the knot is to be placed
|
||||
\param multiplicity - multiplicity of the inserted knot
|
||||
\retval bool - returns true if the operation succeeded, or false if it did not succeed.
|
||||
\brief Inserts a knot in the BSpline at `param` with given `multiplicity`. If the knot already
|
||||
exists, its multiplicity is increased by `multiplicity`. \param GeoId - the geometry of type
|
||||
bspline to increase the degree \param param - the parameter value where the knot is to be
|
||||
placed \param multiplicity - multiplicity of the inserted knot \retval bool - returns true if
|
||||
the operation succeeded, or false if it did not succeed.
|
||||
*/
|
||||
bool insertBSplineKnot(int GeoId, double param, int multiplicity = 1);
|
||||
|
||||
/// retrieves for a Vertex number the corresponding GeoId and PosId
|
||||
void getGeoVertexIndex(int VertexId, int &GeoId, PointPos &PosId) const;
|
||||
int getHighestVertexIndex() const { return VertexId2GeoId.size() - 1; } // Most recently created
|
||||
int getHighestCurveIndex() const { return Geometry.getSize() - 1; }
|
||||
void getGeoVertexIndex(int VertexId, int& GeoId, PointPos& PosId) const;
|
||||
int getHighestVertexIndex() const
|
||||
{
|
||||
return VertexId2GeoId.size() - 1;
|
||||
}// Most recently created
|
||||
int getHighestCurveIndex() const
|
||||
{
|
||||
return Geometry.getSize() - 1;
|
||||
}
|
||||
void rebuildVertexIndex();
|
||||
|
||||
/// retrieves for a GeoId and PosId the Vertex number
|
||||
@@ -374,28 +401,32 @@ public:
|
||||
|
||||
// retrieves an array of maps, each map containing the points that are coincidence by virtue of
|
||||
// any number of direct or indirect coincidence constraints
|
||||
const std::vector< std::map<int, Sketcher::PointPos> > getCoincidenceGroups();
|
||||
// returns if the given geoId is fixed (coincident) with external geometry on any of the possible relevant points
|
||||
void isCoincidentWithExternalGeometry(int GeoId, bool &start_external, bool &mid_external, bool &end_external);
|
||||
// returns a map containing all the GeoIds that are coincident with the given point as keys, and the PosIds as values associated
|
||||
// with the keys.
|
||||
const std::vector<std::map<int, Sketcher::PointPos>> getCoincidenceGroups();
|
||||
// returns if the given geoId is fixed (coincident) with external geometry on any of the
|
||||
// possible relevant points
|
||||
void isCoincidentWithExternalGeometry(int GeoId, bool& start_external, bool& mid_external,
|
||||
bool& end_external);
|
||||
// returns a map containing all the GeoIds that are coincident with the given point as keys, and
|
||||
// the PosIds as values associated with the keys.
|
||||
const std::map<int, Sketcher::PointPos> getAllCoincidentPoints(int GeoId, PointPos PosId);
|
||||
|
||||
/// retrieves for a Vertex number a list with all coincident points (sharing a single coincidence constraint)
|
||||
void getDirectlyCoincidentPoints(int GeoId, PointPos PosId, std::vector<int> &GeoIdList,
|
||||
std::vector<PointPos> &PosIdList);
|
||||
void getDirectlyCoincidentPoints(int VertexId, std::vector<int> &GeoIdList, std::vector<PointPos> &PosIdList);
|
||||
/// retrieves for a Vertex number a list with all coincident points (sharing a single
|
||||
/// coincidence constraint)
|
||||
void getDirectlyCoincidentPoints(int GeoId, PointPos PosId, std::vector<int>& GeoIdList,
|
||||
std::vector<PointPos>& PosIdList);
|
||||
void getDirectlyCoincidentPoints(int VertexId, std::vector<int>& GeoIdList,
|
||||
std::vector<PointPos>& PosIdList);
|
||||
bool arePointsCoincident(int GeoId1, PointPos PosId1, int GeoId2, PointPos PosId2);
|
||||
|
||||
/// returns a list of indices of all constraints involving given GeoId
|
||||
void getConstraintIndices(int GeoId, std::vector<int> &constraintList);
|
||||
void getConstraintIndices(int GeoId, std::vector<int>& constraintList);
|
||||
|
||||
/// generates a warning message about constraint conflicts and appends it to the given message
|
||||
static void appendConflictMsg(const std::vector<int> &conflicting, std::string &msg);
|
||||
static void appendConflictMsg(const std::vector<int>& conflicting, std::string& msg);
|
||||
/// generates a warning message about redundant constraints and appends it to the given message
|
||||
static void appendRedundantMsg(const std::vector<int> &redundant, std::string &msg);
|
||||
static void appendRedundantMsg(const std::vector<int>& redundant, std::string& msg);
|
||||
/// generates a warning message about malformed constraints and appends it to the given message
|
||||
static void appendMalformedConstraintsMsg(const std::vector<int> &malformed, std::string &msg);
|
||||
static void appendMalformedConstraintsMsg(const std::vector<int>& malformed, std::string& msg);
|
||||
|
||||
double calculateAngleViaPoint(int geoId1, int geoId2, double px, double py);
|
||||
bool isPointOnCurve(int geoIdCurve, double px, double py);
|
||||
@@ -404,23 +435,24 @@ public:
|
||||
/// returns whether a given constraint has an associated expression or not
|
||||
bool constraintHasExpression(int constrid) const;
|
||||
|
||||
///porting functions
|
||||
/// porting functions
|
||||
int port_reversedExternalArcs(bool justAnalyze);
|
||||
|
||||
// from base class
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
unsigned int getMemSize() const override;
|
||||
void Save(Base::Writer &/*writer*/) const override;
|
||||
void Restore(Base::XMLReader &/*reader*/) override;
|
||||
void Save(Base::Writer& /*writer*/) const override;
|
||||
void Restore(Base::XMLReader& /*reader*/) override;
|
||||
|
||||
/// returns the number of construction lines (to be used as axes)
|
||||
int getAxisCount() const override;
|
||||
/// retrieves an axis iterating through the construction lines of the sketch (indices start at 0)
|
||||
/// retrieves an axis iterating through the construction lines of the sketch (indices start at
|
||||
/// 0)
|
||||
Base::Axis getAxis(int axId) const override;
|
||||
/// verify and accept the assigned geometry
|
||||
void acceptGeometry() override;
|
||||
/// Check if constraint has invalid indexes
|
||||
bool evaluateConstraint(const Constraint *constraint) const;
|
||||
bool evaluateConstraint(const Constraint* constraint) const;
|
||||
/// Check for constraints with invalid indexes
|
||||
bool evaluateConstraints() const;
|
||||
/// Remove constraints with invalid indexes
|
||||
@@ -431,109 +463,170 @@ public:
|
||||
void validateExternalLinks();
|
||||
|
||||
/// gets DoF of last solver execution
|
||||
inline int getLastDoF() const {return lastDoF;}
|
||||
inline int getLastDoF() const
|
||||
{
|
||||
return lastDoF;
|
||||
}
|
||||
/// gets HasConflicts status of last solver execution
|
||||
inline bool getLastHasConflicts() const {return lastHasConflict;}
|
||||
inline bool getLastHasConflicts() const
|
||||
{
|
||||
return lastHasConflict;
|
||||
}
|
||||
/// gets HasRedundancies status of last solver execution
|
||||
inline bool getLastHasRedundancies() const {return lastHasRedundancies;}
|
||||
inline bool getLastHasRedundancies() const
|
||||
{
|
||||
return lastHasRedundancies;
|
||||
}
|
||||
/// gets HasRedundancies status of last solver execution
|
||||
inline bool getLastHasPartialRedundancies() const {return lastHasPartialRedundancies;}
|
||||
inline bool getLastHasPartialRedundancies() const
|
||||
{
|
||||
return lastHasPartialRedundancies;
|
||||
}
|
||||
/// gets HasMalformedConstraints status of last solver execution
|
||||
inline bool getLastHasMalformedConstraints() const {return lastHasMalformedConstraints;}
|
||||
inline bool getLastHasMalformedConstraints() const
|
||||
{
|
||||
return lastHasMalformedConstraints;
|
||||
}
|
||||
/// gets solver status of last solver execution
|
||||
inline int getLastSolverStatus() const {return lastSolverStatus;}
|
||||
inline int getLastSolverStatus() const
|
||||
{
|
||||
return lastSolverStatus;
|
||||
}
|
||||
/// gets solver SolveTime of last solver execution
|
||||
inline float getLastSolveTime() const {return lastSolveTime;}
|
||||
inline float getLastSolveTime() const
|
||||
{
|
||||
return lastSolveTime;
|
||||
}
|
||||
/// gets the conflicting constraints of the last solver execution
|
||||
inline const std::vector<int> &getLastConflicting() const { return lastConflicting; }
|
||||
inline const std::vector<int>& getLastConflicting() const
|
||||
{
|
||||
return lastConflicting;
|
||||
}
|
||||
/// gets the redundant constraints of last solver execution
|
||||
inline const std::vector<int> &getLastRedundant() const { return lastRedundant; }
|
||||
inline const std::vector<int>& getLastRedundant() const
|
||||
{
|
||||
return lastRedundant;
|
||||
}
|
||||
/// gets the redundant constraints of last solver execution
|
||||
inline const std::vector<int> &getLastPartiallyRedundant() const { return lastPartiallyRedundant; }
|
||||
inline const std::vector<int>& getLastPartiallyRedundant() const
|
||||
{
|
||||
return lastPartiallyRedundant;
|
||||
}
|
||||
/// gets the redundant constraints of last solver execution
|
||||
inline const std::vector<int> &getLastMalformedConstraints() const { return lastMalformedConstraints; }
|
||||
inline const std::vector<int>& getLastMalformedConstraints() const
|
||||
{
|
||||
return lastMalformedConstraints;
|
||||
}
|
||||
|
||||
public: /* Solver exposed interface */
|
||||
/// gets the solved sketch as a reference
|
||||
inline const Sketch &getSolvedSketch() const {return solvedSketch;}
|
||||
/// enables/disables solver initial solution recalculation when moving point mode (useful for dragging)
|
||||
inline void setRecalculateInitialSolutionWhileMovingPoint(bool recalculateInitialSolutionWhileMovingPoint)
|
||||
{solvedSketch.setRecalculateInitialSolutionWhileMovingPoint(recalculateInitialSolutionWhileMovingPoint);}
|
||||
/// Forwards a request for a temporary initMove to the solver using the current sketch state as a reference (enables dragging)
|
||||
inline int initTemporaryMove(int geoId, PointPos pos, bool fine=true);
|
||||
/// Forwards a request for a temporary initBSplinePieceMove to the solver using the current sketch state as a reference (enables dragging)
|
||||
inline int initTemporaryBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint, bool fine=true);
|
||||
/** Forwards a request for point or curve temporary movement to the solver using the current state as a reference (enables dragging).
|
||||
* NOTE: A temporary move operation must always be preceded by a initTemporaryMove() operation.
|
||||
inline const Sketch& getSolvedSketch() const
|
||||
{
|
||||
return solvedSketch;
|
||||
}
|
||||
/// enables/disables solver initial solution recalculation when moving point mode (useful for
|
||||
/// dragging)
|
||||
inline void
|
||||
setRecalculateInitialSolutionWhileMovingPoint(bool recalculateInitialSolutionWhileMovingPoint)
|
||||
{
|
||||
solvedSketch.setRecalculateInitialSolutionWhileMovingPoint(
|
||||
recalculateInitialSolutionWhileMovingPoint);
|
||||
}
|
||||
/// Forwards a request for a temporary initMove to the solver using the current sketch state as
|
||||
/// a reference (enables dragging)
|
||||
inline int initTemporaryMove(int geoId, PointPos pos, bool fine = true);
|
||||
/// Forwards a request for a temporary initBSplinePieceMove to the solver using the current
|
||||
/// sketch state as a reference (enables dragging)
|
||||
inline int initTemporaryBSplinePieceMove(int geoId, PointPos pos,
|
||||
const Base::Vector3d& firstPoint, bool fine = true);
|
||||
/** Forwards a request for point or curve temporary movement to the solver using the current
|
||||
* state as a reference (enables dragging). NOTE: A temporary move operation must always be
|
||||
* preceded by a initTemporaryMove() operation.
|
||||
*/
|
||||
inline int moveTemporaryPoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool relative=false);
|
||||
inline int moveTemporaryPoint(int geoId, PointPos pos, Base::Vector3d toPoint,
|
||||
bool relative = false);
|
||||
/// forwards a request to update an extension of a geometry of the solver to the solver.
|
||||
inline void updateSolverExtension(int geoId, std::unique_ptr<Part::GeometryExtension> && ext)
|
||||
{ return solvedSketch.updateExtension(geoId, std::move(ext));}
|
||||
inline void updateSolverExtension(int geoId, std::unique_ptr<Part::GeometryExtension>&& ext)
|
||||
{
|
||||
return solvedSketch.updateExtension(geoId, std::move(ext));
|
||||
}
|
||||
|
||||
public:
|
||||
/// returns the geometric elements/vertex which the solver detects as having dependent parameters.
|
||||
/// these parameters relate to not fully constraint edges/vertices.
|
||||
void getGeometryWithDependentParameters(std::vector<std::pair<int,PointPos>>& geometrymap);
|
||||
/// returns the geometric elements/vertex which the solver detects as having dependent
|
||||
/// parameters. these parameters relate to not fully constraint edges/vertices.
|
||||
void getGeometryWithDependentParameters(std::vector<std::pair<int, PointPos>>& geometrymap);
|
||||
|
||||
/// Flag to allow external geometry from other bodies than the one this sketch belongs to
|
||||
bool isAllowedOtherBody() const {
|
||||
bool isAllowedOtherBody() const
|
||||
{
|
||||
return allowOtherBody;
|
||||
}
|
||||
void setAllowOtherBody(bool on) {
|
||||
void setAllowOtherBody(bool on)
|
||||
{
|
||||
allowOtherBody = on;
|
||||
}
|
||||
|
||||
/// Flag to allow carbon copy from misaligned geometry
|
||||
bool isAllowedUnaligned() const {
|
||||
bool isAllowedUnaligned() const
|
||||
{
|
||||
return allowUnaligned;
|
||||
}
|
||||
void setAllowUnaligned(bool on) {
|
||||
void setAllowUnaligned(bool on)
|
||||
{
|
||||
allowUnaligned = on;
|
||||
}
|
||||
|
||||
enum eReasonList{
|
||||
enum eReasonList
|
||||
{
|
||||
rlAllowed,
|
||||
rlOtherDoc,
|
||||
rlCircularReference,
|
||||
rlOtherPart,
|
||||
rlOtherBody,
|
||||
rlOtherBodyWithLinks, // for carbon copy
|
||||
rlNotASketch, // for carbon copy
|
||||
rlNonParallel, // for carbon copy
|
||||
rlAxesMisaligned, // for carbon copy
|
||||
rlOriginsMisaligned // for carbon copy
|
||||
rlOtherBodyWithLinks,// for carbon copy
|
||||
rlNotASketch, // for carbon copy
|
||||
rlNonParallel, // for carbon copy
|
||||
rlAxesMisaligned, // for carbon copy
|
||||
rlOriginsMisaligned // for carbon copy
|
||||
};
|
||||
/// Return true if this object is allowed as external geometry for the
|
||||
/// sketch. rsn argument receives the reason for disallowing.
|
||||
bool isExternalAllowed(App::Document *pDoc, App::DocumentObject *pObj, eReasonList* rsn = nullptr) const;
|
||||
bool isExternalAllowed(App::Document* pDoc, App::DocumentObject* pObj,
|
||||
eReasonList* rsn = nullptr) const;
|
||||
|
||||
bool isCarbonCopyAllowed(App::Document *pDoc, App::DocumentObject *pObj, bool & xinv, bool & yinv, eReasonList* rsn = nullptr) const;
|
||||
bool isCarbonCopyAllowed(App::Document* pDoc, App::DocumentObject* pObj, bool& xinv, bool& yinv,
|
||||
eReasonList* rsn = nullptr) const;
|
||||
|
||||
bool isPerformingInternalTransaction() const {return internaltransaction;};
|
||||
bool isPerformingInternalTransaction() const
|
||||
{
|
||||
return internaltransaction;
|
||||
};
|
||||
|
||||
/** retrieves intersection points of this curve with the closest two curves around a point of this curve.
|
||||
/** retrieves intersection points of this curve with the closest two curves around a point of
|
||||
* this curve.
|
||||
* - it includes internal and external intersecting geometry.
|
||||
* - it returns GeoEnum::GeoUndef if no intersection is found.
|
||||
*/
|
||||
bool seekTrimPoints(int GeoId, const Base::Vector3d &point,
|
||||
int &GeoId1, Base::Vector3d &intersect1,
|
||||
int &GeoId2, Base::Vector3d &intersect2);
|
||||
bool seekTrimPoints(int GeoId, const Base::Vector3d& point, int& GeoId1,
|
||||
Base::Vector3d& intersect1, int& GeoId2, Base::Vector3d& intersect2);
|
||||
|
||||
public:
|
||||
// Analyser functions
|
||||
int autoConstraint(double precision = Precision::Confusion() * 1000, double angleprecision = M_PI/20, bool includeconstruction = true);
|
||||
int autoConstraint(double precision = Precision::Confusion() * 1000,
|
||||
double angleprecision = M_PI / 20, bool includeconstruction = true);
|
||||
|
||||
int detectMissingPointOnPointConstraints(double precision = Precision::Confusion() * 1000, bool includeconstruction = true);
|
||||
void analyseMissingPointOnPointCoincident(double angleprecision = M_PI/8);
|
||||
int detectMissingVerticalHorizontalConstraints(double angleprecision = M_PI/8);
|
||||
int detectMissingPointOnPointConstraints(double precision = Precision::Confusion() * 1000,
|
||||
bool includeconstruction = true);
|
||||
void analyseMissingPointOnPointCoincident(double angleprecision = M_PI / 8);
|
||||
int detectMissingVerticalHorizontalConstraints(double angleprecision = M_PI / 8);
|
||||
int detectMissingEqualityConstraints(double precision);
|
||||
|
||||
std::vector<ConstraintIds> &getMissingPointOnPointConstraints();
|
||||
std::vector<ConstraintIds> &getMissingVerticalHorizontalConstraints();
|
||||
std::vector<ConstraintIds> &getMissingLineEqualityConstraints();
|
||||
std::vector<ConstraintIds> &getMissingRadiusConstraints();
|
||||
std::vector<ConstraintIds>& getMissingPointOnPointConstraints();
|
||||
std::vector<ConstraintIds>& getMissingVerticalHorizontalConstraints();
|
||||
std::vector<ConstraintIds>& getMissingLineEqualityConstraints();
|
||||
std::vector<ConstraintIds>& getMissingRadiusConstraints();
|
||||
|
||||
void setMissingRadiusConstraints(std::vector<ConstraintIds> &cl);
|
||||
void setMissingRadiusConstraints(std::vector<ConstraintIds>& cl);
|
||||
void setMissingLineEqualityConstraints(std::vector<ConstraintIds>& cl);
|
||||
void setMissingVerticalHorizontalConstraints(std::vector<ConstraintIds>& cl);
|
||||
void setMissingPointOnPointConstraints(std::vector<ConstraintIds>& cl);
|
||||
@@ -551,9 +644,9 @@ public:
|
||||
// Validation routines
|
||||
std::vector<Base::Vector3d> getOpenVertices() const;
|
||||
|
||||
public: // geometry extension functionalities for single element sketch object user convenience
|
||||
public:// geometry extension functionalities for single element sketch object user convenience
|
||||
int setGeometryId(int GeoId, long id);
|
||||
int getGeometryId(int GeoId, long &id) const;
|
||||
int getGeometryId(int GeoId, long& id) const;
|
||||
|
||||
protected:
|
||||
/// get called by the container when a property has changed
|
||||
@@ -561,28 +654,31 @@ protected:
|
||||
void onDocumentRestored() override;
|
||||
void restoreFinished() override;
|
||||
|
||||
void setExpression(const App::ObjectIdentifier &path, std::shared_ptr<App::Expression> expr) override;
|
||||
void setExpression(const App::ObjectIdentifier& path,
|
||||
std::shared_ptr<App::Expression> expr) override;
|
||||
|
||||
std::string validateExpression(const App::ObjectIdentifier &path, std::shared_ptr<const App::Expression> expr);
|
||||
std::string validateExpression(const App::ObjectIdentifier& path,
|
||||
std::shared_ptr<const App::Expression> expr);
|
||||
|
||||
void constraintsRenamed(const std::map<App::ObjectIdentifier, App::ObjectIdentifier> &renamed);
|
||||
void constraintsRemoved(const std::set<App::ObjectIdentifier> &removed);
|
||||
void constraintsRenamed(const std::map<App::ObjectIdentifier, App::ObjectIdentifier>& renamed);
|
||||
void constraintsRemoved(const std::set<App::ObjectIdentifier>& removed);
|
||||
/*!
|
||||
\brief Returns a list of supported geometries from the input list
|
||||
\param geoList - the geometry list
|
||||
\retval list - the supported geometry list
|
||||
*/
|
||||
std::vector<Part::Geometry *> supportedGeometry(const std::vector<Part::Geometry *> &geoList) const;
|
||||
std::vector<Part::Geometry*>
|
||||
supportedGeometry(const std::vector<Part::Geometry*>& geoList) const;
|
||||
|
||||
|
||||
/*!
|
||||
\brief Transfer constraints on lines being filleted.
|
||||
|
||||
Since filleting moves the endpoints of the input geometry, existing constraints may no longer be
|
||||
sensible. If fillet() was called with preserveCorner=false, the constraints are simply deleted.
|
||||
But if the lines are coincident and preserveCorner=true, we can preserve most constraints on the
|
||||
old end points by moving them to the preserved corner, or transforming distance constraints on
|
||||
straight lines into point-to-point distance constraints.
|
||||
Since filleting moves the endpoints of the input geometry, existing constraints may no longer
|
||||
be sensible. If fillet() was called with preserveCorner=false, the constraints are simply
|
||||
deleted. But if the lines are coincident and preserveCorner=true, we can preserve most
|
||||
constraints on the old end points by moving them to the preserved corner, or transforming
|
||||
distance constraints on straight lines into point-to-point distance constraints.
|
||||
|
||||
\param geoId1, podId1, geoId2, posId2 - The two lines that have just been filleted
|
||||
*/
|
||||
@@ -597,43 +693,39 @@ protected:
|
||||
// migration functions
|
||||
void migrateSketch();
|
||||
|
||||
static void appendConstraintsMsg(const std::vector<int> &vector,
|
||||
const std::string & singularmsg,
|
||||
const std::string & pluralmsg,
|
||||
std::string &msg);
|
||||
static void appendConstraintsMsg(const std::vector<int>& vector, const std::string& singularmsg,
|
||||
const std::string& pluralmsg, std::string& msg);
|
||||
|
||||
// retrieves redundant, conflicting and malformed constraint information from the solver
|
||||
void retrieveSolverDiagnostics();
|
||||
|
||||
// retrieves whether a geometry blocked state corresponds to this constraint
|
||||
// returns true of the constraint is of Block type, false otherwise
|
||||
bool getBlockedState(const Constraint * cstr, bool & blockedstate) const;
|
||||
bool getBlockedState(const Constraint* cstr, bool& blockedstate) const;
|
||||
|
||||
// retrieves the geometry blocked state corresponding to this constraint
|
||||
// returns true of the constraint is of InternalAlignment type, false otherwise
|
||||
bool getInternalTypeState(const Constraint * cstr, Sketcher::InternalType::InternalType & internaltypestate) const;
|
||||
bool getInternalTypeState(const Constraint* cstr,
|
||||
Sketcher::InternalType::InternalType& internaltypestate) const;
|
||||
|
||||
// Checks whether the geometry state stored in the geometry extension matches the current sketcher situation (e.g. constraints)
|
||||
// and corrects the state if not matching.
|
||||
// Checks whether the geometry state stored in the geometry extension matches the current
|
||||
// sketcher situation (e.g. constraints) and corrects the state if not matching.
|
||||
void synchroniseGeometryState();
|
||||
|
||||
// helper function to create a new constraint and move it to the Constraint Property
|
||||
void addConstraint( Sketcher::ConstraintType constrType,
|
||||
int firstGeoId,
|
||||
Sketcher::PointPos firstPos,
|
||||
int secondGeoId = GeoEnum::GeoUndef,
|
||||
Sketcher::PointPos secondPos = Sketcher::PointPos::none,
|
||||
int thirdGeoId = GeoEnum::GeoUndef,
|
||||
Sketcher::PointPos thirdPos = Sketcher::PointPos::none);
|
||||
void addConstraint(Sketcher::ConstraintType constrType, int firstGeoId,
|
||||
Sketcher::PointPos firstPos, int secondGeoId = GeoEnum::GeoUndef,
|
||||
Sketcher::PointPos secondPos = Sketcher::PointPos::none,
|
||||
int thirdGeoId = GeoEnum::GeoUndef,
|
||||
Sketcher::PointPos thirdPos = Sketcher::PointPos::none);
|
||||
|
||||
// creates a new constraint
|
||||
std::unique_ptr<Constraint> createConstraint( Sketcher::ConstraintType constrType,
|
||||
int firstGeoId,
|
||||
Sketcher::PointPos firstPos,
|
||||
int secondGeoId = GeoEnum::GeoUndef,
|
||||
Sketcher::PointPos secondPos = Sketcher::PointPos::none,
|
||||
int thirdGeoId = GeoEnum::GeoUndef,
|
||||
Sketcher::PointPos thirdPos = Sketcher::PointPos::none);
|
||||
std::unique_ptr<Constraint>
|
||||
createConstraint(Sketcher::ConstraintType constrType, int firstGeoId,
|
||||
Sketcher::PointPos firstPos, int secondGeoId = GeoEnum::GeoUndef,
|
||||
Sketcher::PointPos secondPos = Sketcher::PointPos::none,
|
||||
int thirdGeoId = GeoEnum::GeoUndef,
|
||||
Sketcher::PointPos thirdPos = Sketcher::PointPos::none);
|
||||
|
||||
private:
|
||||
/// Flag to allow external geometry from other bodies than the one this sketch belongs to
|
||||
@@ -642,15 +734,16 @@ private:
|
||||
/// Flag to allow carbon copy from misaligned geometry
|
||||
bool allowUnaligned;
|
||||
|
||||
std::vector<Part::Geometry *> ExternalGeo;
|
||||
std::vector<Part::Geometry*> ExternalGeo;
|
||||
|
||||
std::vector<int> VertexId2GeoId;
|
||||
std::vector<PointPos> VertexId2PosId;
|
||||
|
||||
Sketch solvedSketch;
|
||||
|
||||
/** this internal flag indicate that an operation modifying the geometry, but not the DoF of the sketch took place (e.g. toggle construction),
|
||||
so if next action is a movement of a point (movePoint), the geometry must be updated first.
|
||||
/** this internal flag indicate that an operation modifying the geometry, but not the DoF of the
|
||||
sketch took place (e.g. toggle construction), so if next action is a movement of a point
|
||||
(movePoint), the geometry must be updated first.
|
||||
*/
|
||||
bool solverNeedsUpdate;
|
||||
|
||||
@@ -672,73 +765,79 @@ private:
|
||||
|
||||
bool AutoLockTangencyAndPerpty(Constraint* cstr, bool bForce = false, bool bLock = true);
|
||||
|
||||
// Geometry Extensions is used to store on geometry a state that is enforced by pre-existing constraints
|
||||
// Like Block constraint and InternalAlignment constraint. This enables (more) convenient handling in ViewProviderSketch
|
||||
// and solver.
|
||||
// Geometry Extensions is used to store on geometry a state that is enforced by pre-existing
|
||||
// constraints Like Block constraint and InternalAlignment constraint. This enables (more)
|
||||
// convenient handling in ViewProviderSketch and solver.
|
||||
//
|
||||
// These functions are responsible for updating the Geometry State, currently Geometry Mode (Blocked) and
|
||||
// Geometry InternalType (BSplineKnot, BSplinePole).
|
||||
// These functions are responsible for updating the Geometry State, currently Geometry Mode
|
||||
// (Blocked) and Geometry InternalType (BSplineKnot, BSplinePole).
|
||||
//
|
||||
// The data life model for handling this state is as follows:
|
||||
// 1. Upon restore, any migration is handled to set the status for legacy files (backwards compatibility)
|
||||
// 2. Functionality adding constraints (of the relevant type) calls addGeometryState to set the status
|
||||
// 3. Functionality removing constraints (of the relevant type) calls removeGeometryState to remove the status
|
||||
// 1. Upon restore, any migration is handled to set the status for legacy files (backwards
|
||||
// compatibility)
|
||||
// 2. Functionality adding constraints (of the relevant type) calls addGeometryState to set the
|
||||
// status
|
||||
// 3. Functionality removing constraints (of the relevant type) calls removeGeometryState to
|
||||
// remove the status
|
||||
// 4. Save mechanism will ensure persistence.
|
||||
void addGeometryState(const Constraint* cstr) const;
|
||||
void removeGeometryState(const Constraint* cstr) const;
|
||||
|
||||
SketchAnalysis * analyser;
|
||||
SketchAnalysis* analyser;
|
||||
|
||||
bool internaltransaction;
|
||||
|
||||
bool managedoperation; // indicates whether changes to properties are the deed of SketchObject or not (for input validation)
|
||||
// indicates whether changes to properties are the deed of SketchObject or not (for input
|
||||
// validation)
|
||||
bool managedoperation;
|
||||
};
|
||||
|
||||
inline int SketchObject::initTemporaryMove(int geoId, PointPos pos, bool fine/*=true*/)
|
||||
inline int SketchObject::initTemporaryMove(int geoId, PointPos pos, bool fine /*=true*/)
|
||||
{
|
||||
// if a previous operation did not update the geometry (including geometry extensions)
|
||||
// or constraints (including any deleted pointer, as in renameConstraint) of the solver,
|
||||
// here we update them before starting a temporary operation.
|
||||
if(solverNeedsUpdate)
|
||||
if (solverNeedsUpdate)
|
||||
solve();
|
||||
|
||||
return solvedSketch.initMove(geoId,pos,fine);
|
||||
return solvedSketch.initMove(geoId, pos, fine);
|
||||
}
|
||||
|
||||
inline int SketchObject::initTemporaryBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint, bool fine)
|
||||
inline int SketchObject::initTemporaryBSplinePieceMove(int geoId, PointPos pos,
|
||||
const Base::Vector3d& firstPoint, bool fine)
|
||||
{
|
||||
// if a previous operation did not update the geometry (including geometry extensions)
|
||||
// or constraints (including any deleted pointer, as in renameConstraint) of the solver,
|
||||
// here we update them before starting a temporary operation.
|
||||
if(solverNeedsUpdate)
|
||||
if (solverNeedsUpdate)
|
||||
solve();
|
||||
|
||||
return solvedSketch.initBSplinePieceMove(geoId,pos,firstPoint,fine);
|
||||
return solvedSketch.initBSplinePieceMove(geoId, pos, firstPoint, fine);
|
||||
}
|
||||
|
||||
inline int SketchObject::moveTemporaryPoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool relative/*=false*/)
|
||||
inline int SketchObject::moveTemporaryPoint(int geoId, PointPos pos, Base::Vector3d toPoint,
|
||||
bool relative /*=false*/)
|
||||
{
|
||||
return solvedSketch.movePoint(geoId, pos, toPoint, relative);
|
||||
}
|
||||
|
||||
template < typename GeometryT,
|
||||
typename >
|
||||
const GeometryT * SketchObject::getGeometry(int GeoId) const
|
||||
template<typename GeometryT, typename>
|
||||
const GeometryT* SketchObject::getGeometry(int GeoId) const
|
||||
{
|
||||
if (GeoId >= 0) {
|
||||
const std::vector<Part::Geometry *> &geomlist = getInternalGeometry();
|
||||
const std::vector<Part::Geometry*>& geomlist = getInternalGeometry();
|
||||
if (GeoId < int(geomlist.size()))
|
||||
return static_cast<GeometryT *>(geomlist[GeoId]);
|
||||
return static_cast<GeometryT*>(geomlist[GeoId]);
|
||||
}
|
||||
else if (-GeoId <= int(ExternalGeo.size()))
|
||||
return static_cast<GeometryT *>(ExternalGeo[-GeoId-1]);
|
||||
return static_cast<GeometryT*>(ExternalGeo[-GeoId - 1]);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
using SketchObjectPython = App::FeaturePythonT<SketchObject>;
|
||||
|
||||
} //namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCHER_SKETCHOBJECT_H
|
||||
#endif// SKETCHER_SKETCHOBJECT_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,8 +33,11 @@ PROPERTY_SOURCE(Sketcher::SketchObjectSF, Part::Part2DObject)
|
||||
|
||||
SketchObjectSF::SketchObjectSF()
|
||||
{
|
||||
ADD_PROPERTY_TYPE(SketchFlatFile,(nullptr),"",(App::PropertyType)(App::Prop_None),
|
||||
"SketchFlat file (*.skf) which defines this sketch");
|
||||
ADD_PROPERTY_TYPE(SketchFlatFile,
|
||||
(nullptr),
|
||||
"",
|
||||
(App::PropertyType)(App::Prop_None),
|
||||
"SketchFlat file (*.skf) which defines this sketch");
|
||||
}
|
||||
|
||||
short SketchObjectSF::mustExecute() const
|
||||
@@ -44,9 +47,11 @@ short SketchObjectSF::mustExecute() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *SketchObjectSF::execute()
|
||||
App::DocumentObjectExecReturn* SketchObjectSF::execute()
|
||||
{
|
||||
Base::Console().Warning("%s: This feature is deprecated and won't be longer supported in future FreeCAD versions\n",this->getNameInDocument());
|
||||
// do nothing
|
||||
Base::Console().Warning(
|
||||
"%s: This feature is deprecated and won't be longer supported in future FreeCAD versions\n",
|
||||
this->getNameInDocument());
|
||||
// do nothing
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
namespace Sketcher
|
||||
{
|
||||
|
||||
class SketchObjectSF :public Part::Part2DObject
|
||||
class SketchObjectSF: public Part::Part2DObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Sketcher::SketchObjectSF);
|
||||
|
||||
@@ -44,21 +44,19 @@ public:
|
||||
/** @name methods override Feature */
|
||||
//@{
|
||||
/// recalculate the Feature
|
||||
App::DocumentObjectExecReturn *execute() override;
|
||||
App::DocumentObjectExecReturn* execute() override;
|
||||
short mustExecute() const override;
|
||||
/// Uses the standard ViewProvider
|
||||
//const char* getViewProviderName(void) const {
|
||||
// return "SketcherGui::ViewProviderSketchSF";
|
||||
//}
|
||||
// const char* getViewProviderName(void) const {
|
||||
// return "SketcherGui::ViewProviderSketchSF";
|
||||
// }
|
||||
//@}
|
||||
|
||||
bool save(const char* FileName);
|
||||
bool load(const char* FileName);
|
||||
|
||||
|
||||
};
|
||||
|
||||
} //namespace Part
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCH_SKETCHOBJECTSF_H
|
||||
#endif// SKETCH_SKETCHOBJECTSF_H
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
// inclusion of the generated files (generated out of SketchObjectSFPy.xml)
|
||||
#include "SketchObjectSFPy.h"
|
||||
#include "SketchObjectSFPy.cpp"
|
||||
|
||||
#include "SketchObjectSFPy.cpp"
|
||||
|
||||
using namespace Sketcher;
|
||||
|
||||
@@ -35,12 +35,12 @@ std::string SketchObjectSFPy::representation() const
|
||||
return "<SketchObjectSF object>";
|
||||
}
|
||||
|
||||
PyObject *SketchObjectSFPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* SketchObjectSFPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int SketchObjectSFPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,10 @@
|
||||
|
||||
// inclusion of the generated files (generated out of SketchPy.xml)
|
||||
#include "SketchPy.h"
|
||||
#include "SketchPy.cpp"
|
||||
#include "ConstraintPy.h"
|
||||
|
||||
#include "SketchPy.cpp"
|
||||
|
||||
#include "ConstraintPy.h"
|
||||
|
||||
using namespace Sketcher;
|
||||
using namespace Part;
|
||||
@@ -41,7 +42,7 @@ std::string SketchPy::representation() const
|
||||
return std::string("<Sketch object>");
|
||||
}
|
||||
|
||||
PyObject *SketchPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
PyObject* SketchPy::PyMake(struct _typeobject*, PyObject*, PyObject*)// Python wrapper
|
||||
{
|
||||
// create a new instance of SketchPy and the Twin object
|
||||
return new SketchPy(new Sketch());
|
||||
@@ -55,7 +56,7 @@ int SketchPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
|
||||
// +++ methods implementer ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
PyObject* SketchPy::solve(PyObject *args)
|
||||
PyObject* SketchPy::solve(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
@@ -63,23 +64,23 @@ PyObject* SketchPy::solve(PyObject *args)
|
||||
return Py::new_reference_to(Py::Long(getSketchPtr()->solve()));
|
||||
}
|
||||
|
||||
PyObject* SketchPy::addGeometry(PyObject *args)
|
||||
PyObject* SketchPy::addGeometry(PyObject* args)
|
||||
{
|
||||
PyObject *pcObj;
|
||||
PyObject* pcObj;
|
||||
if (!PyArg_ParseTuple(args, "O", &pcObj))
|
||||
return nullptr;
|
||||
|
||||
if (PyObject_TypeCheck(pcObj, &(Part::GeometryPy::Type))) {
|
||||
Part::Geometry *geo = static_cast<Part::GeometryPy*>(pcObj)->getGeometryPtr();
|
||||
Part::Geometry* geo = static_cast<Part::GeometryPy*>(pcObj)->getGeometryPtr();
|
||||
return Py::new_reference_to(Py::Long(this->getSketchPtr()->addGeometry(geo)));
|
||||
}
|
||||
else if (PyObject_TypeCheck(pcObj, &(PyList_Type)) ||
|
||||
PyObject_TypeCheck(pcObj, &(PyTuple_Type))) {
|
||||
std::vector<Part::Geometry *> geoList;
|
||||
else if (PyObject_TypeCheck(pcObj, &(PyList_Type))
|
||||
|| PyObject_TypeCheck(pcObj, &(PyTuple_Type))) {
|
||||
std::vector<Part::Geometry*> geoList;
|
||||
Py::Sequence list(pcObj);
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
if (PyObject_TypeCheck((*it).ptr(), &(Part::GeometryPy::Type))) {
|
||||
Part::Geometry *geo = static_cast<Part::GeometryPy*>((*it).ptr())->getGeometryPtr();
|
||||
Part::Geometry* geo = static_cast<Part::GeometryPy*>((*it).ptr())->getGeometryPtr();
|
||||
geoList.push_back(geo);
|
||||
}
|
||||
}
|
||||
@@ -87,7 +88,7 @@ PyObject* SketchPy::addGeometry(PyObject *args)
|
||||
int ret = this->getSketchPtr()->addGeometry(geoList) + 1;
|
||||
std::size_t numGeo = geoList.size();
|
||||
Py::Tuple tuple(numGeo);
|
||||
for (std::size_t i=0; i<numGeo; ++i) {
|
||||
for (std::size_t i = 0; i < numGeo; ++i) {
|
||||
int geoId = ret - int(numGeo - i);
|
||||
tuple.setItem(i, Py::Long(geoId));
|
||||
}
|
||||
@@ -99,9 +100,9 @@ PyObject* SketchPy::addGeometry(PyObject *args)
|
||||
throw Py::TypeError(error);
|
||||
}
|
||||
|
||||
PyObject* SketchPy::addConstraint(PyObject *args)
|
||||
PyObject* SketchPy::addConstraint(PyObject* args)
|
||||
{
|
||||
PyObject *pcObj;
|
||||
PyObject* pcObj;
|
||||
if (!PyArg_ParseTuple(args, "O", &pcObj))
|
||||
return nullptr;
|
||||
|
||||
@@ -110,7 +111,7 @@ PyObject* SketchPy::addConstraint(PyObject *args)
|
||||
Py::Sequence list(pcObj);
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
if (PyObject_TypeCheck((*it).ptr(), &(ConstraintPy::Type))) {
|
||||
Constraint *con = static_cast<ConstraintPy*>((*it).ptr())->getConstraintPtr();
|
||||
Constraint* con = static_cast<ConstraintPy*>((*it).ptr())->getConstraintPtr();
|
||||
values.push_back(con);
|
||||
}
|
||||
}
|
||||
@@ -118,14 +119,14 @@ PyObject* SketchPy::addConstraint(PyObject *args)
|
||||
int ret = getSketchPtr()->addConstraints(values) + 1;
|
||||
std::size_t numCon = values.size();
|
||||
Py::Tuple tuple(numCon);
|
||||
for (std::size_t i=0; i<numCon; ++i) {
|
||||
for (std::size_t i = 0; i < numCon; ++i) {
|
||||
int conId = ret - int(numCon - i);
|
||||
tuple.setItem(i, Py::Long(conId));
|
||||
}
|
||||
return Py::new_reference_to(tuple);
|
||||
}
|
||||
else if(PyObject_TypeCheck(pcObj, &(ConstraintPy::Type))) {
|
||||
ConstraintPy *pcObject = static_cast<ConstraintPy*>(pcObj);
|
||||
else if (PyObject_TypeCheck(pcObj, &(ConstraintPy::Type))) {
|
||||
ConstraintPy* pcObject = static_cast<ConstraintPy*>(pcObj);
|
||||
int ret = getSketchPtr()->addConstraint(pcObject->getConstraintPtr());
|
||||
return Py::new_reference_to(Py::Long(ret));
|
||||
}
|
||||
@@ -136,7 +137,7 @@ PyObject* SketchPy::addConstraint(PyObject *args)
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* SketchPy::clear(PyObject *args)
|
||||
PyObject* SketchPy::clear(PyObject* args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
@@ -146,23 +147,25 @@ PyObject* SketchPy::clear(PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject* SketchPy::movePoint(PyObject *args)
|
||||
PyObject* SketchPy::movePoint(PyObject* args)
|
||||
{
|
||||
int index1,index2;
|
||||
PyObject *pcObj;
|
||||
int relative=0;
|
||||
if (!PyArg_ParseTuple(args, "iiO!|i", &index1,&index2,&(Base::VectorPy::Type),&pcObj,&relative))
|
||||
int index1, index2;
|
||||
PyObject* pcObj;
|
||||
int relative = 0;
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "iiO!|i", &index1, &index2, &(Base::VectorPy::Type), &pcObj, &relative))
|
||||
return nullptr;
|
||||
Base::Vector3d* toPoint = static_cast<Base::VectorPy*>(pcObj)->getVectorPtr();
|
||||
|
||||
return Py::new_reference_to(Py::Long(getSketchPtr()->movePoint(index1,static_cast<Sketcher::PointPos>(index2),*toPoint,(relative>0))));
|
||||
return Py::new_reference_to(Py::Long(getSketchPtr()->movePoint(
|
||||
index1, static_cast<Sketcher::PointPos>(index2), *toPoint, (relative > 0))));
|
||||
}
|
||||
|
||||
// +++ attributes implementer ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Py::Long SketchPy::getConstraint() const
|
||||
{
|
||||
//return Py::Int();
|
||||
// return Py::Int();
|
||||
throw Py::AttributeError("Not yet implemented");
|
||||
}
|
||||
|
||||
@@ -170,7 +173,7 @@ Py::Tuple SketchPy::getConflicts() const
|
||||
{
|
||||
std::vector<int> c = getSketchPtr()->getConflicting();
|
||||
Py::Tuple t(c.size());
|
||||
for (std::size_t i=0; i<c.size(); i++) {
|
||||
for (std::size_t i = 0; i < c.size(); i++) {
|
||||
t.setItem(i, Py::Long(c[i]));
|
||||
}
|
||||
|
||||
@@ -181,7 +184,7 @@ Py::Tuple SketchPy::getRedundancies() const
|
||||
{
|
||||
std::vector<int> c = getSketchPtr()->getRedundant();
|
||||
Py::Tuple t(c.size());
|
||||
for (std::size_t i=0; i<c.size(); i++) {
|
||||
for (std::size_t i = 0; i < c.size(); i++) {
|
||||
t.setItem(i, Py::Long(c[i]));
|
||||
}
|
||||
|
||||
@@ -202,7 +205,7 @@ Py::Object SketchPy::getShape() const
|
||||
// +++ custom attributes implementer ++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
PyObject *SketchPy::getCustomAttributes(const char* /*attr*/) const
|
||||
PyObject* SketchPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -211,5 +214,3 @@ int SketchPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,23 +31,21 @@
|
||||
using namespace Sketcher;
|
||||
|
||||
//---------- Geometry Extension
|
||||
TYPESYSTEM_SOURCE(Sketcher::SolverGeometryExtension,Part::GeometryExtension)
|
||||
TYPESYSTEM_SOURCE(Sketcher::SolverGeometryExtension, Part::GeometryExtension)
|
||||
|
||||
SolverGeometryExtension::SolverGeometryExtension():
|
||||
Start(SolverGeometryExtension::Dependent),
|
||||
Mid(SolverGeometryExtension::Dependent),
|
||||
End(SolverGeometryExtension::Dependent)
|
||||
{
|
||||
SolverGeometryExtension::SolverGeometryExtension()
|
||||
: Start(SolverGeometryExtension::Dependent),
|
||||
Mid(SolverGeometryExtension::Dependent),
|
||||
End(SolverGeometryExtension::Dependent)
|
||||
{}
|
||||
|
||||
}
|
||||
|
||||
void SolverGeometryExtension::copyAttributes(Part::GeometryExtension * cpy) const
|
||||
void SolverGeometryExtension::copyAttributes(Part::GeometryExtension* cpy) const
|
||||
{
|
||||
Part::GeometryExtension::copyAttributes(cpy);
|
||||
static_cast<SolverGeometryExtension *>(cpy)->Edge = this->Edge;
|
||||
static_cast<SolverGeometryExtension *>(cpy)->Start = this->Start;
|
||||
static_cast<SolverGeometryExtension *>(cpy)->End = this->End;
|
||||
static_cast<SolverGeometryExtension *>(cpy)->Mid = this->Mid;
|
||||
static_cast<SolverGeometryExtension*>(cpy)->Edge = this->Edge;
|
||||
static_cast<SolverGeometryExtension*>(cpy)->Start = this->Start;
|
||||
static_cast<SolverGeometryExtension*>(cpy)->End = this->End;
|
||||
static_cast<SolverGeometryExtension*>(cpy)->Mid = this->Mid;
|
||||
}
|
||||
|
||||
std::unique_ptr<Part::GeometryExtension> SolverGeometryExtension::copy() const
|
||||
@@ -56,33 +54,35 @@ std::unique_ptr<Part::GeometryExtension> SolverGeometryExtension::copy() const
|
||||
|
||||
copyAttributes(cpy.get());
|
||||
|
||||
#if defined (__GNUC__) && (__GNUC__ <=4)
|
||||
#if defined(__GNUC__) && (__GNUC__ <= 4)
|
||||
return std::move(cpy);
|
||||
#else
|
||||
return cpy;
|
||||
#endif
|
||||
}
|
||||
|
||||
PyObject * SolverGeometryExtension::getPyObject()
|
||||
PyObject* SolverGeometryExtension::getPyObject()
|
||||
{
|
||||
THROWM(Base::NotImplementedError, "SolverGeometryExtension does not have a Python counterpart");
|
||||
}
|
||||
|
||||
SolverGeometryExtension::PointParameterStatus SolverGeometryExtension::getPoint(Sketcher::PointPos pos) const {
|
||||
if(pos==Sketcher::PointPos::start)
|
||||
SolverGeometryExtension::PointParameterStatus
|
||||
SolverGeometryExtension::getPoint(Sketcher::PointPos pos) const
|
||||
{
|
||||
if (pos == Sketcher::PointPos::start)
|
||||
return getStartPoint();
|
||||
if(pos==Sketcher::PointPos::end)
|
||||
if (pos == Sketcher::PointPos::end)
|
||||
return getEndPoint();
|
||||
if(pos==Sketcher::PointPos::mid)
|
||||
if (pos == Sketcher::PointPos::mid)
|
||||
return getMidPoint();
|
||||
|
||||
THROWM(Base::ValueError, "SolverGeometryExtension - getPoint: Edge is not a point");
|
||||
}
|
||||
|
||||
void SolverGeometryExtension::notifyAttachment(Part::Geometry * geo)
|
||||
void SolverGeometryExtension::notifyAttachment(Part::Geometry* geo)
|
||||
{
|
||||
// maps type to number of solver parameters taken by the edge
|
||||
static std::map<Base::Type,int> edgeParamMap = {
|
||||
static std::map<Base::Type, int> edgeParamMap = {
|
||||
{Part::GeomPoint::getClassTypeId(), 0},
|
||||
{Part::GeomLineSegment::getClassTypeId(), 0},
|
||||
{Part::GeomArcOfCircle::getClassTypeId(), 3},
|
||||
@@ -91,78 +91,80 @@ void SolverGeometryExtension::notifyAttachment(Part::Geometry * geo)
|
||||
{Part::GeomEllipse::getClassTypeId(), 3},
|
||||
{Part::GeomArcOfHyperbola::getClassTypeId(), 5},
|
||||
{Part::GeomArcOfParabola::getClassTypeId(), 4},
|
||||
{Part::GeomBSplineCurve::getClassTypeId(), 0} // is dynamic
|
||||
{Part::GeomBSplineCurve::getClassTypeId(), 0}// is dynamic
|
||||
};
|
||||
|
||||
GeometryType = geo->getTypeId();
|
||||
|
||||
auto result = edgeParamMap.find(GeometryType);
|
||||
|
||||
if( result == edgeParamMap.end() )
|
||||
THROWM(Base::TypeError, "SolverGeometryExtension - notifyAttachment - Geometry not supported!!");
|
||||
if (result == edgeParamMap.end())
|
||||
THROWM(Base::TypeError,
|
||||
"SolverGeometryExtension - notifyAttachment - Geometry not supported!!");
|
||||
|
||||
auto nedgeparams = (*result).second;
|
||||
|
||||
if(nedgeparams>0)
|
||||
if (nedgeparams > 0)
|
||||
Edge.init(nedgeparams);
|
||||
}
|
||||
|
||||
void SolverGeometryExtension::ensureType(const Base::Type & type)
|
||||
void SolverGeometryExtension::ensureType(const Base::Type& type)
|
||||
{
|
||||
if(GeometryType != type)
|
||||
THROWM(Base::TypeError, "SolverGeometryExtension - requested edge parameters do not match underlying type!");
|
||||
if (GeometryType != type)
|
||||
THROWM(Base::TypeError,
|
||||
"SolverGeometryExtension - requested edge parameters do not match underlying type!");
|
||||
}
|
||||
|
||||
SolverGeometryExtension::Point & SolverGeometryExtension::getPoint()
|
||||
SolverGeometryExtension::Point& SolverGeometryExtension::getPoint()
|
||||
{
|
||||
ensureType(Part::GeomPoint::getClassTypeId());
|
||||
return static_cast<Point &>(Edge);
|
||||
return static_cast<Point&>(Edge);
|
||||
}
|
||||
|
||||
SolverGeometryExtension::Line & SolverGeometryExtension::getLine()
|
||||
SolverGeometryExtension::Line& SolverGeometryExtension::getLine()
|
||||
{
|
||||
ensureType(Part::GeomLineSegment::getClassTypeId());
|
||||
return static_cast<Line &>(Edge);
|
||||
return static_cast<Line&>(Edge);
|
||||
}
|
||||
|
||||
SolverGeometryExtension::Arc & SolverGeometryExtension::getArc()
|
||||
SolverGeometryExtension::Arc& SolverGeometryExtension::getArc()
|
||||
{
|
||||
ensureType(Part::GeomArcOfCircle::getClassTypeId());
|
||||
return static_cast<Arc &>(Edge);
|
||||
return static_cast<Arc&>(Edge);
|
||||
}
|
||||
|
||||
SolverGeometryExtension::Circle & SolverGeometryExtension::getCircle()
|
||||
SolverGeometryExtension::Circle& SolverGeometryExtension::getCircle()
|
||||
{
|
||||
ensureType(Part::GeomCircle::getClassTypeId());
|
||||
return static_cast<Circle &>(Edge);
|
||||
return static_cast<Circle&>(Edge);
|
||||
}
|
||||
|
||||
SolverGeometryExtension::ArcOfEllipse & SolverGeometryExtension::getArcOfEllipse()
|
||||
SolverGeometryExtension::ArcOfEllipse& SolverGeometryExtension::getArcOfEllipse()
|
||||
{
|
||||
ensureType(Part::GeomArcOfEllipse::getClassTypeId());
|
||||
return static_cast<ArcOfEllipse &>(Edge);
|
||||
return static_cast<ArcOfEllipse&>(Edge);
|
||||
}
|
||||
|
||||
SolverGeometryExtension::Ellipse & SolverGeometryExtension::getEllipse()
|
||||
SolverGeometryExtension::Ellipse& SolverGeometryExtension::getEllipse()
|
||||
{
|
||||
ensureType(Part::GeomEllipse::getClassTypeId());
|
||||
return static_cast<Ellipse &>(Edge);
|
||||
return static_cast<Ellipse&>(Edge);
|
||||
}
|
||||
|
||||
SolverGeometryExtension::ArcOfHyperbola & SolverGeometryExtension::getArcOfHyperbola()
|
||||
SolverGeometryExtension::ArcOfHyperbola& SolverGeometryExtension::getArcOfHyperbola()
|
||||
{
|
||||
ensureType(Part::GeomArcOfHyperbola::getClassTypeId());
|
||||
return static_cast<ArcOfHyperbola &>(Edge);
|
||||
return static_cast<ArcOfHyperbola&>(Edge);
|
||||
}
|
||||
|
||||
SolverGeometryExtension::ArcOfParabola & SolverGeometryExtension::getArcOfParabola()
|
||||
SolverGeometryExtension::ArcOfParabola& SolverGeometryExtension::getArcOfParabola()
|
||||
{
|
||||
ensureType(Part::GeomArcOfParabola::getClassTypeId());
|
||||
return static_cast<ArcOfParabola &>(Edge);
|
||||
return static_cast<ArcOfParabola&>(Edge);
|
||||
}
|
||||
|
||||
SolverGeometryExtension::BSpline & SolverGeometryExtension::getBSpline()
|
||||
SolverGeometryExtension::BSpline& SolverGeometryExtension::getBSpline()
|
||||
{
|
||||
ensureType(Part::GeomBSplineCurve::getClassTypeId());
|
||||
return static_cast<BSpline &>(Edge);
|
||||
return static_cast<BSpline&>(Edge);
|
||||
}
|
||||
|
||||
@@ -33,55 +33,95 @@
|
||||
namespace Sketcher
|
||||
{
|
||||
|
||||
class SketcherExport SolverGeometryExtension : public Part::GeometryExtension
|
||||
class SketcherExport SolverGeometryExtension: public Part::GeometryExtension
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
enum SolverStatus {
|
||||
enum SolverStatus
|
||||
{
|
||||
FullyConstraint = 0,
|
||||
NotFullyConstraint = 1,
|
||||
NumSolverStatus
|
||||
};
|
||||
|
||||
enum ParameterStatus {
|
||||
enum ParameterStatus
|
||||
{
|
||||
Dependent = 0,
|
||||
Independent = 1,
|
||||
NumParameterStatus
|
||||
};
|
||||
|
||||
class PointParameterStatus {
|
||||
class PointParameterStatus
|
||||
{
|
||||
public:
|
||||
explicit PointParameterStatus(ParameterStatus status) {setStatus(status);}
|
||||
PointParameterStatus(ParameterStatus statusx, ParameterStatus statusy) {setStatus(statusx, statusy);}
|
||||
explicit PointParameterStatus(ParameterStatus status)
|
||||
{
|
||||
setStatus(status);
|
||||
}
|
||||
PointParameterStatus(ParameterStatus statusx, ParameterStatus statusy)
|
||||
{
|
||||
setStatus(statusx, statusy);
|
||||
}
|
||||
|
||||
PointParameterStatus(const PointParameterStatus &) = default;
|
||||
PointParameterStatus & operator=(const PointParameterStatus &) = default;
|
||||
PointParameterStatus(PointParameterStatus &&) = default;
|
||||
PointParameterStatus & operator=(PointParameterStatus &&) = default;
|
||||
PointParameterStatus(const PointParameterStatus&) = default;
|
||||
PointParameterStatus& operator=(const PointParameterStatus&) = default;
|
||||
PointParameterStatus(PointParameterStatus&&) = default;
|
||||
PointParameterStatus& operator=(PointParameterStatus&&) = default;
|
||||
|
||||
ParameterStatus getStatus() const { return (xstatus == Independent && ystatus == Independent)?Independent:Dependent;}
|
||||
ParameterStatus getStatusx() const { return xstatus;}
|
||||
ParameterStatus getStatusy() const { return ystatus;}
|
||||
ParameterStatus getStatus() const
|
||||
{
|
||||
return (xstatus == Independent && ystatus == Independent) ? Independent : Dependent;
|
||||
}
|
||||
ParameterStatus getStatusx() const
|
||||
{
|
||||
return xstatus;
|
||||
}
|
||||
ParameterStatus getStatusy() const
|
||||
{
|
||||
return ystatus;
|
||||
}
|
||||
|
||||
bool isXDoF() {return xstatus == Dependent;}
|
||||
bool isYDoF() {return ystatus == Dependent;}
|
||||
bool isXDoF()
|
||||
{
|
||||
return xstatus == Dependent;
|
||||
}
|
||||
bool isYDoF()
|
||||
{
|
||||
return ystatus == Dependent;
|
||||
}
|
||||
|
||||
int getDoFs() {
|
||||
int getDoFs()
|
||||
{
|
||||
bool xfree = isXDoF();
|
||||
bool yfree = isYDoF();
|
||||
|
||||
if(xfree && yfree)
|
||||
if (xfree && yfree)
|
||||
return 2;
|
||||
else if(xfree || yfree)
|
||||
else if (xfree || yfree)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setStatus(ParameterStatus status) {xstatus=status; ystatus=status;}
|
||||
void setStatus(ParameterStatus statusx, ParameterStatus statusy) {xstatus=statusx; ystatus=statusy;}
|
||||
void setStatusx(ParameterStatus statusx) {xstatus=statusx;}
|
||||
void setStatusy(ParameterStatus statusy) {ystatus=statusy;}
|
||||
void setStatus(ParameterStatus status)
|
||||
{
|
||||
xstatus = status;
|
||||
ystatus = status;
|
||||
}
|
||||
void setStatus(ParameterStatus statusx, ParameterStatus statusy)
|
||||
{
|
||||
xstatus = statusx;
|
||||
ystatus = statusy;
|
||||
}
|
||||
void setStatusx(ParameterStatus statusx)
|
||||
{
|
||||
xstatus = statusx;
|
||||
}
|
||||
void setStatusy(ParameterStatus statusy)
|
||||
{
|
||||
ystatus = statusy;
|
||||
}
|
||||
|
||||
private:
|
||||
ParameterStatus xstatus;
|
||||
@@ -93,108 +133,192 @@ public:
|
||||
public:
|
||||
EdgeParameterStatus() = default;
|
||||
|
||||
void init(int nparams) { pstatus.resize(nparams, ParameterStatus::Dependent);}
|
||||
|
||||
ParameterStatus getStatus() const {
|
||||
return std::all_of(pstatus.begin(), pstatus.end(), [](const auto & v){ return v == Independent;})?Independent:Dependent;
|
||||
void init(int nparams)
|
||||
{
|
||||
pstatus.resize(nparams, ParameterStatus::Dependent);
|
||||
}
|
||||
|
||||
void setStatus(ParameterStatus status) { std::fill(pstatus.begin(), pstatus.end(), status);}
|
||||
ParameterStatus getStatus() const
|
||||
{
|
||||
return std::all_of(pstatus.begin(),
|
||||
pstatus.end(),
|
||||
[](const auto& v) {
|
||||
return v == Independent;
|
||||
})
|
||||
? Independent
|
||||
: Dependent;
|
||||
}
|
||||
|
||||
void setStatus(int index, ParameterStatus status) {
|
||||
if(index >= int(pstatus.size()))
|
||||
pstatus.resize(index+1,ParameterStatus::Dependent);
|
||||
void setStatus(ParameterStatus status)
|
||||
{
|
||||
std::fill(pstatus.begin(), pstatus.end(), status);
|
||||
}
|
||||
|
||||
void setStatus(int index, ParameterStatus status)
|
||||
{
|
||||
if (index >= int(pstatus.size()))
|
||||
pstatus.resize(index + 1, ParameterStatus::Dependent);
|
||||
|
||||
pstatus.at(index) = status;
|
||||
|
||||
};
|
||||
|
||||
protected:
|
||||
std::vector<ParameterStatus> pstatus;
|
||||
|
||||
};
|
||||
|
||||
class Point : public EdgeParameterStatus
|
||||
class Point: public EdgeParameterStatus
|
||||
{
|
||||
public:
|
||||
Point() = default;
|
||||
};
|
||||
|
||||
class Line : public EdgeParameterStatus
|
||||
class Line: public EdgeParameterStatus
|
||||
{
|
||||
public:
|
||||
Line() = default;
|
||||
};
|
||||
|
||||
class Arc : public EdgeParameterStatus
|
||||
class Arc: public EdgeParameterStatus
|
||||
{
|
||||
public:
|
||||
Arc() = default;
|
||||
|
||||
ParameterStatus getRadiusStatus() const {return pstatus[0];}
|
||||
ParameterStatus getStartParameter() const {return pstatus[1];}
|
||||
ParameterStatus getEndParameter() const {return pstatus[2];}
|
||||
ParameterStatus getRadiusStatus() const
|
||||
{
|
||||
return pstatus[0];
|
||||
}
|
||||
ParameterStatus getStartParameter() const
|
||||
{
|
||||
return pstatus[1];
|
||||
}
|
||||
ParameterStatus getEndParameter() const
|
||||
{
|
||||
return pstatus[2];
|
||||
}
|
||||
};
|
||||
|
||||
class Circle : public EdgeParameterStatus
|
||||
class Circle: public EdgeParameterStatus
|
||||
{
|
||||
public:
|
||||
Circle() = default;
|
||||
|
||||
ParameterStatus getRadiusStatus() const {return pstatus[0];}
|
||||
bool isRadiusDoF() const {return pstatus[0] == Dependent;}
|
||||
ParameterStatus getRadiusStatus() const
|
||||
{
|
||||
return pstatus[0];
|
||||
}
|
||||
bool isRadiusDoF() const
|
||||
{
|
||||
return pstatus[0] == Dependent;
|
||||
}
|
||||
};
|
||||
|
||||
class ArcOfEllipse : public EdgeParameterStatus
|
||||
class ArcOfEllipse: public EdgeParameterStatus
|
||||
{
|
||||
public:
|
||||
ArcOfEllipse() = default;
|
||||
|
||||
ParameterStatus getFocusXStatus() const {return pstatus[0];}
|
||||
ParameterStatus getFocusYStatus() const {return pstatus[1];}
|
||||
ParameterStatus getFocusMinorRadiusStatus() const {return pstatus[2];}
|
||||
ParameterStatus getStartParameter() const {return pstatus[3];}
|
||||
ParameterStatus getEndParameter() const {return pstatus[4];}
|
||||
ParameterStatus getFocusXStatus() const
|
||||
{
|
||||
return pstatus[0];
|
||||
}
|
||||
ParameterStatus getFocusYStatus() const
|
||||
{
|
||||
return pstatus[1];
|
||||
}
|
||||
ParameterStatus getFocusMinorRadiusStatus() const
|
||||
{
|
||||
return pstatus[2];
|
||||
}
|
||||
ParameterStatus getStartParameter() const
|
||||
{
|
||||
return pstatus[3];
|
||||
}
|
||||
ParameterStatus getEndParameter() const
|
||||
{
|
||||
return pstatus[4];
|
||||
}
|
||||
|
||||
bool isFocusDoF() const {return pstatus[0] == Dependent || pstatus[1] == Dependent;}
|
||||
bool isMinorRadiusDoF() const {return (pstatus[2] == Dependent);}
|
||||
bool isFocusDoF() const
|
||||
{
|
||||
return pstatus[0] == Dependent || pstatus[1] == Dependent;
|
||||
}
|
||||
bool isMinorRadiusDoF() const
|
||||
{
|
||||
return (pstatus[2] == Dependent);
|
||||
}
|
||||
};
|
||||
|
||||
class Ellipse : public EdgeParameterStatus
|
||||
class Ellipse: public EdgeParameterStatus
|
||||
{
|
||||
public:
|
||||
Ellipse() = default;
|
||||
|
||||
ParameterStatus getFocusXStatus() const {return pstatus[0];}
|
||||
ParameterStatus getFocusYStatus() const {return pstatus[1];}
|
||||
ParameterStatus getFocusMinorRadiusStatus() const {return pstatus[2];}
|
||||
ParameterStatus getFocusXStatus() const
|
||||
{
|
||||
return pstatus[0];
|
||||
}
|
||||
ParameterStatus getFocusYStatus() const
|
||||
{
|
||||
return pstatus[1];
|
||||
}
|
||||
ParameterStatus getFocusMinorRadiusStatus() const
|
||||
{
|
||||
return pstatus[2];
|
||||
}
|
||||
|
||||
bool isFocusDoF() const {return pstatus[0] == Dependent || pstatus[1] == Dependent;}
|
||||
bool isMinorRadiusDoF() const {return (pstatus[2] == Dependent);}
|
||||
bool isFocusDoF() const
|
||||
{
|
||||
return pstatus[0] == Dependent || pstatus[1] == Dependent;
|
||||
}
|
||||
bool isMinorRadiusDoF() const
|
||||
{
|
||||
return (pstatus[2] == Dependent);
|
||||
}
|
||||
};
|
||||
|
||||
class ArcOfHyperbola : public EdgeParameterStatus
|
||||
class ArcOfHyperbola: public EdgeParameterStatus
|
||||
{
|
||||
public:
|
||||
ArcOfHyperbola() = default;
|
||||
|
||||
ParameterStatus getFocusXStatus() const {return pstatus[0];}
|
||||
ParameterStatus getFocusYStatus() const {return pstatus[1];}
|
||||
ParameterStatus getFocusMinorRadiusStatus() const {return pstatus[2];}
|
||||
ParameterStatus getStartParameter() const {return pstatus[3];}
|
||||
ParameterStatus getEndParameter() const {return pstatus[4];}
|
||||
ParameterStatus getFocusXStatus() const
|
||||
{
|
||||
return pstatus[0];
|
||||
}
|
||||
ParameterStatus getFocusYStatus() const
|
||||
{
|
||||
return pstatus[1];
|
||||
}
|
||||
ParameterStatus getFocusMinorRadiusStatus() const
|
||||
{
|
||||
return pstatus[2];
|
||||
}
|
||||
ParameterStatus getStartParameter() const
|
||||
{
|
||||
return pstatus[3];
|
||||
}
|
||||
ParameterStatus getEndParameter() const
|
||||
{
|
||||
return pstatus[4];
|
||||
}
|
||||
};
|
||||
|
||||
class ArcOfParabola : public EdgeParameterStatus
|
||||
class ArcOfParabola: public EdgeParameterStatus
|
||||
{
|
||||
public:
|
||||
ArcOfParabola() = default;
|
||||
|
||||
ParameterStatus getFocusXStatus() const {return pstatus[0];}
|
||||
ParameterStatus getFocusYStatus() const {return pstatus[1];}
|
||||
ParameterStatus getFocusXStatus() const
|
||||
{
|
||||
return pstatus[0];
|
||||
}
|
||||
ParameterStatus getFocusYStatus() const
|
||||
{
|
||||
return pstatus[1];
|
||||
}
|
||||
};
|
||||
|
||||
class BSpline : public EdgeParameterStatus
|
||||
class BSpline: public EdgeParameterStatus
|
||||
{
|
||||
public:
|
||||
BSpline() = default;
|
||||
@@ -203,30 +327,28 @@ public:
|
||||
{
|
||||
int npoles = pstatus.size() / 3;
|
||||
|
||||
if(poleindex < npoles)
|
||||
return pstatus[poleindex*2];
|
||||
if (poleindex < npoles)
|
||||
return pstatus[poleindex * 2];
|
||||
|
||||
THROWM(Base::IndexError, "Pole index out of range")
|
||||
|
||||
}
|
||||
|
||||
ParameterStatus getPoleYStatus(int poleindex) const
|
||||
{
|
||||
int npoles = pstatus.size() / 3;
|
||||
|
||||
if(poleindex < npoles)
|
||||
return pstatus[poleindex*2+1];
|
||||
if (poleindex < npoles)
|
||||
return pstatus[poleindex * 2 + 1];
|
||||
|
||||
THROWM(Base::IndexError, "Pole index out of range")
|
||||
|
||||
}
|
||||
|
||||
ParameterStatus getWeightStatus(int weightindex) const
|
||||
{
|
||||
int nweights = pstatus.size() / 3;
|
||||
|
||||
if(weightindex < nweights)
|
||||
return pstatus[nweights*2 + weightindex];
|
||||
if (weightindex < nweights)
|
||||
return pstatus[nweights * 2 + weightindex];
|
||||
|
||||
THROWM(Base::IndexError, "Weight index out of range")
|
||||
}
|
||||
@@ -238,51 +360,112 @@ public:
|
||||
|
||||
std::unique_ptr<Part::GeometryExtension> copy() const override;
|
||||
|
||||
PyObject *getPyObject() override;
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
void notifyAttachment(Part::Geometry * geo) override;
|
||||
void notifyAttachment(Part::Geometry* geo) override;
|
||||
|
||||
SolverStatus getGeometry() const {return ( Edge.getStatus() == Independent &&
|
||||
Start.getStatus() == Independent &&
|
||||
End.getStatus() == Independent &&
|
||||
Mid.getStatus() == Independent) ? FullyConstraint : NotFullyConstraint;}
|
||||
SolverStatus getGeometry() const
|
||||
{
|
||||
return (Edge.getStatus() == Independent && Start.getStatus() == Independent
|
||||
&& End.getStatus() == Independent && Mid.getStatus() == Independent)
|
||||
? FullyConstraint
|
||||
: NotFullyConstraint;
|
||||
}
|
||||
|
||||
ParameterStatus getEdge() const {return Edge.getStatus();}
|
||||
Point & getPoint();
|
||||
Line & getLine();
|
||||
Arc & getArc();
|
||||
Circle & getCircle();
|
||||
ArcOfEllipse & getArcOfEllipse();
|
||||
Ellipse & getEllipse();
|
||||
ArcOfHyperbola & getArcOfHyperbola();
|
||||
ArcOfParabola & getArcOfParabola();
|
||||
BSpline & getBSpline();
|
||||
EdgeParameterStatus getEdgeParameters() {return Edge;}
|
||||
void setEdge(ParameterStatus status) {Edge.setStatus(status);}
|
||||
void setEdge(int paramindex, ParameterStatus status) {Edge.setStatus(paramindex,status);}
|
||||
ParameterStatus getEdge() const
|
||||
{
|
||||
return Edge.getStatus();
|
||||
}
|
||||
Point& getPoint();
|
||||
Line& getLine();
|
||||
Arc& getArc();
|
||||
Circle& getCircle();
|
||||
ArcOfEllipse& getArcOfEllipse();
|
||||
Ellipse& getEllipse();
|
||||
ArcOfHyperbola& getArcOfHyperbola();
|
||||
ArcOfParabola& getArcOfParabola();
|
||||
BSpline& getBSpline();
|
||||
EdgeParameterStatus getEdgeParameters()
|
||||
{
|
||||
return Edge;
|
||||
}
|
||||
void setEdge(ParameterStatus status)
|
||||
{
|
||||
Edge.setStatus(status);
|
||||
}
|
||||
void setEdge(int paramindex, ParameterStatus status)
|
||||
{
|
||||
Edge.setStatus(paramindex, status);
|
||||
}
|
||||
|
||||
ParameterStatus getStart() const {return Start.getStatus();}
|
||||
PointParameterStatus getStartPoint() const {return Start;}
|
||||
void setStart(ParameterStatus xstatus, ParameterStatus ystatus) {Start.setStatus(xstatus,ystatus);}
|
||||
void setStartx(ParameterStatus xstatus) {Start.setStatusx(xstatus);}
|
||||
void setStarty(ParameterStatus ystatus) {Start.setStatusy(ystatus);}
|
||||
ParameterStatus getStart() const
|
||||
{
|
||||
return Start.getStatus();
|
||||
}
|
||||
PointParameterStatus getStartPoint() const
|
||||
{
|
||||
return Start;
|
||||
}
|
||||
void setStart(ParameterStatus xstatus, ParameterStatus ystatus)
|
||||
{
|
||||
Start.setStatus(xstatus, ystatus);
|
||||
}
|
||||
void setStartx(ParameterStatus xstatus)
|
||||
{
|
||||
Start.setStatusx(xstatus);
|
||||
}
|
||||
void setStarty(ParameterStatus ystatus)
|
||||
{
|
||||
Start.setStatusy(ystatus);
|
||||
}
|
||||
|
||||
ParameterStatus getMid() const {return Mid.getStatus();}
|
||||
PointParameterStatus getMidPoint() const {return Mid;}
|
||||
void setMid(ParameterStatus xstatus, ParameterStatus ystatus) {Mid.setStatus(xstatus,ystatus);}
|
||||
void setMidx(ParameterStatus xstatus) {Mid.setStatusx(xstatus);}
|
||||
void setMidy(ParameterStatus ystatus) {Mid.setStatusy(ystatus);}
|
||||
ParameterStatus getMid() const
|
||||
{
|
||||
return Mid.getStatus();
|
||||
}
|
||||
PointParameterStatus getMidPoint() const
|
||||
{
|
||||
return Mid;
|
||||
}
|
||||
void setMid(ParameterStatus xstatus, ParameterStatus ystatus)
|
||||
{
|
||||
Mid.setStatus(xstatus, ystatus);
|
||||
}
|
||||
void setMidx(ParameterStatus xstatus)
|
||||
{
|
||||
Mid.setStatusx(xstatus);
|
||||
}
|
||||
void setMidy(ParameterStatus ystatus)
|
||||
{
|
||||
Mid.setStatusy(ystatus);
|
||||
}
|
||||
|
||||
ParameterStatus getEnd() const {return End.getStatus();}
|
||||
PointParameterStatus getEndPoint() const {return End;}
|
||||
ParameterStatus getEnd() const
|
||||
{
|
||||
return End.getStatus();
|
||||
}
|
||||
PointParameterStatus getEndPoint() const
|
||||
{
|
||||
return End;
|
||||
}
|
||||
|
||||
void setEnd(ParameterStatus xstatus, ParameterStatus ystatus) {End.setStatus(xstatus,ystatus);}
|
||||
void setEndx(ParameterStatus xstatus) {End.setStatusx(xstatus);}
|
||||
void setEndy(ParameterStatus ystatus) {End.setStatusy(ystatus);}
|
||||
void setEnd(ParameterStatus xstatus, ParameterStatus ystatus)
|
||||
{
|
||||
End.setStatus(xstatus, ystatus);
|
||||
}
|
||||
void setEndx(ParameterStatus xstatus)
|
||||
{
|
||||
End.setStatusx(xstatus);
|
||||
}
|
||||
void setEndy(ParameterStatus ystatus)
|
||||
{
|
||||
End.setStatusy(ystatus);
|
||||
}
|
||||
|
||||
PointParameterStatus getPoint(Sketcher::PointPos pos) const;
|
||||
|
||||
void init(ParameterStatus status) {
|
||||
void init(ParameterStatus status)
|
||||
{
|
||||
Edge.setStatus(status);
|
||||
Start.setStatus(status);
|
||||
Mid.setStatus(status);
|
||||
@@ -290,24 +473,24 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
void copyAttributes(Part::GeometryExtension * cpy) const override;
|
||||
void copyAttributes(Part::GeometryExtension* cpy) const override;
|
||||
|
||||
private:
|
||||
SolverGeometryExtension(const SolverGeometryExtension&) = default;
|
||||
|
||||
void ensureType(const Base::Type & type);
|
||||
void ensureType(const Base::Type& type);
|
||||
|
||||
private:
|
||||
EdgeParameterStatus Edge;
|
||||
EdgeParameterStatus Edge;
|
||||
|
||||
PointParameterStatus Start;
|
||||
PointParameterStatus Mid;
|
||||
PointParameterStatus End;
|
||||
PointParameterStatus Start;
|
||||
PointParameterStatus Mid;
|
||||
PointParameterStatus End;
|
||||
|
||||
Base::Type GeometryType;
|
||||
Base::Type GeometryType;
|
||||
};
|
||||
|
||||
} //namespace Sketcher
|
||||
}// namespace Sketcher
|
||||
|
||||
|
||||
#endif // SKETCHER_SOLVERGEOMETRYEXTENSION_H
|
||||
#endif// SKETCHER_SOLVERGEOMETRYEXTENSION_H
|
||||
|
||||
Reference in New Issue
Block a user