Sketcher New Feature: Ellipse support
- Ellipse introduction button via (center,majaxis extreme, a point in edge), ellipse is always CCW so that Z axis goes in the positive direction of the sketch - Backwards compatibility with files of previous versions of ellipse not defining a phi angle - Art by Jim (all the icons you see and the XPMs shown on creation of an ellipse) - Element Widget support for ellipses - Box selection for ellipses - Point on Ellipse constraint based on the gardener's method based on Ulrich's function proposal (radcan simplified, i.e. with simplify_radical sage function) - Tangent: Ellipse to Line based on DeepSOIC's geometric formulation (radcan simplified) Sketcher New Feature: Internal Alignment Constraint - The element to which internal alignment is applied has to be selected last. - All other elements are added in the order of priority, taking into account existing elements - Art by Jim (beautiful icons). Sketcher New Feature: Tool to show/hide/restore the internal geometry of an element - New functionality for show/hide internal geometry: toggles between hiding all unused internal geometry elements and showing all internal geometry. The restore function is implicit to the showing all internal geometry Sketcher New Feature: Arc of Ellipse support - Part::Geometry + Python implementation - ArcOfEllipse creation method - Art by Jim (all the icons you see and the XPMs shown on creation of arc of ellipse elements) - Sketcher Element widget for ArcOfEllipse. Bug fix: Select elements associated to constraints works now for foci internal alignment constraints
This commit is contained in:
@@ -66,6 +66,7 @@
|
||||
#include "EllipsePy.h"
|
||||
#include "ArcPy.h"
|
||||
#include "ArcOfCirclePy.h"
|
||||
#include "ArcOfEllipsePy.h"
|
||||
#include "BezierCurvePy.h"
|
||||
#include "BSplineCurvePy.h"
|
||||
#include "HyperbolaPy.h"
|
||||
@@ -172,6 +173,7 @@ void PartExport initPart()
|
||||
Base::Interpreter().addType(&Part::ParabolaPy ::Type,partModule,"Parabola");
|
||||
Base::Interpreter().addType(&Part::ArcPy ::Type,partModule,"Arc");
|
||||
Base::Interpreter().addType(&Part::ArcOfCirclePy ::Type,partModule,"ArcOfCircle");
|
||||
Base::Interpreter().addType(&Part::ArcOfEllipsePy ::Type,partModule,"ArcOfEllipse");
|
||||
Base::Interpreter().addType(&Part::BezierCurvePy ::Type,partModule,"BezierCurve");
|
||||
Base::Interpreter().addType(&Part::BSplineCurvePy ::Type,partModule,"BSplineCurve");
|
||||
Base::Interpreter().addType(&Part::OffsetCurvePy ::Type,partModule,"OffsetCurve");
|
||||
@@ -261,6 +263,7 @@ void PartExport initPart()
|
||||
Part::GeomBSplineCurve ::init();
|
||||
Part::GeomCircle ::init();
|
||||
Part::GeomArcOfCircle ::init();
|
||||
Part::GeomArcOfEllipse ::init();
|
||||
Part::GeomEllipse ::init();
|
||||
Part::GeomHyperbola ::init();
|
||||
Part::GeomParabola ::init();
|
||||
|
||||
54
src/Mod/Part/App/ArcOfEllipsePy.xml
Normal file
54
src/Mod/Part/App/ArcOfEllipsePy.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="GeometryCurvePy"
|
||||
Name="ArcOfEllipsePy"
|
||||
Twin="GeomArcOfEllipse"
|
||||
TwinPointer="GeomArcOfEllipse"
|
||||
Include="Mod/Part/App/Geometry.h"
|
||||
Namespace="Part"
|
||||
FatherInclude="Mod/Part/App/GeometryCurvePy.h"
|
||||
FatherNamespace="Part"
|
||||
Constructor="true">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Abdullah Tahiri" EMail="abdullah.tahiri.yo[at]gmail.com" />
|
||||
<UserDocu>Describes a portion of an ellipse</UserDocu>
|
||||
</Documentation>
|
||||
<Attribute Name="MajorRadius" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>The major radius of the ellipse.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="MajorRadius" Type="Float"/>
|
||||
</Attribute>
|
||||
<Attribute Name="MinorRadius" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>The minor radius of the ellipse.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="MinorRadius" Type="Float"/>
|
||||
</Attribute>
|
||||
<Attribute Name="AngleXU" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>The angle between the X axis and the major axis of the ellipse.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="AngleXU" Type="Float"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Center" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Center of the ellipse.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Center" Type="Object"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Axis" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>The axis direction of the ellipse</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Axis" Type="Object"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Ellipse" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The internal ellipse representation</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Ellipse" Type="Object"/>
|
||||
</Attribute>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
233
src/Mod/Part/App/ArcOfEllipsePyImp.cpp
Normal file
233
src/Mod/Part/App/ArcOfEllipsePyImp.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2014 Abdullah Tahiri <abdullah.tahiri.yo@gmail.com *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <gp_Elips.hxx>
|
||||
# include <Geom_Ellipse.hxx>
|
||||
# include <GC_MakeArcOfEllipse.hxx>
|
||||
# include <GC_MakeEllipse.hxx>
|
||||
# include <Geom_TrimmedCurve.hxx>
|
||||
#endif
|
||||
|
||||
#include "Mod/Part/App/Geometry.h"
|
||||
#include "ArcOfEllipsePy.h"
|
||||
#include "ArcOfEllipsePy.cpp"
|
||||
#include "EllipsePy.h"
|
||||
#include "OCCError.h"
|
||||
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
#include <Base/VectorPy.h>
|
||||
|
||||
using namespace Part;
|
||||
|
||||
extern const char* gce_ErrorStatusText(gce_ErrorType et);
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string ArcOfEllipsePy::representation(void) const
|
||||
{
|
||||
Handle_Geom_TrimmedCurve trim = Handle_Geom_TrimmedCurve::DownCast
|
||||
(getGeomArcOfEllipsePtr()->handle());
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(trim->BasisCurve());
|
||||
|
||||
gp_Ax1 axis = ellipse->Axis();
|
||||
gp_Dir dir = axis.Direction();
|
||||
gp_Pnt loc = axis.Location();
|
||||
Standard_Real fMajRad = ellipse->MajorRadius();
|
||||
Standard_Real fMinRad = ellipse->MinorRadius();
|
||||
Standard_Real u1 = trim->FirstParameter();
|
||||
Standard_Real u2 = trim->LastParameter();
|
||||
|
||||
gp_Dir normal = ellipse->Axis().Direction();
|
||||
gp_Dir xdir = ellipse->XAxis().Direction();
|
||||
|
||||
gp_Ax2 xdirref(loc, normal); // this is a reference XY for the ellipse
|
||||
|
||||
Standard_Real fAngleXU = -xdir.AngleWithRef(xdirref.XDirection(),normal);
|
||||
|
||||
|
||||
std::stringstream str;
|
||||
str << "ArcOfEllipse (";
|
||||
str << "MajorRadius : " << fMajRad << ", ";
|
||||
str << "MinorRadius : " << fMinRad << ", ";
|
||||
str << "AngleXU : " << fAngleXU << ", ";
|
||||
str << "Position : (" << loc.X() << ", "<< loc.Y() << ", "<< loc.Z() << "), ";
|
||||
str << "Direction : (" << dir.X() << ", "<< dir.Y() << ", "<< dir.Z() << "), ";
|
||||
str << "Parameter : (" << u1 << ", " << u2 << ")";
|
||||
str << ")";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *ArcOfEllipsePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
{
|
||||
// create a new instance of ArcOfEllipsePy and the Twin object
|
||||
return new ArcOfEllipsePy(new GeomArcOfEllipse);
|
||||
}
|
||||
|
||||
// constructor method
|
||||
int ArcOfEllipsePy::PyInit(PyObject* args, PyObject* kwds)
|
||||
{
|
||||
PyObject* o;
|
||||
double u1, u2;
|
||||
PyObject *sense=Py_True;
|
||||
if (PyArg_ParseTuple(args, "O!dd|O!", &(Part::EllipsePy::Type), &o, &u1, &u2, &PyBool_Type, &sense)) {
|
||||
try {
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast
|
||||
(static_cast<EllipsePy*>(o)->getGeomEllipsePtr()->handle());
|
||||
GC_MakeArcOfEllipse arc(ellipse->Elips(), u1, u2, PyObject_IsTrue(sense) ? Standard_True : Standard_False);
|
||||
if (!arc.IsDone()) {
|
||||
PyErr_SetString(PartExceptionOCCError, gce_ErrorStatusText(arc.Status()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
getGeomArcOfEllipsePtr()->setHandle(arc.Value());
|
||||
return 0;
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
|
||||
return -1;
|
||||
}
|
||||
catch (...) {
|
||||
PyErr_SetString(PartExceptionOCCError, "creation of arc failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// All checks failed
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"ArcOfEllipse constructor expects an ellipse curve and a parameter range");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py::Float ArcOfEllipsePy::getMajorRadius(void) const
|
||||
{
|
||||
return Py::Float(getGeomArcOfEllipsePtr()->getMajorRadius());
|
||||
}
|
||||
|
||||
void ArcOfEllipsePy::setMajorRadius(Py::Float arg)
|
||||
{
|
||||
getGeomArcOfEllipsePtr()->setMajorRadius((double)arg);
|
||||
}
|
||||
|
||||
Py::Float ArcOfEllipsePy::getMinorRadius(void) const
|
||||
{
|
||||
return Py::Float(getGeomArcOfEllipsePtr()->getMinorRadius());
|
||||
}
|
||||
|
||||
void ArcOfEllipsePy::setMinorRadius(Py::Float arg)
|
||||
{
|
||||
getGeomArcOfEllipsePtr()->setMinorRadius((double)arg);
|
||||
}
|
||||
|
||||
Py::Float ArcOfEllipsePy::getAngleXU(void) const
|
||||
{
|
||||
return Py::Float(getGeomArcOfEllipsePtr()->getAngleXU());
|
||||
}
|
||||
|
||||
void ArcOfEllipsePy::setAngleXU(Py::Float arg)
|
||||
{
|
||||
getGeomArcOfEllipsePtr()->setAngleXU((double)arg);
|
||||
}
|
||||
|
||||
Py::Object ArcOfEllipsePy::getCenter(void) const
|
||||
{
|
||||
return Py::Vector(getGeomArcOfEllipsePtr()->getCenter());
|
||||
}
|
||||
|
||||
void ArcOfEllipsePy::setCenter(Py::Object arg)
|
||||
{
|
||||
PyObject* p = arg.ptr();
|
||||
if (PyObject_TypeCheck(p, &(Base::VectorPy::Type))) {
|
||||
Base::Vector3d loc = static_cast<Base::VectorPy*>(p)->value();
|
||||
getGeomArcOfEllipsePtr()->setCenter(loc);
|
||||
}
|
||||
else if (PyObject_TypeCheck(p, &PyTuple_Type)) {
|
||||
Base::Vector3d loc = Base::getVectorFromTuple<double>(p);
|
||||
getGeomArcOfEllipsePtr()->setCenter(loc);
|
||||
}
|
||||
else {
|
||||
std::string error = std::string("type must be 'Vector', not ");
|
||||
error += p->ob_type->tp_name;
|
||||
throw Py::TypeError(error);
|
||||
}
|
||||
}
|
||||
|
||||
Py::Object ArcOfEllipsePy::getAxis(void) const
|
||||
{
|
||||
Handle_Geom_TrimmedCurve trim = Handle_Geom_TrimmedCurve::DownCast
|
||||
(getGeomArcOfEllipsePtr()->handle());
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(trim->BasisCurve());
|
||||
gp_Ax1 axis = ellipse->Axis();
|
||||
gp_Dir dir = axis.Direction();
|
||||
return Py::Vector(Base::Vector3d(dir.X(), dir.Y(), dir.Z()));
|
||||
}
|
||||
|
||||
void ArcOfEllipsePy::setAxis(Py::Object arg)
|
||||
{
|
||||
PyObject* p = arg.ptr();
|
||||
Base::Vector3d val;
|
||||
if (PyObject_TypeCheck(p, &(Base::VectorPy::Type))) {
|
||||
val = static_cast<Base::VectorPy*>(p)->value();
|
||||
}
|
||||
else if (PyTuple_Check(p)) {
|
||||
val = Base::getVectorFromTuple<double>(p);
|
||||
}
|
||||
else {
|
||||
std::string error = std::string("type must be 'Vector', not ");
|
||||
error += p->ob_type->tp_name;
|
||||
throw Py::TypeError(error);
|
||||
}
|
||||
|
||||
Handle_Geom_TrimmedCurve trim = Handle_Geom_TrimmedCurve::DownCast
|
||||
(getGeomArcOfEllipsePtr()->handle());
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(trim->BasisCurve());
|
||||
try {
|
||||
gp_Ax1 axis;
|
||||
axis.SetLocation(ellipse->Location());
|
||||
axis.SetDirection(gp_Dir(val.x, val.y, val.z));
|
||||
ellipse->SetAxis(axis);
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
throw Py::Exception("cannot set axis");
|
||||
}
|
||||
}
|
||||
|
||||
Py::Object ArcOfEllipsePy::getEllipse(void) const
|
||||
{
|
||||
Handle_Geom_TrimmedCurve trim = Handle_Geom_TrimmedCurve::DownCast
|
||||
(getGeomArcOfEllipsePtr()->handle());
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(trim->BasisCurve());
|
||||
return Py::Object(new EllipsePy(new GeomEllipse(ellipse)), true);
|
||||
}
|
||||
|
||||
PyObject *ArcOfEllipsePy::getCustomAttributes(const char* attr) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ArcOfEllipsePy::setCustomAttributes(const char* attr, PyObject *obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -21,5 +21,12 @@
|
||||
const Geom_Circle & value(void) const {return *getGeom_CirclePtr();}
|
||||
</ClassDeclarations>
|
||||
-->
|
||||
<!--
|
||||
<ClassDeclarations>public:
|
||||
ArcPy(const Geom_Ellipse & circ, PyTypeObject *T = &Type)
|
||||
:PyObjectBase(new Geom_Ellipse(circ),T){}
|
||||
const Geom_Ellipse & value(void) const {return *getGeom_EllipsePtr();}
|
||||
</ClassDeclarations>
|
||||
-->
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
|
||||
@@ -40,6 +40,7 @@ endif(FREETYPE_FOUND)
|
||||
generate_from_xml(ArcPy)
|
||||
generate_from_xml(ArcOfCirclePy)
|
||||
generate_from_xml(CirclePy)
|
||||
generate_from_xml(ArcOfEllipsePy)
|
||||
generate_from_xml(EllipsePy)
|
||||
generate_from_xml(HyperbolaPy)
|
||||
generate_from_xml(ParabolaPy)
|
||||
@@ -148,6 +149,8 @@ SET(Python_SRCS
|
||||
ArcOfCirclePyImp.cpp
|
||||
CirclePy.xml
|
||||
CirclePyImp.cpp
|
||||
ArcOfEllipsePy.xml
|
||||
ArcOfEllipsePyImp.cpp
|
||||
EllipsePy.xml
|
||||
EllipsePyImp.cpp
|
||||
HyperbolaPy.xml
|
||||
|
||||
@@ -46,6 +46,12 @@
|
||||
</Documentation>
|
||||
<Parameter Name="MinorRadius" Type="Float"/>
|
||||
</Attribute>
|
||||
<Attribute Name="AngleXU" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>The angle between the X axis and the major axis of the ellipse.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="AngleXU" Type="Float"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Eccentricity" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The eccentricity of the ellipse.</UserDocu>
|
||||
|
||||
@@ -151,6 +151,38 @@ void EllipsePy::setMinorRadius(Py::Float arg)
|
||||
ellipse->SetMinorRadius((double)arg);
|
||||
}
|
||||
|
||||
Py::Float EllipsePy::getAngleXU(void) const
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(getGeomEllipsePtr()->handle());
|
||||
|
||||
gp_Pnt center = ellipse->Axis().Location();
|
||||
gp_Dir normal = ellipse->Axis().Direction();
|
||||
gp_Dir xdir = ellipse->XAxis().Direction();
|
||||
|
||||
gp_Ax2 xdirref(center, normal); // this is a reference system, might be CCW or CW depending on the creation method
|
||||
|
||||
return Py::Float(-xdir.AngleWithRef(xdirref.XDirection(),normal));
|
||||
|
||||
}
|
||||
|
||||
void EllipsePy::setAngleXU(Py::Float arg)
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(getGeomEllipsePtr()->handle());
|
||||
|
||||
|
||||
gp_Pnt center = ellipse->Axis().Location();
|
||||
gp_Dir normal = ellipse->Axis().Direction();
|
||||
|
||||
gp_Ax1 normaxis(center, normal);
|
||||
|
||||
gp_Ax2 xdirref(center, normal);
|
||||
|
||||
xdirref.Rotate(normaxis,arg);
|
||||
|
||||
ellipse->SetPosition(xdirref);
|
||||
|
||||
}
|
||||
|
||||
Py::Float EllipsePy::getEccentricity(void) const
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(getGeomEllipsePtr()->handle());
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
# include <Geom_TrimmedCurve.hxx>
|
||||
# include <GC_MakeArcOfCircle.hxx>
|
||||
# include <GC_MakeCircle.hxx>
|
||||
# include <GC_MakeArcOfEllipse.hxx>
|
||||
# include <GC_MakeEllipse.hxx>
|
||||
# include <GC_MakeLine.hxx>
|
||||
# include <GC_MakeSegment.hxx>
|
||||
@@ -91,6 +92,7 @@
|
||||
#include "EllipsePy.h"
|
||||
#include "ArcPy.h"
|
||||
#include "ArcOfCirclePy.h"
|
||||
#include "ArcOfEllipsePy.h"
|
||||
#include "BezierCurvePy.h"
|
||||
#include "BSplineCurvePy.h"
|
||||
#include "HyperbolaPy.h"
|
||||
@@ -888,6 +890,44 @@ void GeomEllipse::setMinorRadius(double Radius)
|
||||
}
|
||||
}
|
||||
|
||||
double GeomEllipse::getAngleXU(void) const
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(handle());
|
||||
|
||||
gp_Pnt center = this->myCurve->Axis().Location();
|
||||
gp_Dir normal = this->myCurve->Axis().Direction();
|
||||
gp_Dir xdir = this->myCurve->XAxis().Direction();
|
||||
|
||||
|
||||
gp_Ax2 xdirref(center, normal); // this is a reference system, might be CCW or CW depending on the creation method
|
||||
|
||||
return -xdir.AngleWithRef(xdirref.XDirection(),normal);
|
||||
|
||||
}
|
||||
|
||||
void GeomEllipse::setAngleXU(double angle)
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(handle());
|
||||
|
||||
try {
|
||||
gp_Pnt center = this->myCurve->Axis().Location();
|
||||
gp_Dir normal = this->myCurve->Axis().Direction();
|
||||
|
||||
gp_Ax1 normaxis(center, normal);
|
||||
|
||||
gp_Ax2 xdirref(center, normal);
|
||||
|
||||
xdirref.Rotate(normaxis,angle);
|
||||
|
||||
this->myCurve->SetPosition(xdirref);
|
||||
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Base::Exception(e->GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
// Persistence implementer
|
||||
unsigned int GeomEllipse::getMemSize (void) const
|
||||
{
|
||||
@@ -901,7 +941,13 @@ void GeomEllipse::Save(Base::Writer& writer) const
|
||||
|
||||
gp_Pnt center = this->myCurve->Axis().Location();
|
||||
gp_Dir normal = this->myCurve->Axis().Direction();
|
||||
|
||||
gp_Dir xdir = this->myCurve->XAxis().Direction();
|
||||
|
||||
gp_Ax2 xdirref(center, normal); // this is a reference XY for the ellipse
|
||||
|
||||
double AngleXU = -xdir.AngleWithRef(xdirref.XDirection(),normal);
|
||||
|
||||
|
||||
writer.Stream()
|
||||
<< writer.ind()
|
||||
<< "<Ellipse "
|
||||
@@ -913,6 +959,7 @@ void GeomEllipse::Save(Base::Writer& writer) const
|
||||
<< "NormalZ=\"" << normal.Z() << "\" "
|
||||
<< "MajorRadius=\"" << this->myCurve->MajorRadius() << "\" "
|
||||
<< "MinorRadius=\"" << this->myCurve->MinorRadius() << "\" "
|
||||
<< "AngleXU=\"" << AngleXU << "\" "
|
||||
<< "/>" << endl;
|
||||
}
|
||||
|
||||
@@ -921,7 +968,7 @@ void GeomEllipse::Restore(Base::XMLReader& reader)
|
||||
// read the attributes of the father class
|
||||
GeomCurve::Restore(reader);
|
||||
|
||||
double CenterX,CenterY,CenterZ,NormalX,NormalY,NormalZ,MajorRadius,MinorRadius;
|
||||
double CenterX,CenterY,CenterZ,NormalX,NormalY,NormalZ,MajorRadius,MinorRadius,AngleXU;
|
||||
// read my Element
|
||||
reader.readElement("Ellipse");
|
||||
// get the value of my Attribute
|
||||
@@ -933,12 +980,25 @@ void GeomEllipse::Restore(Base::XMLReader& reader)
|
||||
NormalZ = reader.getAttributeAsFloat("NormalZ");
|
||||
MajorRadius = reader.getAttributeAsFloat("MajorRadius");
|
||||
MinorRadius = reader.getAttributeAsFloat("MinorRadius");
|
||||
|
||||
// This is for backwards compatibility
|
||||
if(reader.hasAttribute("AngleXU"))
|
||||
AngleXU = reader.getAttributeAsFloat("AngleXU");
|
||||
else
|
||||
AngleXU = 0;
|
||||
|
||||
// set the read geometry
|
||||
gp_Pnt p1(CenterX,CenterY,CenterZ);
|
||||
gp_Dir norm(NormalX,NormalY,NormalZ);
|
||||
|
||||
gp_Ax1 normaxis(p1,norm);
|
||||
|
||||
gp_Ax2 xdir(p1, norm);
|
||||
|
||||
xdir.Rotate(normaxis,AngleXU);
|
||||
|
||||
try {
|
||||
GC_MakeEllipse mc(gp_Ax2(p1, norm), MajorRadius, MinorRadius);
|
||||
GC_MakeEllipse mc(xdir, MajorRadius, MinorRadius);
|
||||
if (!mc.IsDone())
|
||||
throw Base::Exception(gce_ErrorStatusText(mc.Status()));
|
||||
|
||||
@@ -955,6 +1015,271 @@ PyObject *GeomEllipse::getPyObject(void)
|
||||
return new EllipsePy((GeomEllipse*)this->clone());
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
TYPESYSTEM_SOURCE(Part::GeomArcOfEllipse,Part::GeomCurve);
|
||||
|
||||
GeomArcOfEllipse::GeomArcOfEllipse()
|
||||
{
|
||||
Handle_Geom_Ellipse e = new Geom_Ellipse(gp_Elips());
|
||||
this->myCurve = new Geom_TrimmedCurve(e, e->FirstParameter(),e->LastParameter());
|
||||
}
|
||||
|
||||
GeomArcOfEllipse::GeomArcOfEllipse(const Handle_Geom_Ellipse& e)
|
||||
{
|
||||
this->myCurve = new Geom_TrimmedCurve(e, e->FirstParameter(),e->LastParameter());
|
||||
}
|
||||
|
||||
GeomArcOfEllipse::~GeomArcOfEllipse()
|
||||
{
|
||||
}
|
||||
|
||||
void GeomArcOfEllipse::setHandle(const Handle_Geom_TrimmedCurve& c)
|
||||
{
|
||||
Handle_Geom_Ellipse basis = Handle_Geom_Ellipse::DownCast(c->BasisCurve());
|
||||
if (basis.IsNull())
|
||||
Standard_Failure::Raise("Basis curve is not an ellipse");
|
||||
this->myCurve = Handle_Geom_TrimmedCurve::DownCast(c->Copy());
|
||||
}
|
||||
|
||||
const Handle_Geom_Geometry& GeomArcOfEllipse::handle() const
|
||||
{
|
||||
return myCurve;
|
||||
}
|
||||
|
||||
Geometry *GeomArcOfEllipse::clone(void) const
|
||||
{
|
||||
GeomArcOfEllipse* copy = new GeomArcOfEllipse();
|
||||
copy->setHandle(this->myCurve);
|
||||
copy->Construction = this->Construction;
|
||||
return copy;
|
||||
}
|
||||
|
||||
Base::Vector3d GeomArcOfEllipse::getStartPoint() const
|
||||
{
|
||||
gp_Pnt pnt = this->myCurve->StartPoint();
|
||||
return Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z());
|
||||
}
|
||||
|
||||
Base::Vector3d GeomArcOfEllipse::getEndPoint() const
|
||||
{
|
||||
gp_Pnt pnt = this->myCurve->EndPoint();
|
||||
return Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z());
|
||||
}
|
||||
|
||||
Base::Vector3d GeomArcOfEllipse::getCenter(void) const
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(myCurve->BasisCurve());
|
||||
gp_Ax1 axis = ellipse->Axis();
|
||||
const gp_Pnt& loc = axis.Location();
|
||||
return Base::Vector3d(loc.X(),loc.Y(),loc.Z());
|
||||
}
|
||||
|
||||
void GeomArcOfEllipse::setCenter(const Base::Vector3d& Center)
|
||||
{
|
||||
gp_Pnt p1(Center.x,Center.y,Center.z);
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(myCurve->BasisCurve());
|
||||
|
||||
try {
|
||||
ellipse->SetLocation(p1);
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Base::Exception(e->GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
double GeomArcOfEllipse::getMajorRadius(void) const
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(myCurve->BasisCurve());
|
||||
return ellipse->MajorRadius();
|
||||
}
|
||||
|
||||
void GeomArcOfEllipse::setMajorRadius(double Radius)
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(myCurve->BasisCurve());
|
||||
|
||||
try {
|
||||
ellipse->SetMajorRadius(Radius);
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Base::Exception(e->GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
double GeomArcOfEllipse::getMinorRadius(void) const
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(myCurve->BasisCurve());
|
||||
return ellipse->MinorRadius();
|
||||
}
|
||||
|
||||
void GeomArcOfEllipse::setMinorRadius(double Radius)
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(myCurve->BasisCurve());
|
||||
|
||||
try {
|
||||
ellipse->SetMinorRadius(Radius);
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Base::Exception(e->GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
double GeomArcOfEllipse::getAngleXU(void) const
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(myCurve->BasisCurve());
|
||||
|
||||
gp_Pnt center = ellipse->Axis().Location();
|
||||
gp_Dir normal = ellipse->Axis().Direction();
|
||||
gp_Dir xdir = ellipse->XAxis().Direction();
|
||||
|
||||
gp_Ax2 xdirref(center, normal); // this is a reference system, might be CCW or CW depending on the creation method
|
||||
|
||||
return -xdir.AngleWithRef(xdirref.XDirection(),normal);
|
||||
|
||||
}
|
||||
|
||||
void GeomArcOfEllipse::setAngleXU(double angle)
|
||||
{
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(myCurve->BasisCurve());
|
||||
|
||||
try {
|
||||
gp_Pnt center = ellipse->Axis().Location();
|
||||
gp_Dir normal = ellipse->Axis().Direction();
|
||||
|
||||
gp_Ax1 normaxis(center, normal);
|
||||
|
||||
gp_Ax2 xdirref(center, normal);
|
||||
|
||||
xdirref.Rotate(normaxis,angle);
|
||||
|
||||
ellipse->SetPosition(xdirref);
|
||||
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Base::Exception(e->GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
void GeomArcOfEllipse::getRange(double& u, double& v) const
|
||||
{
|
||||
u = myCurve->FirstParameter();
|
||||
v = myCurve->LastParameter();
|
||||
}
|
||||
|
||||
void GeomArcOfEllipse::setRange(double u, double v)
|
||||
{
|
||||
try {
|
||||
myCurve->SetTrim(u, v);
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Base::Exception(e->GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
// Persistence implementer
|
||||
unsigned int GeomArcOfEllipse::getMemSize (void) const
|
||||
{
|
||||
return sizeof(Geom_Ellipse) + 2 *sizeof(double);
|
||||
}
|
||||
|
||||
void GeomArcOfEllipse::Save(Base::Writer &writer) const
|
||||
{
|
||||
// save the attributes of the father class
|
||||
GeomCurve::Save(writer);
|
||||
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(this->myCurve->BasisCurve());
|
||||
|
||||
gp_Pnt center = ellipse->Axis().Location();
|
||||
gp_Dir normal = ellipse->Axis().Direction();
|
||||
gp_Dir xdir = ellipse->XAxis().Direction();
|
||||
|
||||
gp_Ax2 xdirref(center, normal); // this is a reference XY for the ellipse
|
||||
|
||||
double AngleXU = -xdir.AngleWithRef(xdirref.XDirection(),normal);
|
||||
|
||||
|
||||
writer.Stream()
|
||||
<< writer.ind()
|
||||
<< "<ArcOfEllipse "
|
||||
<< "CenterX=\"" << center.X() << "\" "
|
||||
<< "CenterY=\"" << center.Y() << "\" "
|
||||
<< "CenterZ=\"" << center.Z() << "\" "
|
||||
<< "NormalX=\"" << normal.X() << "\" "
|
||||
<< "NormalY=\"" << normal.Y() << "\" "
|
||||
<< "NormalZ=\"" << normal.Z() << "\" "
|
||||
<< "MajorRadius=\"" << ellipse->MajorRadius() << "\" "
|
||||
<< "MinorRadius=\"" << ellipse->MinorRadius() << "\" "
|
||||
<< "AngleXU=\"" << AngleXU << "\" "
|
||||
<< "StartAngle=\"" << this->myCurve->FirstParameter() << "\" "
|
||||
<< "EndAngle=\"" << this->myCurve->LastParameter() << "\" "
|
||||
<< "/>" << endl;
|
||||
}
|
||||
|
||||
void GeomArcOfEllipse::Restore(Base::XMLReader &reader)
|
||||
{
|
||||
// read the attributes of the father class
|
||||
GeomCurve::Restore(reader);
|
||||
|
||||
double CenterX,CenterY,CenterZ,NormalX,NormalY,NormalZ,MajorRadius,MinorRadius,AngleXU,StartAngle,EndAngle;
|
||||
// read my Element
|
||||
reader.readElement("ArcOfEllipse");
|
||||
// get the value of my Attribute
|
||||
CenterX = reader.getAttributeAsFloat("CenterX");
|
||||
CenterY = reader.getAttributeAsFloat("CenterY");
|
||||
CenterZ = reader.getAttributeAsFloat("CenterZ");
|
||||
NormalX = reader.getAttributeAsFloat("NormalX");
|
||||
NormalY = reader.getAttributeAsFloat("NormalY");
|
||||
NormalZ = reader.getAttributeAsFloat("NormalZ");
|
||||
MajorRadius = reader.getAttributeAsFloat("MajorRadius");
|
||||
MinorRadius = reader.getAttributeAsFloat("MinorRadius");
|
||||
AngleXU = reader.getAttributeAsFloat("AngleXU");
|
||||
StartAngle = reader.getAttributeAsFloat("StartAngle");
|
||||
EndAngle = reader.getAttributeAsFloat("EndAngle");
|
||||
|
||||
|
||||
// set the read geometry
|
||||
gp_Pnt p1(CenterX,CenterY,CenterZ);
|
||||
gp_Dir norm(NormalX,NormalY,NormalZ);
|
||||
|
||||
gp_Ax1 normaxis(p1,norm);
|
||||
|
||||
gp_Ax2 xdir(p1, norm);
|
||||
|
||||
xdir.Rotate(normaxis,AngleXU);
|
||||
|
||||
try {
|
||||
GC_MakeEllipse mc(xdir, MajorRadius, MinorRadius);
|
||||
if (!mc.IsDone())
|
||||
throw Base::Exception(gce_ErrorStatusText(mc.Status()));
|
||||
|
||||
GC_MakeArcOfEllipse ma(mc.Value()->Elips(), StartAngle, EndAngle, 1);
|
||||
if (!ma.IsDone())
|
||||
throw Base::Exception(gce_ErrorStatusText(ma.Status()));
|
||||
|
||||
Handle_Geom_TrimmedCurve tmpcurve = ma.Value();
|
||||
Handle_Geom_Ellipse tmpellipse = Handle_Geom_Ellipse::DownCast(tmpcurve->BasisCurve());
|
||||
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(this->myCurve->BasisCurve());
|
||||
|
||||
ellipse->SetElips(tmpellipse->Elips());
|
||||
this->myCurve->SetTrim(tmpcurve->FirstParameter(), tmpcurve->LastParameter());
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Base::Exception(e->GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *GeomArcOfEllipse::getPyObject(void)
|
||||
{
|
||||
return new ArcOfEllipsePy(static_cast<GeomArcOfEllipse*>(this->clone()));
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
TYPESYSTEM_SOURCE(Part::GeomHyperbola,Part::GeomCurve);
|
||||
|
||||
@@ -244,6 +244,8 @@ public:
|
||||
void setMajorRadius(double Radius);
|
||||
double getMinorRadius(void) const;
|
||||
void setMinorRadius(double Radius);
|
||||
double getAngleXU(void) const;
|
||||
void setAngleXU(double angle);
|
||||
|
||||
// Persistence implementer ---------------------
|
||||
virtual unsigned int getMemSize(void) const;
|
||||
@@ -258,6 +260,45 @@ private:
|
||||
Handle_Geom_Ellipse myCurve;
|
||||
};
|
||||
|
||||
class PartExport GeomArcOfEllipse : public GeomCurve
|
||||
{
|
||||
TYPESYSTEM_HEADER();
|
||||
public:
|
||||
GeomArcOfEllipse();
|
||||
GeomArcOfEllipse(const Handle_Geom_Ellipse&);
|
||||
virtual ~GeomArcOfEllipse();
|
||||
virtual Geometry *clone(void) const;
|
||||
|
||||
Base::Vector3d getStartPoint() const;
|
||||
Base::Vector3d getEndPoint() const;
|
||||
|
||||
Base::Vector3d getCenter(void) const;
|
||||
void setCenter(const Base::Vector3d& Center);
|
||||
double getMajorRadius(void) const;
|
||||
void setMajorRadius(double Radius);
|
||||
double getMinorRadius(void) const;
|
||||
void setMinorRadius(double Radius);
|
||||
double getAngleXU(void) const;
|
||||
void setAngleXU(double angle);
|
||||
|
||||
void getRange(double& u, double& v) const;
|
||||
void setRange(double u, double v);
|
||||
|
||||
// Persistence implementer ---------------------
|
||||
virtual unsigned int getMemSize(void) const;
|
||||
virtual void Save(Base::Writer &/*writer*/) const;
|
||||
virtual void Restore(Base::XMLReader &/*reader*/);
|
||||
// Base implementer ----------------------------
|
||||
virtual PyObject *getPyObject(void);
|
||||
|
||||
void setHandle(const Handle_Geom_TrimmedCurve&);
|
||||
const Handle_Geom_Geometry& handle() const;
|
||||
|
||||
private:
|
||||
Handle_Geom_TrimmedCurve myCurve;
|
||||
};
|
||||
|
||||
|
||||
class PartExport GeomHyperbola : public GeomCurve
|
||||
{
|
||||
TYPESYSTEM_HEADER();
|
||||
@@ -340,7 +381,7 @@ public:
|
||||
Base::Vector3d getStartPoint() const;
|
||||
Base::Vector3d getEndPoint() const;
|
||||
|
||||
void setPoints(const Base::Vector3d& p1,
|
||||
void setPoints(const Base::Vector3d& p1,
|
||||
const Base::Vector3d& p2);
|
||||
|
||||
// Persistence implementer ---------------------
|
||||
@@ -674,14 +715,14 @@ bool find2DLinesIntersection(const GeomLineSegment *lineSeg1, const GeomLineSegm
|
||||
PartExport
|
||||
bool findFilletCenter(const GeomLineSegment *lineSeg1, const GeomLineSegment *lineSeg2, double radius,
|
||||
Base::Vector3d ¢er);
|
||||
PartExport
|
||||
PartExport
|
||||
bool findFilletCenter(const GeomLineSegment *lineSeg1, const GeomLineSegment *lineSeg2, double radius,
|
||||
const Base::Vector3d& refPnt1, const Base::Vector3d& refPnt2,
|
||||
Base::Vector3d ¢er);
|
||||
PartExport
|
||||
double suggestFilletRadius(const GeomLineSegment *lineSeg1, const GeomLineSegment *lineSeg2,
|
||||
const Base::Vector3d &refPnt1, const Base::Vector3d &refPnt2);
|
||||
PartExport
|
||||
PartExport
|
||||
GeomArcOfCircle *createFilletGeometry(const GeomLineSegment *lineSeg1, const GeomLineSegment *lineSeg2,
|
||||
const Base::Vector3d ¢er, double radius);
|
||||
}
|
||||
|
||||
309
src/Mod/Part/App/Makefile.am
Normal file
309
src/Mod/Part/App/Makefile.am
Normal file
@@ -0,0 +1,309 @@
|
||||
|
||||
lib_LTLIBRARIES=libPart.la Part.la
|
||||
|
||||
BUILT_SOURCES=\
|
||||
ArcPy.cpp \
|
||||
ArcOfCirclePy.cpp \
|
||||
ArcOfEllipsePy.cpp \
|
||||
BRepOffsetAPI_MakePipeShellPy.cpp \
|
||||
CirclePy.cpp \
|
||||
EllipsePy.cpp \
|
||||
HyperbolaPy.cpp \
|
||||
ParabolaPy.cpp \
|
||||
OffsetCurvePy.cpp \
|
||||
GeometryPy.cpp \
|
||||
GeometryCurvePy.cpp \
|
||||
GeometrySurfacePy.cpp \
|
||||
LinePy.cpp \
|
||||
PointPy.cpp \
|
||||
BezierCurvePy.cpp \
|
||||
BSplineCurvePy.cpp \
|
||||
PlanePy.cpp \
|
||||
ConePy.cpp \
|
||||
CylinderPy.cpp \
|
||||
SpherePy.cpp \
|
||||
ToroidPy.cpp \
|
||||
BezierSurfacePy.cpp \
|
||||
BSplineSurfacePy.cpp \
|
||||
OffsetSurfacePy.cpp \
|
||||
RectangularTrimmedSurfacePy.cpp \
|
||||
SurfaceOfExtrusionPy.cpp \
|
||||
SurfaceOfRevolutionPy.cpp \
|
||||
PartFeaturePy.cpp \
|
||||
FeaturePythonPy.cpp \
|
||||
Part2DObjectPy.cpp \
|
||||
TopoShapeCompoundPy.cpp \
|
||||
TopoShapeCompSolidPy.cpp \
|
||||
TopoShapeEdgePy.cpp \
|
||||
TopoShapeFacePy.cpp \
|
||||
TopoShapeShellPy.cpp \
|
||||
TopoShapeSolidPy.cpp \
|
||||
TopoShapeVertexPy.cpp \
|
||||
TopoShapeWirePy.cpp \
|
||||
TopoShapePy.cpp
|
||||
|
||||
libPart_la_BUILT=\
|
||||
ArcPy.h \
|
||||
ArcOfCirclePy.h \
|
||||
ArcOfEllipsePy.h \
|
||||
BRepOffsetAPI_MakePipeShellPy.h \
|
||||
CirclePy.h \
|
||||
EllipsePy.h \
|
||||
HyperbolaPy.h \
|
||||
ParabolaPy.h \
|
||||
OffsetCurvePy.h \
|
||||
GeometryPy.h \
|
||||
GeometryCurvePy.h \
|
||||
GeometrySurfacePy.h \
|
||||
LinePy.h \
|
||||
PointPy.h \
|
||||
BezierCurvePy.h \
|
||||
BSplineCurvePy.h \
|
||||
PlanePy.h \
|
||||
ConePy.h \
|
||||
CylinderPy.h \
|
||||
SpherePy.h \
|
||||
ToroidPy.h \
|
||||
BezierSurfacePy.h \
|
||||
BSplineSurfacePy.h \
|
||||
OffsetSurfacePy.h \
|
||||
RectangularTrimmedSurfacePy.h \
|
||||
SurfaceOfExtrusionPy.h \
|
||||
SurfaceOfRevolutionPy.h \
|
||||
PartFeaturePy.h \
|
||||
FeaturePythonPy.h \
|
||||
Part2DObjectPy.h \
|
||||
TopoShapeCompoundPy.h \
|
||||
TopoShapeCompSolidPy.h \
|
||||
TopoShapeEdgePy.h \
|
||||
TopoShapeFacePy.h \
|
||||
TopoShapeShellPy.h \
|
||||
TopoShapeSolidPy.h \
|
||||
TopoShapeVertexPy.h \
|
||||
TopoShapeWirePy.h \
|
||||
TopoShapePy.h
|
||||
|
||||
libPart_la_SOURCES=\
|
||||
AppPartPy.cpp \
|
||||
ArcPyImp.cpp \
|
||||
ArcOfCirclePyImp.cpp \
|
||||
ArcOfEllipsePyImp.cpp \
|
||||
BRepOffsetAPI_MakePipeShellPyImp.cpp \
|
||||
CirclePyImp.cpp \
|
||||
CrossSection.cpp \
|
||||
EllipsePyImp.cpp \
|
||||
HyperbolaPyImp.cpp \
|
||||
ParabolaPyImp.cpp \
|
||||
OffsetCurvePyImp.cpp \
|
||||
GeometryPyImp.cpp \
|
||||
GeometryCurvePyImp.cpp \
|
||||
GeometrySurfacePyImp.cpp \
|
||||
LinePyImp.cpp \
|
||||
PointPyImp.cpp \
|
||||
BezierCurvePyImp.cpp \
|
||||
BSplineCurvePyImp.cpp \
|
||||
PlanePyImp.cpp \
|
||||
ConePyImp.cpp \
|
||||
CylinderPyImp.cpp \
|
||||
SpherePyImp.cpp \
|
||||
ToroidPyImp.cpp \
|
||||
BezierSurfacePyImp.cpp \
|
||||
BSplineSurfacePyImp.cpp \
|
||||
OffsetSurfacePyImp.cpp \
|
||||
RectangularTrimmedSurfacePyImp.cpp \
|
||||
SurfaceOfExtrusionPyImp.cpp \
|
||||
SurfaceOfRevolutionPyImp.cpp \
|
||||
edgecluster.cpp \
|
||||
FeaturePartBoolean.cpp \
|
||||
FeaturePartBox.cpp \
|
||||
FeaturePartCircle.cpp \
|
||||
FeaturePartCurveNet.cpp \
|
||||
FeaturePartCommon.cpp \
|
||||
FeaturePartCut.cpp \
|
||||
FeaturePartFuse.cpp \
|
||||
FeaturePartImportBrep.cpp \
|
||||
FeaturePartImportIges.cpp \
|
||||
FeaturePartImportStep.cpp \
|
||||
FeaturePartPolygon.cpp \
|
||||
FeaturePartSection.cpp \
|
||||
FeatureChamfer.cpp \
|
||||
FeatureExtrusion.cpp \
|
||||
FeatureFillet.cpp \
|
||||
FeatureGeometrySet.cpp \
|
||||
FeatureRevolution.cpp \
|
||||
FeatureMirroring.cpp \
|
||||
PartFeatures.cpp \
|
||||
Geometry.cpp \
|
||||
ImportIges.cpp \
|
||||
ImportStep.cpp \
|
||||
modelRefine.cpp \
|
||||
CustomFeature.cpp \
|
||||
PartFeature.cpp \
|
||||
PartFeatureReference.cpp \
|
||||
PartFeaturePyImp.cpp \
|
||||
FeaturePythonPyImp.cpp \
|
||||
Part2DObject.cpp \
|
||||
Part2DObjectPyImp.cpp \
|
||||
PreCompiled.cpp \
|
||||
PreCompiled.h \
|
||||
PrimitiveFeature.cpp \
|
||||
ProgressIndicator.cpp \
|
||||
PropertyGeometryList.cpp \
|
||||
PropertyTopoShape.cpp \
|
||||
TopoShape.cpp \
|
||||
TopoShapeCompoundPyImp.cpp \
|
||||
TopoShapeCompSolidPyImp.cpp \
|
||||
TopoShapeEdgePyImp.cpp \
|
||||
TopoShapeFacePyImp.cpp \
|
||||
TopoShapeShellPyImp.cpp \
|
||||
TopoShapeSolidPyImp.cpp \
|
||||
TopoShapeVertexPyImp.cpp \
|
||||
TopoShapeWirePyImp.cpp \
|
||||
TopoShapePyImp.cpp
|
||||
|
||||
nodist_include_HEADERS=\
|
||||
$(libPart_la_BUILT)
|
||||
|
||||
include_HEADERS=\
|
||||
CrossSection.h \
|
||||
edgecluster.h \
|
||||
FeaturePartBoolean.h \
|
||||
FeaturePartBox.h \
|
||||
FeaturePartCircle.h \
|
||||
FeaturePartCurveNet.h \
|
||||
FeaturePartCommon.h \
|
||||
FeaturePartCut.h \
|
||||
FeaturePartFuse.h \
|
||||
FeaturePartImportBrep.h \
|
||||
FeaturePartImportIges.h \
|
||||
FeaturePartImportStep.h \
|
||||
FeaturePartPolygon.h \
|
||||
FeaturePartSection.h \
|
||||
FeatureChamfer.h \
|
||||
FeatureExtrusion.h \
|
||||
FeatureFillet.h \
|
||||
FeatureGeometrySet.h \
|
||||
FeatureRevolution.h \
|
||||
FeatureMirroring.h \
|
||||
PartFeatures.h \
|
||||
Geometry.h \
|
||||
ImportIges.h \
|
||||
ImportStep.h \
|
||||
modelRefine.h \
|
||||
PartFeature.h \
|
||||
PartFeatureReference.h \
|
||||
CustomFeature.h \
|
||||
Part2DObject.h \
|
||||
PrimitiveFeature.h \
|
||||
ProgressIndicator.h \
|
||||
PropertyGeometryList.h \
|
||||
PropertyTopoShape.h \
|
||||
Tools.h \
|
||||
TopoShape.h
|
||||
|
||||
|
||||
# the library search path.
|
||||
libPart_la_LDFLAGS = -L../../../Base -L../../../App -L/usr/X11R6/lib -L$(OCC_LIB) $(all_libraries) \
|
||||
-version-info @LIB_CURRENT@:@LIB_REVISION@:@LIB_AGE@
|
||||
libPart_la_CPPFLAGS = -DPartExport=
|
||||
|
||||
libPart_la_LIBADD = \
|
||||
@BOOST_FILESYSTEM_LIB@ @BOOST_SYSTEM_LIB@ \
|
||||
-l@PYTHON_LIB@ \
|
||||
-lxerces-c \
|
||||
-lFreeCADBase \
|
||||
-lFreeCADApp \
|
||||
-lTKernel \
|
||||
-lTKFillet \
|
||||
-lTKG2d \
|
||||
-lTKG3d \
|
||||
-lTKMath \
|
||||
-lTKMesh \
|
||||
-lTKSTEP \
|
||||
-lTKSTEPAttr \
|
||||
-lTKSTEPBase \
|
||||
-lTKIGES \
|
||||
-lTKSTL \
|
||||
-lTKShHealing \
|
||||
-lTKXSBase \
|
||||
-lTKBool \
|
||||
-lTKBO \
|
||||
-lTKBRep \
|
||||
-lTKTopAlgo \
|
||||
-lTKGeomAlgo \
|
||||
-lTKGeomBase \
|
||||
-lTKOffset \
|
||||
-lTKPrim
|
||||
|
||||
%.cpp: %.xml $(top_srcdir)/src/Tools/generateTemplates/templateClassPyExport.py
|
||||
$(PYTHON) $(top_srcdir)/src/Tools/generate.py --outputPath $(@D) $<
|
||||
|
||||
#--------------------------------------------------------------------------------------
|
||||
# Loader of libPart
|
||||
|
||||
Part_la_SOURCES=\
|
||||
AppPart.cpp
|
||||
|
||||
# the library search path.
|
||||
Part_la_LDFLAGS = $(libPart_la_LDFLAGS) -module -avoid-version
|
||||
Part_la_CPPFLAGS = $(libPart_la_CPPFLAGS)
|
||||
|
||||
Part_la_LIBADD = \
|
||||
$(libPart_la_LIBADD) \
|
||||
-lPart
|
||||
|
||||
Part_la_DEPENDENCIES = libPart.la
|
||||
|
||||
#--------------------------------------------------------------------------------------
|
||||
|
||||
# set the include path found by configure
|
||||
AM_CXXFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src $(all_includes) -I$(OCC_INC)
|
||||
|
||||
|
||||
includedir = @includedir@/Mod/Part/App
|
||||
libdir = $(prefix)/Mod/Part
|
||||
|
||||
CLEANFILES = $(BUILT_SOURCES) $(libPart_la_BUILT)
|
||||
|
||||
EXTRA_DIST = \
|
||||
OpenCascadeAll.h \
|
||||
ArcPy.xml \
|
||||
ArcOfCirclePy.xml \
|
||||
ArcOfEllipsePy.xml \
|
||||
BRepOffsetAPI_MakePipeShellPy.xml \
|
||||
CirclePy.xml \
|
||||
EllipsePy.xml \
|
||||
HyperbolaPy.xml \
|
||||
ParabolaPy.xml \
|
||||
OffsetCurvePy.xml \
|
||||
GeometryPy.xml \
|
||||
GeometryCurvePy.xml \
|
||||
GeometrySurfacePy.xml \
|
||||
LinePy.xml \
|
||||
PointPy.xml \
|
||||
BezierCurvePy.xml \
|
||||
BSplineCurvePy.xml \
|
||||
PlanePy.xml \
|
||||
ConePy.xml \
|
||||
CylinderPy.xml \
|
||||
SpherePy.xml \
|
||||
ToroidPy.xml \
|
||||
BezierSurfacePy.xml \
|
||||
BSplineSurfacePy.xml \
|
||||
OffsetSurfacePy.xml \
|
||||
RectangularTrimmedSurfacePy.xml \
|
||||
SurfaceOfExtrusionPy.xml \
|
||||
SurfaceOfRevolutionPy.xml \
|
||||
PartFeaturePy.xml \
|
||||
FeaturePythonPy.xml \
|
||||
Part2DObjectPy.xml \
|
||||
TopoShapePy.xml \
|
||||
TopoShapeCompSolidPy.xml \
|
||||
TopoShapeCompoundPy.xml \
|
||||
TopoShapeEdgePy.xml \
|
||||
TopoShapeFacePy.xml \
|
||||
TopoShapeShellPy.xml \
|
||||
TopoShapeSolidPy.xml \
|
||||
TopoShapeVertexPy.xml \
|
||||
TopoShapeWirePy.xml \
|
||||
CMakeLists.txt
|
||||
@@ -172,6 +172,10 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
Gui::MenuItem* cons = new Gui::MenuItem();
|
||||
cons->setCommand("Sketcher constraints");
|
||||
SketcherGui::addSketcherWorkbenchConstraints( *cons );
|
||||
|
||||
Gui::MenuItem* consaccel = new Gui::MenuItem();
|
||||
consaccel->setCommand("Sketcher tools");
|
||||
SketcherGui::addSketcherWorkbenchTools(*consaccel);
|
||||
|
||||
Gui::MenuItem* part = new Gui::MenuItem;
|
||||
root->insertItem(item, part);
|
||||
@@ -233,6 +237,10 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
cons->setCommand("Sketcher constraints");
|
||||
SketcherGui::addSketcherWorkbenchConstraints( *cons );
|
||||
|
||||
Gui::ToolBarItem* consaccel = new Gui::ToolBarItem(root);
|
||||
consaccel->setCommand("Sketcher tools");
|
||||
SketcherGui::addSketcherWorkbenchTools( *consaccel );
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ const int Constraint::GeoUndef = -2000;
|
||||
|
||||
Constraint::Constraint()
|
||||
: Type(None),
|
||||
AlignmentType(Undef),
|
||||
Name(""),
|
||||
Value(0.0),
|
||||
First(GeoUndef),
|
||||
@@ -58,6 +59,7 @@ Constraint::Constraint()
|
||||
|
||||
Constraint::Constraint(const Constraint& from)
|
||||
: Type(from.Type),
|
||||
AlignmentType(from.AlignmentType),
|
||||
Name(from.Name),
|
||||
Value(from.Value),
|
||||
First(from.First),
|
||||
@@ -92,18 +94,22 @@ unsigned int Constraint::getMemSize (void) const
|
||||
|
||||
void Constraint::Save (Writer &writer) const
|
||||
{
|
||||
writer.Stream() << writer.ind() << "<Constrain "
|
||||
<< "Name=\"" << Name << "\" "
|
||||
<< "Type=\"" << (int)Type << "\" "
|
||||
<< "Value=\"" << Value << "\" "
|
||||
<< "First=\"" << First << "\" "
|
||||
<< "FirstPos=\"" << (int) FirstPos << "\" "
|
||||
<< "Second=\"" << Second << "\" "
|
||||
<< "SecondPos=\"" << (int) SecondPos << "\" "
|
||||
<< "Third=\"" << Third << "\" "
|
||||
<< "ThirdPos=\"" << (int) ThirdPos << "\" "
|
||||
<< "LabelDistance=\"" << LabelDistance << "\" "
|
||||
<< "LabelPosition=\"" << LabelPosition << "\" />"
|
||||
writer.Stream() << writer.ind() << "<Constrain "
|
||||
<< "Name=\"" << Name << "\" "
|
||||
<< "Type=\"" << (int)Type << "\" ";
|
||||
if(this->Type==InternalAlignment)
|
||||
writer.Stream()
|
||||
<< "InternalAlignmentType=\"" << (int)AlignmentType << "\" ";
|
||||
writer.Stream()
|
||||
<< "Value=\"" << Value << "\" "
|
||||
<< "First=\"" << First << "\" "
|
||||
<< "FirstPos=\"" << (int) FirstPos << "\" "
|
||||
<< "Second=\"" << Second << "\" "
|
||||
<< "SecondPos=\"" << (int) SecondPos << "\" "
|
||||
<< "Third=\"" << Third << "\" "
|
||||
<< "ThirdPos=\"" << (int) ThirdPos << "\" "
|
||||
<< "LabelDistance=\"" << LabelDistance << "\" "
|
||||
<< "LabelPosition=\"" << LabelPosition << "\" />"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
@@ -118,6 +124,11 @@ void Constraint::Restore(XMLReader &reader)
|
||||
Second = reader.getAttributeAsInteger("Second");
|
||||
SecondPos = (PointPos) reader.getAttributeAsInteger("SecondPos");
|
||||
|
||||
if(this->Type==InternalAlignment)
|
||||
AlignmentType = (InternalAlignmentType) reader.getAttributeAsInteger("InternalAlignmentType");
|
||||
else
|
||||
AlignmentType = Undef;
|
||||
|
||||
// read the third geo group if present
|
||||
if (reader.hasAttribute("Third")) {
|
||||
Third = reader.getAttributeAsInteger("Third");
|
||||
|
||||
@@ -31,21 +31,30 @@ namespace Sketcher
|
||||
{
|
||||
|
||||
enum ConstraintType {
|
||||
None,
|
||||
Coincident,
|
||||
Horizontal,
|
||||
Vertical,
|
||||
Parallel,
|
||||
Tangent,
|
||||
Distance,
|
||||
DistanceX,
|
||||
DistanceY,
|
||||
Angle,
|
||||
Perpendicular,
|
||||
Radius,
|
||||
Equal,
|
||||
PointOnObject,
|
||||
Symmetric
|
||||
None = 0,
|
||||
Coincident = 1,
|
||||
Horizontal = 2,
|
||||
Vertical = 3,
|
||||
Parallel = 4,
|
||||
Tangent = 5,
|
||||
Distance = 6,
|
||||
DistanceX = 7,
|
||||
DistanceY = 8,
|
||||
Angle = 9,
|
||||
Perpendicular = 10,
|
||||
Radius = 11,
|
||||
Equal = 12,
|
||||
PointOnObject = 13,
|
||||
Symmetric = 14,
|
||||
InternalAlignment = 15
|
||||
};
|
||||
|
||||
enum InternalAlignmentType {
|
||||
Undef = 0,
|
||||
EllipseMajorDiameter = 1,
|
||||
EllipseMinorDiameter = 2,
|
||||
EllipseFocus1 = 3,
|
||||
EllipseFocus2 = 4
|
||||
};
|
||||
|
||||
/// define if you want to use the end or start point
|
||||
@@ -74,6 +83,7 @@ public:
|
||||
|
||||
public:
|
||||
ConstraintType Type;
|
||||
InternalAlignmentType AlignmentType;
|
||||
std::string Name;
|
||||
double Value;
|
||||
int First;
|
||||
|
||||
@@ -93,6 +93,20 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
this->getConstraintPtr()->Type = Equal;
|
||||
valid = true;
|
||||
}
|
||||
else if (strstr(ConstraintType,"InternalAlignment") != NULL) {
|
||||
this->getConstraintPtr()->Type = InternalAlignment;
|
||||
|
||||
valid = true;
|
||||
if(strstr(ConstraintType,"EllipseMajorDiameter") != NULL)
|
||||
this->getConstraintPtr()->AlignmentType=EllipseMajorDiameter;
|
||||
else if(strstr(ConstraintType,"EllipseMinorDiameter") != NULL)
|
||||
this->getConstraintPtr()->AlignmentType=EllipseMinorDiameter;
|
||||
else {
|
||||
this->getConstraintPtr()->AlignmentType=Undef;
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->Second = SecondIndex;
|
||||
@@ -155,6 +169,20 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
this->getConstraintPtr()->Type = PointOnObject;
|
||||
valid = true;
|
||||
}
|
||||
else if (strstr(ConstraintType,"InternalAlignment") != NULL) {
|
||||
this->getConstraintPtr()->Type = InternalAlignment;
|
||||
|
||||
valid = true;
|
||||
|
||||
if(strstr(ConstraintType,"EllipseFocus1") != NULL)
|
||||
this->getConstraintPtr()->AlignmentType=EllipseFocus1;
|
||||
else if(strstr(ConstraintType,"EllipseFocus2") != NULL)
|
||||
this->getConstraintPtr()->AlignmentType=EllipseFocus2;
|
||||
else {
|
||||
this->getConstraintPtr()->AlignmentType=Undef;
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
if (valid) {
|
||||
this->getConstraintPtr()->First = FirstIndex;
|
||||
this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) FirstPos;
|
||||
@@ -340,17 +368,27 @@ std::string ConstraintPy::representation(void) 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 Parallel : result << "'Parallel'>";break;
|
||||
case Tangent : result << "'Tangent'>";break;
|
||||
case Distance : result << "'Distance'>";break;
|
||||
case Angle : result << "'Angle'>";break;
|
||||
default : result << "'?'>";break;
|
||||
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 Parallel : result << "'Parallel'>";break;
|
||||
case Tangent : result << "'Tangent'>";break;
|
||||
case Distance : result << "'Distance'>";break;
|
||||
case Angle : result << "'Angle'>";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;
|
||||
default : result << "'?'>";break;
|
||||
}
|
||||
return result.str();
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <Mod/Part/App/GeometryCurvePy.h>
|
||||
#include <Mod/Part/App/ArcOfCirclePy.h>
|
||||
#include <Mod/Part/App/ArcOfEllipsePy.h>
|
||||
#include <Mod/Part/App/CirclePy.h>
|
||||
#include <Mod/Part/App/EllipsePy.h>
|
||||
#include <Mod/Part/App/LinePy.h>
|
||||
@@ -78,6 +79,8 @@ void Sketch::clear(void)
|
||||
Lines.clear();
|
||||
Arcs.clear();
|
||||
Circles.clear();
|
||||
Ellipses.clear();
|
||||
ArcsOfEllipse.clear();
|
||||
|
||||
// deleting the doubles allocated with new
|
||||
for (std::vector<double*>::iterator it = Parameters.begin(); it != Parameters.end(); ++it)
|
||||
@@ -142,6 +145,8 @@ const char* nameByType(Sketch::GeoType type)
|
||||
return "circle";
|
||||
case Sketch::Ellipse:
|
||||
return "ellipse";
|
||||
case Sketch::ArcOfEllipse:
|
||||
return "arcofellipse";
|
||||
case Sketch::None:
|
||||
default:
|
||||
return "unknown";
|
||||
@@ -164,10 +169,18 @@ int Sketch::addGeometry(const Part::Geometry *geo, bool fixed)
|
||||
const GeomCircle *circle = dynamic_cast<const GeomCircle*>(geo);
|
||||
// create the definition struct for that geom
|
||||
return addCircle(*circle, fixed);
|
||||
} else if (geo->getTypeId() == GeomEllipse::getClassTypeId()) { // add a ellipse
|
||||
const GeomEllipse *ellipse = dynamic_cast<const GeomEllipse*>(geo);
|
||||
// create the definition struct for that geom
|
||||
return addEllipse(*ellipse, fixed);
|
||||
} else if (geo->getTypeId() == GeomArcOfCircle::getClassTypeId()) { // add an arc
|
||||
const GeomArcOfCircle *aoc = dynamic_cast<const GeomArcOfCircle*>(geo);
|
||||
// create the definition struct for that geom
|
||||
return addArc(*aoc, fixed);
|
||||
} else if (geo->getTypeId() == GeomArcOfEllipse::getClassTypeId()) { // add an arc
|
||||
const GeomArcOfEllipse *aoe = dynamic_cast<const GeomArcOfEllipse*>(geo);
|
||||
// create the definition struct for that geom
|
||||
return addArcOfEllipse(*aoe, fixed);
|
||||
} else {
|
||||
Base::Exception("Sketch::addGeometry(): Unknown or unsupported type added to a sketch");
|
||||
return 0;
|
||||
@@ -341,6 +354,99 @@ int Sketch::addArc(const Part::GeomArcOfCircle &circleSegment, bool fixed)
|
||||
return Geoms.size()-1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int Sketch::addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool fixed)
|
||||
{
|
||||
std::vector<double *> ¶ms = fixed ? FixParameters : Parameters;
|
||||
|
||||
// create our own copy
|
||||
GeomArcOfEllipse *aoe = static_cast<GeomArcOfEllipse*>(ellipseSegment.clone());
|
||||
// create the definition struct for that geom
|
||||
GeoDef def;
|
||||
def.geo = aoe;
|
||||
def.type = ArcOfEllipse;
|
||||
|
||||
Base::Vector3d center = aoe->getCenter();
|
||||
Base::Vector3d startPnt = aoe->getStartPoint();
|
||||
Base::Vector3d endPnt = aoe->getEndPoint();
|
||||
double radmaj = aoe->getMajorRadius();
|
||||
double radmin = aoe->getMinorRadius();
|
||||
double phi = aoe->getAngleXU();
|
||||
|
||||
double dist_C_F = sqrt(radmaj*radmaj-radmin*radmin);
|
||||
// solver parameters
|
||||
Base::Vector3d focus1 = center+dist_C_F*Vector3d(cos(phi), sin(phi),0); //+x
|
||||
|
||||
double startAngle, endAngle;
|
||||
aoe->getRange(startAngle, endAngle);
|
||||
|
||||
GCS::Point p1, p2, p3;
|
||||
GCS::Point f1;
|
||||
|
||||
params.push_back(new double(startPnt.x));
|
||||
params.push_back(new double(startPnt.y));
|
||||
p1.x = params[params.size()-2];
|
||||
p1.y = params[params.size()-1];
|
||||
|
||||
params.push_back(new double(endPnt.x));
|
||||
params.push_back(new double(endPnt.y));
|
||||
p2.x = params[params.size()-2];
|
||||
p2.y = params[params.size()-1];
|
||||
|
||||
params.push_back(new double(center.x));
|
||||
params.push_back(new double(center.y));
|
||||
p3.x = params[params.size()-2];
|
||||
p3.y = params[params.size()-1];
|
||||
|
||||
params.push_back(new double(focus1.x));
|
||||
params.push_back(new double(focus1.y));
|
||||
f1.x = params[params.size()-2];
|
||||
f1.y = params[params.size()-1];
|
||||
|
||||
def.startPointId = Points.size();
|
||||
Points.push_back(p1);
|
||||
def.endPointId = Points.size();
|
||||
Points.push_back(p2);
|
||||
def.midPointId = Points.size();
|
||||
Points.push_back(p3);
|
||||
|
||||
Points.push_back(f1);
|
||||
|
||||
|
||||
// add the radius parameters
|
||||
params.push_back(new double(radmin));
|
||||
double *rmin = params[params.size()-1];
|
||||
params.push_back(new double(startAngle));
|
||||
double *a1 = params[params.size()-1];
|
||||
params.push_back(new double(endAngle));
|
||||
double *a2 = params[params.size()-1];
|
||||
|
||||
|
||||
|
||||
// set the arc for later constraints
|
||||
GCS::ArcOfEllipse a;
|
||||
a.start = p1;
|
||||
a.end = p2;
|
||||
a.center = p3;
|
||||
a.focus1 = f1;
|
||||
a.radmin = rmin;
|
||||
a.startAngle = a1;
|
||||
a.endAngle = a2;
|
||||
def.index = ArcsOfEllipse.size();
|
||||
ArcsOfEllipse.push_back(a);
|
||||
|
||||
// store complete set
|
||||
Geoms.push_back(def);
|
||||
|
||||
// arcs require an ArcRules constraint for the end points
|
||||
if (!fixed)
|
||||
GCSsys.addConstraintArcOfEllipseRules(a); // TODO: ArcOfEllipse implementation.
|
||||
|
||||
// return the position of the newly added geometry
|
||||
return Geoms.size()-1;
|
||||
}
|
||||
|
||||
int Sketch::addCircle(const Part::GeomCircle &cir, bool fixed)
|
||||
{
|
||||
std::vector<double *> ¶ms = fixed ? FixParameters : Parameters;
|
||||
@@ -384,8 +490,66 @@ int Sketch::addCircle(const Part::GeomCircle &cir, bool fixed)
|
||||
return Geoms.size()-1;
|
||||
}
|
||||
|
||||
int Sketch::addEllipse(const Part::GeomEllipse &ellipse, bool fixed)
|
||||
int Sketch::addEllipse(const Part::GeomEllipse &elip, bool fixed)
|
||||
{
|
||||
// TODO: Ellipse
|
||||
std::vector<double *> ¶ms = fixed ? FixParameters : Parameters;
|
||||
|
||||
// create our own copy
|
||||
GeomEllipse *elips = static_cast<GeomEllipse*>(elip.clone());
|
||||
// create the definition struct for that geom
|
||||
GeoDef def;
|
||||
def.geo = elips;
|
||||
def.type = Ellipse;
|
||||
|
||||
Base::Vector3d center = elips->getCenter();
|
||||
double radmaj = elips->getMajorRadius();
|
||||
double radmin = elips->getMinorRadius();
|
||||
double phi = elips->getAngleXU();
|
||||
|
||||
double dist_C_F = sqrt(radmaj*radmaj-radmin*radmin);
|
||||
// solver parameters
|
||||
Base::Vector3d focus1 = center+dist_C_F*Vector3d(cos(phi), sin(phi),0); //+x
|
||||
//double *radmin;
|
||||
|
||||
GCS::Point c;
|
||||
|
||||
params.push_back(new double(center.x));
|
||||
params.push_back(new double(center.y));
|
||||
c.x = params[params.size()-2];
|
||||
c.y = params[params.size()-1];
|
||||
|
||||
def.midPointId = Points.size(); // this takes midPointId+1
|
||||
Points.push_back(c);
|
||||
|
||||
GCS::Point f1;
|
||||
|
||||
params.push_back(new double(focus1.x));
|
||||
params.push_back(new double(focus1.y));
|
||||
f1.x = params[params.size()-2];
|
||||
f1.y = params[params.size()-1];
|
||||
|
||||
//def.midPointId = Points.size();
|
||||
Points.push_back(f1);
|
||||
|
||||
|
||||
|
||||
// add the radius parameters
|
||||
params.push_back(new double(radmin));
|
||||
double *rmin = params[params.size()-1];
|
||||
|
||||
// set the ellipse for later constraints
|
||||
GCS::Ellipse e;
|
||||
e.focus1 = f1;
|
||||
e.center = c;
|
||||
e.radmin = rmin;
|
||||
|
||||
def.index = Ellipses.size();
|
||||
Ellipses.push_back(e);
|
||||
|
||||
// store complete set
|
||||
Geoms.push_back(def);
|
||||
|
||||
// return the position of the newly added geometry
|
||||
return Geoms.size()-1;
|
||||
}
|
||||
@@ -422,7 +586,11 @@ Py::Tuple Sketch::getPyGeometry(void) const
|
||||
} else if (it->type == Ellipse) {
|
||||
GeomEllipse *ellipse = dynamic_cast<GeomEllipse*>(it->geo->clone());
|
||||
tuple[i] = Py::asObject(new EllipsePy(ellipse));
|
||||
} else {
|
||||
} else if (it->type == ArcOfEllipse) {
|
||||
GeomArcOfEllipse *ellipse = dynamic_cast<GeomArcOfEllipse*>(it->geo->clone());
|
||||
tuple[i] = Py::asObject(new ArcOfEllipsePy(ellipse));
|
||||
}
|
||||
else {
|
||||
// not implemented type in the sketch!
|
||||
}
|
||||
}
|
||||
@@ -549,6 +717,22 @@ int Sketch::addConstraint(const Constraint *constraint)
|
||||
rtn = addSymmetricConstraint(constraint->First,constraint->FirstPos,
|
||||
constraint->Second,constraint->SecondPos,constraint->Third);
|
||||
break;
|
||||
case InternalAlignment:
|
||||
switch(constraint->AlignmentType) {
|
||||
case EllipseMajorDiameter:
|
||||
rtn = addInternalAlignmentEllipseMajorDiameter(constraint->First,constraint->Second);
|
||||
break;
|
||||
case EllipseMinorDiameter:
|
||||
rtn = addInternalAlignmentEllipseMinorDiameter(constraint->First,constraint->Second);
|
||||
break;
|
||||
case EllipseFocus1:
|
||||
rtn = addInternalAlignmentEllipseFocus1(constraint->First,constraint->Second);
|
||||
break;
|
||||
case EllipseFocus2:
|
||||
rtn = addInternalAlignmentEllipseFocus2(constraint->First,constraint->Second);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case None:
|
||||
break;
|
||||
}
|
||||
@@ -861,6 +1045,15 @@ int Sketch::addPerpendicularConstraint(int geoId1, PointPos pos1, int geoId2)
|
||||
GCSsys.addConstraintPointOnLine(p2, l1, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else if (Geoms[geoId2].type == Ellipse) {
|
||||
// TODO: Ellipse
|
||||
GCS::Ellipse &c2 = Ellipses[Geoms[geoId2].index];
|
||||
GCS::Point &p2 = Points[Geoms[geoId2].midPointId];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintPointOnEllipse(p1, c2, tag);
|
||||
GCSsys.addConstraintPointOnLine(p2, l1, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
else if (Geoms[geoId1].type == Arc) {
|
||||
GCS::Arc &a1 = Arcs[Geoms[geoId1].index];
|
||||
@@ -871,7 +1064,8 @@ int Sketch::addPerpendicularConstraint(int geoId1, PointPos pos1, int geoId2)
|
||||
GCSsys.addConstraintPointOnLine(a1.center, l2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else if (Geoms[geoId2].type == Arc || Geoms[geoId2].type == Circle) {
|
||||
else if (Geoms[geoId2].type == Arc || Geoms[geoId2].type == Circle || Geoms[geoId2].type == Ellipse) {
|
||||
// TODO: ellipse real implementation
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCS::Point ¢er = Points[Geoms[geoId2].midPointId];
|
||||
double *radius;
|
||||
@@ -879,10 +1073,15 @@ int Sketch::addPerpendicularConstraint(int geoId1, PointPos pos1, int geoId2)
|
||||
GCS::Arc &a2 = Arcs[Geoms[geoId2].index];
|
||||
radius = a2.rad;
|
||||
}
|
||||
else {
|
||||
else if (Geoms[geoId2].type == Circle) {
|
||||
GCS::Circle &c2 = Circles[Geoms[geoId2].index];
|
||||
radius = c2.rad;
|
||||
}
|
||||
else {
|
||||
// TODO: Ellipse
|
||||
GCS::Ellipse &c2 = Ellipses[Geoms[geoId2].index];
|
||||
radius = c2.radmin;
|
||||
}
|
||||
if (pos1 == start)
|
||||
GCSsys.addConstraintPerpendicularCircle2Arc(center, radius, a1, tag);
|
||||
else if (pos1 == end)
|
||||
@@ -1026,6 +1225,18 @@ int Sketch::addTangentConstraint(int geoId1, int geoId2)
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangent(l, c, tag);
|
||||
return ConstraintsCounter;
|
||||
} else if (Geoms[geoId2].type == Ellipse) {
|
||||
// TODO: real implementation
|
||||
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangent(l, e, tag);
|
||||
return ConstraintsCounter;
|
||||
} else if (Geoms[geoId2].type == ArcOfEllipse) {
|
||||
// TODO: real implementation
|
||||
GCS::ArcOfEllipse &a = ArcsOfEllipse[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangent(l, a, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
} else if (Geoms[geoId1].type == Circle) {
|
||||
GCS::Circle &c = Circles[Geoms[geoId1].index];
|
||||
@@ -1034,12 +1245,33 @@ int Sketch::addTangentConstraint(int geoId1, int geoId2)
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangent(c, c2, tag);
|
||||
return ConstraintsCounter;
|
||||
} else if (Geoms[geoId2].type == Arc) {
|
||||
} else if (Geoms[geoId2].type == Ellipse) {
|
||||
// TODO: real implementation
|
||||
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangent(e, c, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else if (Geoms[geoId2].type == Arc) {
|
||||
GCS::Arc &a = Arcs[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangent(c, a, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
} else if (Geoms[geoId1].type == Ellipse) {
|
||||
GCS::Ellipse &e = Ellipses[Geoms[geoId1].index];
|
||||
// TODO: Ellipse
|
||||
if (Geoms[geoId2].type == Circle) {
|
||||
GCS::Circle &c = Circles[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangent(e, c, tag);
|
||||
return ConstraintsCounter;
|
||||
} else if (Geoms[geoId2].type == Arc) {
|
||||
GCS::Arc &a = Arcs[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangent(e, a, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
} else if (Geoms[geoId1].type == Arc) {
|
||||
GCS::Arc &a = Arcs[Geoms[geoId1].index];
|
||||
if (Geoms[geoId2].type == Circle) {
|
||||
@@ -1047,6 +1279,12 @@ int Sketch::addTangentConstraint(int geoId1, int geoId2)
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangent(c, a, tag);
|
||||
return ConstraintsCounter;
|
||||
} else if (Geoms[geoId2].type == Ellipse) {
|
||||
// TODO: Ellipse
|
||||
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangent(e, a, tag);
|
||||
return ConstraintsCounter;
|
||||
} else if (Geoms[geoId2].type == Arc) {
|
||||
GCS::Arc &a2 = Arcs[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
@@ -1096,6 +1334,14 @@ int Sketch::addTangentConstraint(int geoId1, PointPos pos1, int geoId2)
|
||||
GCSsys.addConstraintTangent(l1, c2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else if (Geoms[geoId2].type == Ellipse) {
|
||||
// TODO: Ellipse
|
||||
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintPointOnEllipse(p1, e, tag);
|
||||
GCSsys.addConstraintTangent(l1, e, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
else if (Geoms[geoId1].type == Arc) {
|
||||
GCS::Arc &a1 = Arcs[Geoms[geoId1].index];
|
||||
@@ -1125,6 +1371,19 @@ int Sketch::addTangentConstraint(int geoId1, PointPos pos1, int geoId2)
|
||||
GCSsys.addConstraintTangentArc2Circle(a1, c2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
} else if (Geoms[geoId2].type == Ellipse) {
|
||||
// TODO: Ellipse
|
||||
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
|
||||
if (pos1 == start) {
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangentEllipse2Arc(e, a1, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else if (pos1 == end) {
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangentArc2Ellipse(a1, e, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -1198,6 +1457,35 @@ int Sketch::addTangentConstraint(int geoId1, PointPos pos1, int geoId2, PointPos
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (Geoms[geoId2].type == ArcOfEllipse) {
|
||||
GCS::ArcOfEllipse &a2 = ArcsOfEllipse[Geoms[geoId2].index];
|
||||
if (pos2 == start) {
|
||||
if (pos1 == start) {
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangentLine2ArcOfEllipse(l1.p2, l1.p1, l1, a2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else if (pos1 == end) {
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangentLine2ArcOfEllipse(l1.p1, l1.p2, l1, a2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
else if (pos2 == end) {
|
||||
if (pos1 == start) {
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangentArcOfEllipse2Line(a2, l1, l1.p1, l1.p2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else if (pos1 == end) {
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintTangentArcOfEllipse2Line(a2, l1, l1.p2, l1.p1, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (Geoms[geoId1].type == Arc) {
|
||||
GCS::Arc &a1 = Arcs[Geoms[geoId1].index];
|
||||
@@ -1309,7 +1597,7 @@ int Sketch::addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, PointPo
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Sketch::addRadiusConstraint(int geoId, double value)
|
||||
int Sketch::addRadiusConstraint(int geoId, double value, int radiusnumber)
|
||||
{
|
||||
geoId = checkGeoId(geoId);
|
||||
|
||||
@@ -1448,6 +1736,18 @@ int Sketch::addEqualConstraint(int geoId1, int geoId2)
|
||||
else
|
||||
std::swap(geoId1, geoId2);
|
||||
}
|
||||
// TODO: Ellipse
|
||||
if (Geoms[geoId2].type == Ellipse) {
|
||||
if (Geoms[geoId1].type == Ellipse) {
|
||||
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
|
||||
GCS::Ellipse &e2 = Ellipses[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintEqualRadii(e1, e2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else
|
||||
std::swap(geoId1, geoId2);
|
||||
}
|
||||
|
||||
if (Geoms[geoId1].type == Circle) {
|
||||
GCS::Circle &c1 = Circles[Geoms[geoId1].index];
|
||||
@@ -1502,6 +1802,18 @@ int Sketch::addPointOnObjectConstraint(int geoId1, PointPos pos1, int geoId2)
|
||||
GCSsys.addConstraintPointOnCircle(p1, c, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else if (Geoms[geoId2].type == Ellipse) {
|
||||
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintPointOnEllipse(p1, e, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else if (Geoms[geoId2].type == ArcOfEllipse) {
|
||||
GCS::ArcOfEllipse &a = ArcsOfEllipse[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintPointOnArcOfEllipse(p1, a, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -1555,6 +1867,167 @@ int Sketch::addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointP
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Sketch::addInternalAlignmentEllipseMajorDiameter(int geoId1, int geoId2)
|
||||
{
|
||||
std::swap(geoId1, geoId2);
|
||||
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
geoId2 = checkGeoId(geoId2);
|
||||
|
||||
if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse)
|
||||
return -1;
|
||||
if (Geoms[geoId2].type != Line)
|
||||
return -1;
|
||||
|
||||
int pointId1 = getPointId(geoId2, start);
|
||||
int pointId2 = getPointId(geoId2, end);
|
||||
|
||||
if (pointId1 >= 0 && pointId1 < int(Points.size()) &&
|
||||
pointId2 >= 0 && pointId2 < int(Points.size())) {
|
||||
GCS::Point &p1 = Points[pointId1];
|
||||
GCS::Point &p2 = Points[pointId2];
|
||||
|
||||
if(Geoms[geoId1].type == Ellipse) {
|
||||
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
|
||||
|
||||
// constraints
|
||||
// 1. start point with ellipse -a
|
||||
// 2. end point with ellipse +a
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentEllipseMajorDiameter(e1, p1, p2, tag);
|
||||
return ConstraintsCounter;
|
||||
|
||||
}
|
||||
else {
|
||||
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
|
||||
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentEllipseMajorDiameter(a1, p1, p2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Sketch::addInternalAlignmentEllipseMinorDiameter(int geoId1, int geoId2)
|
||||
{
|
||||
std::swap(geoId1, geoId2);
|
||||
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
geoId2 = checkGeoId(geoId2);
|
||||
|
||||
if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse)
|
||||
return -1;
|
||||
if (Geoms[geoId2].type != Line)
|
||||
return -1;
|
||||
|
||||
int pointId1 = getPointId(geoId2, start);
|
||||
int pointId2 = getPointId(geoId2, end);
|
||||
|
||||
if (pointId1 >= 0 && pointId1 < int(Points.size()) &&
|
||||
pointId2 >= 0 && pointId2 < int(Points.size())) {
|
||||
GCS::Point &p1 = Points[pointId1];
|
||||
GCS::Point &p2 = Points[pointId2];
|
||||
|
||||
if(Geoms[geoId1].type == Ellipse) {
|
||||
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
|
||||
|
||||
// constraints
|
||||
// 1. start point with ellipse -a
|
||||
// 2. end point with ellipse +a
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentEllipseMinorDiameter(e1, p1, p2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else {
|
||||
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
|
||||
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentEllipseMinorDiameter(a1, p1, p2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Sketch::addInternalAlignmentEllipseFocus1(int geoId1, int geoId2)
|
||||
{
|
||||
std::swap(geoId1, geoId2);
|
||||
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
geoId2 = checkGeoId(geoId2);
|
||||
|
||||
if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse)
|
||||
return -1;
|
||||
if (Geoms[geoId2].type != Point)
|
||||
return -1;
|
||||
|
||||
int pointId1 = getPointId(geoId2, start);
|
||||
|
||||
if (pointId1 >= 0 && pointId1 < int(Points.size())) {
|
||||
GCS::Point &p1 = Points[pointId1];
|
||||
|
||||
if(Geoms[geoId1].type == Ellipse) {
|
||||
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
|
||||
|
||||
// constraints
|
||||
// 1. start point with ellipse -a
|
||||
// 2. end point with ellipse +a
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentEllipseFocus1(e1, p1, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else {
|
||||
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
|
||||
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentEllipseFocus1(a1, p1, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int Sketch::addInternalAlignmentEllipseFocus2(int geoId1, int geoId2)
|
||||
{
|
||||
std::swap(geoId1, geoId2);
|
||||
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
geoId2 = checkGeoId(geoId2);
|
||||
|
||||
if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse)
|
||||
return -1;
|
||||
if (Geoms[geoId2].type != Point)
|
||||
return -1;
|
||||
|
||||
int pointId1 = getPointId(geoId2, start);
|
||||
|
||||
if (pointId1 >= 0 && pointId1 < int(Points.size())) {
|
||||
GCS::Point &p1 = Points[pointId1];
|
||||
|
||||
if(Geoms[geoId1].type == Ellipse) {
|
||||
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
|
||||
|
||||
// constraints
|
||||
// 1. start point with ellipse -a
|
||||
// 2. end point with ellipse +a
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentEllipseFocus2(e1, p1, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else {
|
||||
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
|
||||
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintInternalAlignmentEllipseFocus2(a1, p1, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
bool Sketch::updateGeometry()
|
||||
{
|
||||
int i=0;
|
||||
@@ -1589,6 +2062,25 @@ bool Sketch::updateGeometry()
|
||||
);
|
||||
aoc->setRadius(*myArc.rad);
|
||||
aoc->setRange(*myArc.startAngle, *myArc.endAngle);
|
||||
} else if (it->type == ArcOfEllipse) {
|
||||
GCS::ArcOfEllipse &myArc = ArcsOfEllipse[it->index];
|
||||
|
||||
GeomArcOfEllipse *aoe = dynamic_cast<GeomArcOfEllipse*>(it->geo);
|
||||
|
||||
Base::Vector3d center = Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0);
|
||||
Base::Vector3d f1 = Vector3d(*Points[it->midPointId+1].x, *Points[it->midPointId+1].y, 0.0);
|
||||
double radmin = *ArcsOfEllipse[it->index].radmin;
|
||||
|
||||
Base::Vector3d fd=f1-center;
|
||||
double radmaj = sqrt(fd*fd+radmin*radmin);
|
||||
|
||||
double phi = atan2(fd.y,fd.x);
|
||||
|
||||
aoe->setCenter(center);
|
||||
aoe->setMajorRadius(radmaj);
|
||||
aoe->setMinorRadius(radmin);
|
||||
aoe->setAngleXU(phi);
|
||||
aoe->setRange(*myArc.startAngle, *myArc.endAngle);
|
||||
} else if (it->type == Circle) {
|
||||
GeomCircle *circ = dynamic_cast<GeomCircle*>(it->geo);
|
||||
circ->setCenter(Vector3d(*Points[it->midPointId].x,
|
||||
@@ -1596,6 +2088,23 @@ bool Sketch::updateGeometry()
|
||||
0.0)
|
||||
);
|
||||
circ->setRadius(*Circles[it->index].rad);
|
||||
} else if (it->type == Ellipse) {
|
||||
// TODO: Ellipse
|
||||
GeomEllipse *ellipse = dynamic_cast<GeomEllipse*>(it->geo);
|
||||
|
||||
Base::Vector3d center = Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0);
|
||||
Base::Vector3d f1 = Vector3d(*Points[it->midPointId+1].x, *Points[it->midPointId+1].y, 0.0);
|
||||
double radmin = *Ellipses[it->index].radmin;
|
||||
|
||||
Base::Vector3d fd=f1-center;
|
||||
double radmaj = sqrt(fd*fd+radmin*radmin);
|
||||
|
||||
double phi = atan2(fd.y,fd.x);
|
||||
|
||||
ellipse->setCenter(center);
|
||||
ellipse->setMajorRadius(radmaj);
|
||||
ellipse->setMinorRadius(radmin);
|
||||
ellipse->setAngleXU(phi);
|
||||
}
|
||||
} catch (Base::Exception e) {
|
||||
Base::Console().Error("Updating geometry: Error build geometry(%d): %s\n",
|
||||
@@ -1771,6 +2280,72 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
|
||||
GCSsys.rescaleConstraint(i-1, 0.01);
|
||||
GCSsys.rescaleConstraint(i, 0.01);
|
||||
}
|
||||
} else if (Geoms[geoId].type == Ellipse) {
|
||||
// TODO: Ellipse
|
||||
GCS::Point ¢er = Points[Geoms[geoId].midPointId];
|
||||
GCS::Point p0,p1;
|
||||
if (pos == mid) {
|
||||
MoveParameters.resize(2); // cx,cy
|
||||
p0.x = &MoveParameters[0];
|
||||
p0.y = &MoveParameters[1];
|
||||
*p0.x = *center.x;
|
||||
*p0.y = *center.y;
|
||||
GCSsys.addConstraintP2PCoincident(p0,center,-1);
|
||||
} else if (pos == none) {
|
||||
// TODO: Ellipse
|
||||
MoveParameters.resize(4); // x,y,cx,cy
|
||||
GCS::Ellipse &e = Ellipses[Geoms[geoId].index];
|
||||
p0.x = &MoveParameters[0];
|
||||
p0.y = &MoveParameters[1];
|
||||
*p0.x = *center.x;
|
||||
*p0.y = *center.y + *e.radmin;
|
||||
GCSsys.addConstraintPointOnEllipse(p0,e,-1);
|
||||
p1.x = &MoveParameters[2];
|
||||
p1.y = &MoveParameters[3];
|
||||
*p1.x = *center.x;
|
||||
*p1.y = *center.y;
|
||||
int i=GCSsys.addConstraintP2PCoincident(p1,center,-1);
|
||||
GCSsys.rescaleConstraint(i-1, 0.01);
|
||||
GCSsys.rescaleConstraint(i, 0.01);
|
||||
}
|
||||
} else if (Geoms[geoId].type == ArcOfEllipse) {
|
||||
// TODO: ArcOfEllipse
|
||||
GCS::Point ¢er = Points[Geoms[geoId].midPointId];
|
||||
GCS::Point p0,p1;
|
||||
if (pos == mid) {
|
||||
MoveParameters.resize(2); // cx,cy
|
||||
p0.x = &MoveParameters[0];
|
||||
p0.y = &MoveParameters[1];
|
||||
*p0.x = *center.x;
|
||||
*p0.y = *center.y;
|
||||
GCSsys.addConstraintP2PCoincident(p0,center,-1);
|
||||
} else if (pos == start || pos == end || pos == none) {
|
||||
// TODO: Ellipse
|
||||
MoveParameters.resize(4); // x,y,cx,cy
|
||||
if (pos == start || pos == end) {
|
||||
GCS::Point &p = (pos == start) ? Points[Geoms[geoId].startPointId]
|
||||
: Points[Geoms[geoId].endPointId];;
|
||||
p0.x = &MoveParameters[0];
|
||||
p0.y = &MoveParameters[1];
|
||||
*p0.x = *p.x;
|
||||
*p0.y = *p.y;
|
||||
GCSsys.addConstraintP2PCoincident(p0,p,-1);
|
||||
} else if (pos == none) {
|
||||
GCS::ArcOfEllipse &a = ArcsOfEllipse[Geoms[geoId].index];
|
||||
p0.x = &MoveParameters[0];
|
||||
p0.y = &MoveParameters[1];
|
||||
*p0.x = *center.x;
|
||||
*p0.y = *center.y + *a.radmin;
|
||||
GCSsys.addConstraintPointOnArcOfEllipse(p0,a,-1);
|
||||
}
|
||||
p1.x = &MoveParameters[2];
|
||||
p1.y = &MoveParameters[3];
|
||||
*p1.x = *center.x;
|
||||
*p1.y = *center.y;
|
||||
int i=GCSsys.addConstraintP2PCoincident(p1,center,-1);
|
||||
GCSsys.rescaleConstraint(i-1, 0.01);
|
||||
GCSsys.rescaleConstraint(i, 0.01);
|
||||
}
|
||||
} else if (Geoms[geoId].type == Arc) {
|
||||
GCS::Point ¢er = Points[Geoms[geoId].midPointId];
|
||||
GCS::Point p0,p1;
|
||||
@@ -1858,6 +2433,16 @@ int Sketch::movePoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool rela
|
||||
MoveParameters[0] = toPoint.x;
|
||||
MoveParameters[1] = toPoint.y;
|
||||
}
|
||||
} else if (Geoms[geoId].type == Ellipse) {
|
||||
if (pos == mid || pos == none) {
|
||||
MoveParameters[0] = toPoint.x;
|
||||
MoveParameters[1] = toPoint.y;
|
||||
}
|
||||
} else if (Geoms[geoId].type == ArcOfEllipse) {
|
||||
if (pos == start || pos == end || pos == mid || pos == none) {
|
||||
MoveParameters[0] = toPoint.x;
|
||||
MoveParameters[1] = toPoint.y;
|
||||
}
|
||||
}
|
||||
|
||||
return solve();
|
||||
@@ -1886,6 +2471,33 @@ int Sketch::getPointId(int geoId, PointPos pos) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Sketch::getVisiblePointId(int geoId, PointPos pos) const
|
||||
{
|
||||
// do a range check first
|
||||
if (geoId < 0 || geoId >= (int)Geoms.size())
|
||||
return -1;
|
||||
|
||||
int invisiblepoints = 0;
|
||||
int i;
|
||||
|
||||
// calculate the number of points in the solver that are not visible in the UI
|
||||
for(i=0;i<geoId;i++)
|
||||
if(Geoms[i].type == Ellipse || Geoms[i].type == ArcOfEllipse)
|
||||
invisiblepoints++;
|
||||
|
||||
switch (pos) {
|
||||
case start:
|
||||
return Geoms[geoId].startPointId-invisiblepoints;
|
||||
case end:
|
||||
return Geoms[geoId].endPointId-invisiblepoints;
|
||||
case mid:
|
||||
return Geoms[geoId].midPointId-invisiblepoints;
|
||||
case none:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Base::Vector3d Sketch::getPoint(int geoId, PointPos pos)
|
||||
{
|
||||
geoId = checkGeoId(geoId);
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
#include "Constraint.h"
|
||||
|
||||
#include "freegcs/GCS.h"
|
||||
|
||||
#include "freegcs/GCS.h"
|
||||
|
||||
#include <Base/Persistence.h>
|
||||
|
||||
@@ -82,6 +82,8 @@ public:
|
||||
|
||||
/// retrieves the index of a point
|
||||
int getPointId(int geoId, PointPos pos) const;
|
||||
int getVisiblePointId(int geoId, PointPos pos) const;
|
||||
|
||||
/// retrieves a point
|
||||
Base::Vector3d getPoint(int geoId, PointPos pos);
|
||||
|
||||
@@ -119,8 +121,10 @@ public:
|
||||
int addArc(const Part::GeomArcOfCircle &circleSegment, bool fixed=false);
|
||||
/// add a circle
|
||||
int addCircle(const Part::GeomCircle &circle, bool fixed=false);
|
||||
/// add a ellipse
|
||||
/// add an ellipse
|
||||
int addEllipse(const Part::GeomEllipse &ellipse, bool fixed=false);
|
||||
/// add an arc of ellipse
|
||||
int addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool fixed=false);
|
||||
//@}
|
||||
|
||||
|
||||
@@ -163,11 +167,14 @@ public:
|
||||
int addTangentConstraint(int geoId1, PointPos pos1, int geoId2);
|
||||
int addTangentConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2);
|
||||
/// add a radius constraint on a circle or an arc
|
||||
int addRadiusConstraint(int geoId, double value);
|
||||
int addRadiusConstraint(int geoId, double value, int radiusnumber=0);
|
||||
/// add an angle constraint on a line or between two lines
|
||||
int addAngleConstraint(int geoId, double value);
|
||||
int addAngleConstraint(int geoId1, int geoId2, double value);
|
||||
int addAngleConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double value);
|
||||
/// add ellipse XDir axis angle constraint with respect to XAxis or a lines
|
||||
int addEllipseAngleXUConstraint(int geoId, double value);
|
||||
int addEllipseAngleXUConstraint(int geoId1, int geoId2, double value);
|
||||
/// 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
|
||||
@@ -177,14 +184,24 @@ public:
|
||||
/// 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);
|
||||
//@}
|
||||
|
||||
|
||||
/// Internal Alignment constraints
|
||||
//@{
|
||||
/// add InternalAlignmentEllipseMajorDiameter to a line and an ellipse
|
||||
int addInternalAlignmentEllipseMajorDiameter(int geoId1, int geoId2);
|
||||
int addInternalAlignmentEllipseMinorDiameter(int geoId1, int geoId2);
|
||||
int addInternalAlignmentEllipseFocus1(int geoId1, int geoId2);
|
||||
int addInternalAlignmentEllipseFocus2(int geoId1, int geoId2);
|
||||
//@}
|
||||
|
||||
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
|
||||
Ellipse = 5, // 1 Point(mid), 5 Parameters(x,y,r1,r2,phi) phi=angle xaxis of elipse with respect of sketch xaxis// TODO: Ellipse
|
||||
ArcOfEllipse = 6
|
||||
};
|
||||
|
||||
float SolveTime;
|
||||
@@ -217,6 +234,8 @@ protected:
|
||||
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;
|
||||
|
||||
bool isInitMove;
|
||||
bool isFine;
|
||||
|
||||
@@ -257,6 +257,10 @@ Base::Vector3d SketchObject::getPoint(int GeoId, PointPos PosId) const
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle*>(geo);
|
||||
if (PosId == mid)
|
||||
return circle->getCenter();
|
||||
} else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
const Part::GeomEllipse *ellipse = dynamic_cast<const Part::GeomEllipse*>(geo);
|
||||
if (PosId == mid)
|
||||
return ellipse->getCenter();
|
||||
} else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
const Part::GeomArcOfCircle *aoc = dynamic_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
if (PosId == start)
|
||||
@@ -265,6 +269,14 @@ Base::Vector3d SketchObject::getPoint(int GeoId, PointPos PosId) const
|
||||
return aoc->getEndPoint();
|
||||
else if (PosId == mid)
|
||||
return aoc->getCenter();
|
||||
} else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
const Part::GeomArcOfEllipse *aoc = dynamic_cast<const Part::GeomArcOfEllipse*>(geo);
|
||||
if (PosId == start)
|
||||
return aoc->getStartPoint();
|
||||
else if (PosId == end)
|
||||
return aoc->getEndPoint();
|
||||
else if (PosId == mid)
|
||||
return aoc->getCenter();
|
||||
}
|
||||
|
||||
return Base::Vector3d();
|
||||
@@ -944,7 +956,9 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
// TODO: Ellipse Trim support
|
||||
return 0;
|
||||
} else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
const Part::GeomArcOfCircle *aoc = dynamic_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
Base::Vector3d center = aoc->getCenter();
|
||||
@@ -1490,6 +1504,9 @@ void SketchObject::rebuildVertexIndex(void)
|
||||
} else if ((*it)->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
VertexId2GeoId.push_back(i);
|
||||
VertexId2PosId.push_back(mid);
|
||||
} else if ((*it)->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
VertexId2GeoId.push_back(i);
|
||||
VertexId2PosId.push_back(mid);
|
||||
} else if ((*it)->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
VertexId2GeoId.push_back(i);
|
||||
VertexId2PosId.push_back(start);
|
||||
@@ -1497,6 +1514,13 @@ void SketchObject::rebuildVertexIndex(void)
|
||||
VertexId2PosId.push_back(end);
|
||||
VertexId2GeoId.push_back(i);
|
||||
VertexId2PosId.push_back(mid);
|
||||
} else if ((*it)->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
VertexId2GeoId.push_back(i);
|
||||
VertexId2PosId.push_back(start);
|
||||
VertexId2GeoId.push_back(i);
|
||||
VertexId2PosId.push_back(end);
|
||||
VertexId2GeoId.push_back(i);
|
||||
VertexId2PosId.push_back(mid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,9 @@ PyObject* SketchObjectPy::addGeometry(PyObject *args)
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomPoint::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
ret = this->getSketchObjectPtr()->addGeometry(geo);
|
||||
}
|
||||
@@ -131,7 +133,9 @@ PyObject* SketchObjectPy::addGeometry(PyObject *args)
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomPoint::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
geoList.push_back(geo);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,7 +46,26 @@ namespace GCS
|
||||
Perpendicular = 9,
|
||||
L2LAngle = 10,
|
||||
MidpointOnLine = 11,
|
||||
TangentCircumf = 12
|
||||
TangentCircumf = 12,
|
||||
P2OnEllipse = 13,
|
||||
TangentEllipseLine = 14,
|
||||
Point2EllipseDistance = 15,
|
||||
InternalAlignmentPoint2Ellipse = 16,
|
||||
EqualMajorAxesEllipse = 17,
|
||||
EllipticalArcRangeToEndPoints = 18
|
||||
};
|
||||
|
||||
enum InternalAlignmentType {
|
||||
EllipsePositiveMajorX = 0,
|
||||
EllipsePositiveMajorY = 1,
|
||||
EllipseNegativeMajorX = 2,
|
||||
EllipseNegativeMajorY = 3,
|
||||
EllipsePositiveMinorX = 4,
|
||||
EllipsePositiveMinorY = 5,
|
||||
EllipseNegativeMinorX = 6,
|
||||
EllipseNegativeMinorY = 7,
|
||||
EllipseFocus2X = 8,
|
||||
EllipseFocus2Y = 9
|
||||
};
|
||||
|
||||
class Constraint
|
||||
@@ -159,6 +178,7 @@ namespace GCS
|
||||
virtual double error();
|
||||
virtual double grad(double *);
|
||||
virtual double maxStep(MAP_pD_D &dir, double lim=1.);
|
||||
double abs(double darea);
|
||||
};
|
||||
|
||||
// PointOnLine
|
||||
@@ -304,6 +324,110 @@ namespace GCS
|
||||
virtual double error();
|
||||
virtual double grad(double *);
|
||||
};
|
||||
// PointOnEllipse
|
||||
class ConstraintPointOnEllipse : public Constraint
|
||||
{
|
||||
private:
|
||||
inline double* p1x() { return pvec[0]; }
|
||||
inline double* p1y() { return pvec[1]; }
|
||||
inline double* cx() { return pvec[2]; }
|
||||
inline double* cy() { return pvec[3]; }
|
||||
inline double* f1x() { return pvec[4]; }
|
||||
inline double* f1y() { return pvec[5]; }
|
||||
inline double* rmin() { return pvec[6]; }
|
||||
public:
|
||||
ConstraintPointOnEllipse(Point &p, Ellipse &e);
|
||||
ConstraintPointOnEllipse(Point &p, ArcOfEllipse &a);
|
||||
virtual ConstraintType getTypeId();
|
||||
virtual void rescale(double coef=1.);
|
||||
virtual double error();
|
||||
virtual double grad(double *);
|
||||
};
|
||||
|
||||
class ConstraintEllipseTangentLine : public Constraint
|
||||
{
|
||||
private:
|
||||
inline double* p1x() { return pvec[0]; }
|
||||
inline double* p1y() { return pvec[1]; }
|
||||
inline double* p2x() { return pvec[2]; }
|
||||
inline double* p2y() { return pvec[3]; }
|
||||
inline double* cx() { return pvec[4]; }
|
||||
inline double* cy() { return pvec[5]; }
|
||||
inline double* f1x() { return pvec[6]; }
|
||||
inline double* f1y() { return pvec[7]; }
|
||||
inline double* rmin() { return pvec[8]; }
|
||||
public:
|
||||
ConstraintEllipseTangentLine(Line &l, Ellipse &e);
|
||||
ConstraintEllipseTangentLine(Line &l, ArcOfEllipse &a);
|
||||
virtual ConstraintType getTypeId();
|
||||
virtual void rescale(double coef=1.);
|
||||
virtual double error();
|
||||
virtual double grad(double *);
|
||||
};
|
||||
|
||||
class ConstraintInternalAlignmentPoint2Ellipse : public Constraint
|
||||
{
|
||||
private:
|
||||
inline double* p1x() { return pvec[0]; }
|
||||
inline double* p1y() { return pvec[1]; }
|
||||
inline double* cx() { return pvec[2]; }
|
||||
inline double* cy() { return pvec[3]; }
|
||||
inline double* f1x() { return pvec[4]; }
|
||||
inline double* f1y() { return pvec[5]; }
|
||||
inline double* rmin() { return pvec[6]; }
|
||||
public:
|
||||
ConstraintInternalAlignmentPoint2Ellipse(Ellipse &e, Point &p1, InternalAlignmentType alignmentType);
|
||||
ConstraintInternalAlignmentPoint2Ellipse(ArcOfEllipse &e, Point &p1, InternalAlignmentType alignmentType);
|
||||
virtual ConstraintType getTypeId();
|
||||
virtual void rescale(double coef=1.);
|
||||
virtual double error();
|
||||
virtual double grad(double *);
|
||||
private:
|
||||
InternalAlignmentType AlignmentType;
|
||||
};
|
||||
|
||||
class ConstraintEqualMajorAxesEllipse : public Constraint
|
||||
{
|
||||
private:
|
||||
inline double* e1cx() { return pvec[0]; }
|
||||
inline double* e1cy() { return pvec[1]; }
|
||||
inline double* e1f1x() { return pvec[2]; }
|
||||
inline double* e1f1y() { return pvec[3]; }
|
||||
inline double* e1rmin() { return pvec[4]; }
|
||||
inline double* e2cx() { return pvec[5]; }
|
||||
inline double* e2cy() { return pvec[6]; }
|
||||
inline double* e2f1x() { return pvec[7]; }
|
||||
inline double* e2f1y() { return pvec[8]; }
|
||||
inline double* e2rmin() { return pvec[9]; }
|
||||
public:
|
||||
ConstraintEqualMajorAxesEllipse(Ellipse &e1, Ellipse &e2);
|
||||
virtual ConstraintType getTypeId();
|
||||
virtual void rescale(double coef=1.);
|
||||
virtual double error();
|
||||
virtual double grad(double *);
|
||||
};
|
||||
|
||||
// EllipticalArcRangeToEndPoints
|
||||
class ConstraintEllipticalArcRangeToEndPoints : public Constraint
|
||||
{
|
||||
private:
|
||||
inline double* p1x() { return pvec[0]; }
|
||||
inline double* p1y() { return pvec[1]; }
|
||||
inline double* angle() { return pvec[2]; }
|
||||
inline double* cx() { return pvec[3]; }
|
||||
inline double* cy() { return pvec[4]; }
|
||||
inline double* f1x() { return pvec[5]; }
|
||||
inline double* f1y() { return pvec[6]; }
|
||||
inline double* rmin() { return pvec[7]; }
|
||||
public:
|
||||
ConstraintEllipticalArcRangeToEndPoints(Point &p, ArcOfEllipse &a, double *angle_t);
|
||||
virtual ConstraintType getTypeId();
|
||||
virtual void rescale(double coef=1.);
|
||||
virtual double error();
|
||||
virtual double grad(double *);
|
||||
virtual double maxStep(MAP_pD_D &dir, double lim=1.);
|
||||
};
|
||||
|
||||
|
||||
} //namespace GCS
|
||||
|
||||
|
||||
@@ -27,6 +27,16 @@
|
||||
#include "qp_eq.h"
|
||||
#include <Eigen/QR>
|
||||
|
||||
#define _GCS_DEBUG 1
|
||||
|
||||
#ifdef _GCS_DEBUG
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/TimeInfo.h>
|
||||
#include <Base/Console.h>
|
||||
#endif // _GCS_DEBUG
|
||||
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/connected_components.hpp>
|
||||
|
||||
@@ -481,6 +491,42 @@ int System::addConstraintPointOnCircle(Point &p, Circle &c, int tagId)
|
||||
return addConstraintP2PDistance(p, c.center, c.rad, tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintPointOnEllipse(Point &p, Ellipse &e, int tagId)
|
||||
{
|
||||
// TODO: Implement real constraint => Done
|
||||
|
||||
Constraint *constr = new ConstraintPointOnEllipse(p, e);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintEllipticalArcRangeToEndPoints(Point &p, ArcOfEllipse &a, double *angle, int tagId)
|
||||
{
|
||||
Constraint *constr = new ConstraintEllipticalArcRangeToEndPoints(p,a,angle);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
|
||||
int System::addConstraintArcOfEllipseRules(ArcOfEllipse &a, int tagId)
|
||||
{
|
||||
/* addConstraintP2PAngle(a.center, a.start, a.startAngle, tagId);
|
||||
return addConstraintP2PAngle(a.center, a.end, a.endAngle, tagId);*/
|
||||
|
||||
addConstraintEllipticalArcRangeToEndPoints(a.start,a,a.startAngle, tagId);
|
||||
addConstraintEllipticalArcRangeToEndPoints(a.end,a,a.endAngle, tagId);
|
||||
|
||||
addConstraintPointOnArcOfEllipse(a.start, a, tagId);
|
||||
return addConstraintPointOnArcOfEllipse(a.end, a, tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintPointOnArcOfEllipse(Point &p, ArcOfEllipse &a, int tagId)
|
||||
{
|
||||
Constraint *constr = new ConstraintPointOnEllipse(p, a);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintPointOnArc(Point &p, Arc &a, int tagId)
|
||||
{
|
||||
return addConstraintP2PDistance(p, a.center, a.rad, tagId);
|
||||
@@ -552,6 +598,39 @@ int System::addConstraintTangent(Line &l, Circle &c, int tagId)
|
||||
return addConstraintP2LDistance(c.center, l, c.rad, tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintTangent(Line &l, Ellipse &e, int tagId)
|
||||
{
|
||||
// TODO: real ellipse implementation => Done
|
||||
Constraint *constr = new ConstraintEllipseTangentLine(l, e);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintTangent(Line &l, ArcOfEllipse &a, int tagId)
|
||||
{
|
||||
// TODO: real ellipse implementation => Done
|
||||
Constraint *constr = new ConstraintEllipseTangentLine(l, a);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintTangent(Ellipse &e, Circle &c, int tagId)
|
||||
{
|
||||
// TODO: elipse
|
||||
/*double dx = *(c.center.x) - *(e.center.x);
|
||||
double dy = *(c.center.y) - *(e.center.y);
|
||||
double d = sqrt(dx*dx + dy*dy);*/
|
||||
|
||||
/*Constraint *constr = new ConstraintPoint2EllipseDistance(c.center,e,c.rad);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr); */
|
||||
|
||||
|
||||
//return addConstraintTangentCircumf(e.center, c.center, e.radmaj, c.rad,
|
||||
// (d < *e.radmaj || d < *c.rad), tagId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int System::addConstraintTangent(Line &l, Arc &a, int tagId)
|
||||
{
|
||||
return addConstraintP2LDistance(a.center, l, a.rad, tagId);
|
||||
@@ -584,6 +663,19 @@ int System::addConstraintTangent(Circle &c, Arc &a, int tagId)
|
||||
(d < *c.rad || d < *a.rad), tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintTangent(Ellipse &e, Arc &a, int tagId)
|
||||
{
|
||||
// TODO: elipse
|
||||
/*double dx = *(a.center.x) - *(e.center.x);
|
||||
double dy = *(a.center.y) - *(e.center.y);
|
||||
double d = sqrt(dx*dx + dy*dy);Constraint *constr = new ConstraintEllipseTangentLine(l, e);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
return addConstraintTangentCircumf(e.center, a.center, e.radmaj, a.rad,
|
||||
(d < *e.radmaj || d < *a.rad), tagId);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int System::addConstraintTangentLine2Arc(Point &p1, Point &p2, Arc &a, int tagId)
|
||||
{
|
||||
addConstraintP2PCoincident(p2, a.start, tagId);
|
||||
@@ -598,6 +690,18 @@ int System::addConstraintTangentArc2Line(Arc &a, Point &p1, Point &p2, int tagId
|
||||
return addConstraintP2PAngle(p1, p2, a.endAngle, incrAngle, tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintTangentLine2ArcOfEllipse(Point &p1, Point &p2, Line &l, ArcOfEllipse &a, int tagId)
|
||||
{
|
||||
addConstraintP2PCoincident(p2, a.start, tagId);
|
||||
return addConstraintTangent(l, a, tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintTangentArcOfEllipse2Line(ArcOfEllipse &a, Line &l, Point &p1, Point &p2, int tagId)
|
||||
{
|
||||
addConstraintP2PCoincident(p1, a.end, tagId);
|
||||
return addConstraintTangent(l, a, tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintTangentCircle2Arc(Circle &c, Arc &a, int tagId)
|
||||
{
|
||||
addConstraintPointOnCircle(a.start, c, tagId);
|
||||
@@ -609,6 +713,19 @@ int System::addConstraintTangentCircle2Arc(Circle &c, Arc &a, int tagId)
|
||||
return addConstraintP2PAngle(c.center, a.start, a.startAngle, M_PI, tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintTangentEllipse2Arc(Ellipse &e, Arc &a, int tagId)
|
||||
{
|
||||
// TODO: Ellipse
|
||||
/*addConstraintPointOnEllipse(a.start, e, tagId);
|
||||
double dx = *(a.start.x) - *(e.center.x);
|
||||
double dy = *(a.start.y) - *(e.center.y);
|
||||
if (dx * cos(*(a.startAngle)) + dy * sin(*(a.startAngle)) > 0)
|
||||
return addConstraintP2PAngle(e.center, a.start, a.startAngle, 0, tagId);
|
||||
else
|
||||
return addConstraintP2PAngle(e.center, a.start, a.startAngle, M_PI, tagId);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int System::addConstraintTangentArc2Circle(Arc &a, Circle &c, int tagId)
|
||||
{
|
||||
addConstraintPointOnCircle(a.end, c, tagId);
|
||||
@@ -620,6 +737,19 @@ int System::addConstraintTangentArc2Circle(Arc &a, Circle &c, int tagId)
|
||||
return addConstraintP2PAngle(c.center, a.end, a.endAngle, M_PI, tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintTangentArc2Ellipse(Arc &a, Ellipse &e, int tagId)
|
||||
{
|
||||
// TODO: Ellipse
|
||||
/*addConstraintPointOnEllipse(a.end, e, tagId);
|
||||
double dx = *(a.end.x) - *(e.center.x);
|
||||
double dy = *(a.end.y) - *(e.center.y);
|
||||
if (dx * cos(*(a.endAngle)) + dy * sin(*(a.endAngle)) > 0)
|
||||
return addConstraintP2PAngle(e.center, a.end, a.endAngle, 0, tagId);
|
||||
else
|
||||
return addConstraintP2PAngle(e.center, a.end, a.endAngle, M_PI, tagId);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int System::addConstraintTangentArc2Arc(Arc &a1, bool reverse1, Arc &a2, bool reverse2,
|
||||
int tagId)
|
||||
{
|
||||
@@ -656,6 +786,17 @@ int System::addConstraintEqualRadius(Circle &c1, Circle &c2, int tagId)
|
||||
return addConstraintEqual(c1.rad, c2.rad, tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintEqualRadii(Ellipse &e1, Ellipse &e2, int tagId)
|
||||
{
|
||||
// TODO: Ellipse
|
||||
//addConstraintEqual(e1.radmaj, e2.radmaj, tagId);
|
||||
addConstraintEqual(e1.radmin, e2.radmin, tagId);
|
||||
|
||||
Constraint *constr = new ConstraintEqualMajorAxesEllipse(e1,e2);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintEqualRadius(Circle &c1, Arc &a2, int tagId)
|
||||
{
|
||||
return addConstraintEqual(c1.rad, a2.rad, tagId);
|
||||
@@ -678,6 +819,74 @@ int System::addConstraintP2PSymmetric(Point &p1, Point &p2, Point &p, int tagId)
|
||||
return addConstraintPointOnLine(p, p1, p2, tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentPoint2Ellipse(Ellipse &e, Point &p1, InternalAlignmentType alignmentType, int tagId)
|
||||
{
|
||||
Constraint *constr = new ConstraintInternalAlignmentPoint2Ellipse(e, p1, alignmentType);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId)
|
||||
{
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMajorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMajorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMajorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMajorY,tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId)
|
||||
{
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMinorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMinorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMinorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMinorY,tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseFocus1(Ellipse &e, Point &p1, int tagId)
|
||||
{
|
||||
return addConstraintP2PCoincident(e.focus1,p1);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseFocus2(Ellipse &e, Point &p1, int tagId)
|
||||
{
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseFocus2X,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseFocus2Y,tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentPoint2Ellipse(ArcOfEllipse &a, Point &p1, InternalAlignmentType alignmentType, int tagId)
|
||||
{
|
||||
Constraint *constr = new ConstraintInternalAlignmentPoint2Ellipse(a, p1, alignmentType);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseMajorDiameter(ArcOfEllipse &a, Point &p1, Point &p2, int tagId)
|
||||
{
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipsePositiveMajorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipsePositiveMajorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipseNegativeMajorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipseNegativeMajorY,tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseMinorDiameter(ArcOfEllipse &a, Point &p1, Point &p2, int tagId)
|
||||
{
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipsePositiveMinorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipsePositiveMinorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipseNegativeMinorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipseNegativeMinorY,tagId);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseFocus1(ArcOfEllipse &a, Point &p1, int tagId)
|
||||
{
|
||||
return addConstraintP2PCoincident(a.focus1,p1);
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseFocus2(ArcOfEllipse &a, Point &p1, int tagId)
|
||||
{
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipseFocus2X,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipseFocus2Y,tagId);
|
||||
}
|
||||
|
||||
void System::rescaleConstraint(int id, double coeff)
|
||||
{
|
||||
if (id >= clist.size() || id < 0)
|
||||
@@ -1465,12 +1674,27 @@ int System::diagnose()
|
||||
J(count-1,j) = (*constr)->grad(plist[j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef _GCS_DEBUG
|
||||
// Debug code starts
|
||||
std::stringstream stream;
|
||||
|
||||
stream << "[";
|
||||
stream << J ;
|
||||
stream << "]";
|
||||
|
||||
const std::string tmp = stream.str();
|
||||
|
||||
Base::Console().Warning(tmp.c_str());
|
||||
// Debug code ends
|
||||
#endif
|
||||
|
||||
if (J.rows() > 0) {
|
||||
Eigen::FullPivHouseholderQR<Eigen::MatrixXd> qrJT(J.topRows(count).transpose());
|
||||
Eigen::MatrixXd Q = qrJT.matrixQ ();
|
||||
int paramsNum = qrJT.rows();
|
||||
int constrNum = qrJT.cols();
|
||||
//qrJT.setThreshold(0);
|
||||
int rank = qrJT.rank();
|
||||
|
||||
Eigen::MatrixXd R;
|
||||
|
||||
@@ -125,6 +125,10 @@ namespace GCS
|
||||
int addConstraintCoordinateY(Point &p, double *y, int tagId=0);
|
||||
int addConstraintArcRules(Arc &a, int tagId=0);
|
||||
int addConstraintPointOnCircle(Point &p, Circle &c, int tagId=0);
|
||||
int addConstraintPointOnEllipse(Point &p, Ellipse &e, int tagId=0);
|
||||
int addConstraintEllipticalArcRangeToEndPoints(Point &p, ArcOfEllipse &a, double *angle, int tagId=0);
|
||||
int addConstraintArcOfEllipseRules(ArcOfEllipse &a, int tagId=0);
|
||||
int addConstraintPointOnArcOfEllipse(Point &p, ArcOfEllipse &a, int tagId=0);
|
||||
int addConstraintPointOnArc(Point &p, Arc &a, int tagId=0);
|
||||
int addConstraintPerpendicularLine2Arc(Point &p1, Point &p2, Arc &a,
|
||||
int tagId=0);
|
||||
@@ -137,24 +141,47 @@ namespace GCS
|
||||
int addConstraintPerpendicularArc2Arc(Arc &a1, bool reverse1,
|
||||
Arc &a2, bool reverse2, int tagId=0);
|
||||
int addConstraintTangent(Line &l, Circle &c, int tagId=0);
|
||||
int addConstraintTangent(Line &l, Ellipse &e, int tagId=0);
|
||||
int addConstraintTangent(Line &l, ArcOfEllipse &a, int tagId=0);
|
||||
int addConstraintTangent(Ellipse &e, Circle &c, int tagId=0);
|
||||
int addConstraintTangent(Line &l, Arc &a, int tagId=0);
|
||||
int addConstraintTangent(Circle &c1, Circle &c2, int tagId=0);
|
||||
int addConstraintTangent(Arc &a1, Arc &a2, int tagId=0);
|
||||
int addConstraintTangent(Circle &c, Arc &a, int tagId=0);
|
||||
int addConstraintTangent(Ellipse &e, Arc &a, int tagId=0);
|
||||
int addConstraintTangentLine2ArcOfEllipse(Point &p1, Point &p2, Line &l, ArcOfEllipse &a, int tagId=0);
|
||||
int addConstraintTangentArcOfEllipse2Line(ArcOfEllipse &a, Line &l, Point &p1, Point &p2, int tagId=0);
|
||||
int addConstraintTangentLine2Arc(Point &p1, Point &p2, Arc &a, int tagId=0);
|
||||
int addConstraintTangentArc2Line(Arc &a, Point &p1, Point &p2, int tagId=0);
|
||||
int addConstraintTangentCircle2Arc(Circle &c, Arc &a, int tagId=0);
|
||||
int addConstraintTangentEllipse2Arc(Ellipse &e, Arc &a, int tagId=0);
|
||||
int addConstraintTangentArc2Circle(Arc &a, Circle &c, int tagId=0);
|
||||
int addConstraintTangentArc2Ellipse(Arc &a, Ellipse &e, int tagId=0);
|
||||
int addConstraintTangentArc2Arc(Arc &a1, bool reverse1, Arc &a2, bool reverse2,
|
||||
int tagId=0);
|
||||
int addConstraintCircleRadius(Circle &c, double *radius, int tagId=0);
|
||||
int addConstraintEllipseAngleXU(Ellipse &e, double *angle, int tagId=0);
|
||||
int addConstraintArcRadius(Arc &a, double *radius, int tagId=0);
|
||||
int addConstraintEqualLength(Line &l1, Line &l2, double *length, int tagId=0);
|
||||
int addConstraintEqualRadius(Circle &c1, Circle &c2, int tagId=0);
|
||||
int addConstraintEqualRadii(Ellipse &e1, Ellipse &e2, int tagId=0);
|
||||
int addConstraintEqualRadius(Circle &c1, Arc &a2, int tagId=0);
|
||||
int addConstraintEqualRadius(Arc &a1, Arc &a2, int tagId=0);
|
||||
int addConstraintP2PSymmetric(Point &p1, Point &p2, Line &l, int tagId=0);
|
||||
int addConstraintP2PSymmetric(Point &p1, Point &p2, Point &p, int tagId=0);
|
||||
|
||||
// internal alignment constraints
|
||||
int addConstraintInternalAlignmentPoint2Ellipse(Ellipse &e, Point &p1, InternalAlignmentType alignmentType, int tagId=0);
|
||||
int addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId=0);
|
||||
int addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId=0);
|
||||
int addConstraintInternalAlignmentEllipseFocus1(Ellipse &e, Point &p1, int tagId=0);
|
||||
int addConstraintInternalAlignmentEllipseFocus2(Ellipse &e, Point &p1, int tagId=0);
|
||||
int addConstraintInternalAlignmentPoint2Ellipse(ArcOfEllipse &a, Point &p1, InternalAlignmentType alignmentType, int tagId=0);
|
||||
int addConstraintInternalAlignmentEllipseMajorDiameter(ArcOfEllipse &a, Point &p1, Point &p2, int tagId=0);
|
||||
int addConstraintInternalAlignmentEllipseMinorDiameter(ArcOfEllipse &a, Point &p1, Point &p2, int tagId=0);
|
||||
int addConstraintInternalAlignmentEllipseFocus1(ArcOfEllipse &a, Point &p1, int tagId=0);
|
||||
int addConstraintInternalAlignmentEllipseFocus2(ArcOfEllipse &a, Point &p1, int tagId=0);
|
||||
|
||||
void rescaleConstraint(int id, double coeff);
|
||||
|
||||
void declareUnknowns(VEC_pD ¶ms);
|
||||
|
||||
@@ -65,6 +65,28 @@ namespace GCS
|
||||
Point center;
|
||||
double *rad;
|
||||
};
|
||||
|
||||
class Ellipse
|
||||
{
|
||||
public:
|
||||
Ellipse(){ radmin = 0;}
|
||||
Point center;
|
||||
Point focus1; //+x
|
||||
double *radmin;
|
||||
};
|
||||
|
||||
class ArcOfEllipse
|
||||
{
|
||||
public:
|
||||
ArcOfEllipse(){startAngle=0;endAngle=0;radmin = 0;}
|
||||
double *startAngle;
|
||||
double *endAngle;
|
||||
double *radmin;
|
||||
Point start;
|
||||
Point end;
|
||||
Point center;
|
||||
Point focus1; //+x
|
||||
};
|
||||
|
||||
} //namespace GCS
|
||||
|
||||
|
||||
@@ -147,8 +147,8 @@ bool isSimpleVertex(const Sketcher::SketchObject* Obj, int GeoId, PointPos PosId
|
||||
if (geo->getTypeId() == Part::GeomPoint::getClassTypeId())
|
||||
return true;
|
||||
else if (PosId == Sketcher::mid &&
|
||||
(geo->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()))
|
||||
(geo->getTypeId() == Part::GeomCircle::getClassTypeId() || // TODO: ellipse
|
||||
geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@@ -802,8 +802,10 @@ void CmdSketcherConstrainPointOnObject::activated(int iMsg)
|
||||
|
||||
// Currently only accepts line segments and circles
|
||||
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ) {
|
||||
geom->getTypeId() == Part::GeomCircle::getClassTypeId() || // TODO: ellipse
|
||||
geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ) {
|
||||
|
||||
openCommand("add point on object constraint");
|
||||
Gui::Command::doCommand(
|
||||
@@ -1287,7 +1289,7 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg)
|
||||
}
|
||||
else if (geo2->getTypeId() != Part::GeomLineSegment::getClassTypeId() &&
|
||||
geo2->getTypeId() != Part::GeomArcOfCircle::getClassTypeId() &&
|
||||
geo2->getTypeId() != Part::GeomCircle::getClassTypeId()) {
|
||||
geo2->getTypeId() != Part::GeomCircle::getClassTypeId()) { // TODO: ellipse
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("The selected edge should be an arc, line or circle."));
|
||||
return;
|
||||
@@ -1490,7 +1492,7 @@ void CmdSketcherConstrainRadius::activated(int iMsg)
|
||||
double radius = arc->getRadius();
|
||||
geoIdRadiusMap.push_back(std::make_pair(GeoId, radius));
|
||||
}
|
||||
else if (geom && geom->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
else if (geom && geom->getTypeId() == Part::GeomCircle::getClassTypeId()) { // TODO: ellipse
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geom);
|
||||
double radius = circle->getRadius();
|
||||
geoIdRadiusMap.push_back(std::make_pair(GeoId, radius));
|
||||
@@ -1615,7 +1617,6 @@ bool CmdSketcherConstrainRadius::isActive(void)
|
||||
return isCreateConstraintActive( getActiveGuiDocument() );
|
||||
}
|
||||
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherConstrainAngle);
|
||||
|
||||
CmdSketcherConstrainAngle::CmdSketcherConstrainAngle()
|
||||
@@ -1764,7 +1765,6 @@ bool CmdSketcherConstrainAngle::isActive(void)
|
||||
return isCreateConstraintActive( getActiveGuiDocument() );
|
||||
}
|
||||
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherConstrainEqual);
|
||||
|
||||
CmdSketcherConstrainEqual::CmdSketcherConstrainEqual()
|
||||
@@ -1838,7 +1838,7 @@ void CmdSketcherConstrainEqual::activated(int iMsg)
|
||||
lineSel = true;
|
||||
else if (geo->getTypeId() != Part::GeomArcOfCircle::getClassTypeId())
|
||||
arcSel = true;
|
||||
else if (geo->getTypeId() != Part::GeomCircle::getClassTypeId())
|
||||
else if (geo->getTypeId() != Part::GeomCircle::getClassTypeId()) // TODO: ellipse
|
||||
circSel = true;
|
||||
else {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
@@ -2027,7 +2027,412 @@ bool CmdSketcherConstrainSymmetric::isActive(void)
|
||||
return isCreateConstraintActive( getActiveGuiDocument() );
|
||||
}
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherConstrainInternalAlignment);
|
||||
|
||||
CmdSketcherConstrainInternalAlignment::CmdSketcherConstrainInternalAlignment()
|
||||
:Command("Sketcher_ConstrainInternalAlignment")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = QT_TR_NOOP("Sketcher");
|
||||
sMenuText = QT_TR_NOOP("Constrain InternalAlignment");
|
||||
sToolTipText = QT_TR_NOOP("Constraint an element to be aligned with the internal geometry of another element");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Constraint_InternalAlignment";
|
||||
sAccel = "Ctrl+A";
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
void CmdSketcherConstrainInternalAlignment::activated(int iMsg)
|
||||
{
|
||||
// get the selection
|
||||
std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
|
||||
|
||||
// only one sketch with its subelements are allowed to be selected
|
||||
if (selection.size() != 1) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select at least one ellipse and one edge from the sketch."));
|
||||
return;
|
||||
}
|
||||
|
||||
// get the needed lists and objects
|
||||
const std::vector<std::string> &SubNames = selection[0].getSubNames();
|
||||
Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
|
||||
|
||||
// go through the selected subelements
|
||||
if (SubNames.size() < 2) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select at least one ellipse and one edge from the sketch."));
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<int> pointids;
|
||||
std::vector<int> lineids;
|
||||
std::vector<int> ellipseids;
|
||||
std::vector<int> arcsofellipseids;
|
||||
|
||||
bool hasAlreadyExternal = false;
|
||||
|
||||
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
|
||||
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
getIdsFromName(*it, Obj, GeoId, PosId);
|
||||
|
||||
if (GeoId < 0) {
|
||||
if (GeoId == -1 || GeoId == -2) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Sketch axes cannot be used in internal alignment constraint"));
|
||||
return;
|
||||
}
|
||||
else if (hasAlreadyExternal) {
|
||||
checkBothExternal(-1,-2); // just for printing the error message
|
||||
return;
|
||||
}
|
||||
else
|
||||
hasAlreadyExternal = true;
|
||||
}
|
||||
|
||||
const Part::Geometry *geo = Obj->getGeometry(GeoId);
|
||||
|
||||
if (geo->getTypeId() == Part::GeomPoint::getClassTypeId())
|
||||
pointids.push_back(GeoId);
|
||||
else if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId())
|
||||
lineids.push_back(GeoId);
|
||||
else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId())
|
||||
ellipseids.push_back(GeoId);
|
||||
else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId())
|
||||
arcsofellipseids.push_back(GeoId);
|
||||
else {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select two or more compatible edges"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
getIdsFromName(SubNames[SubNames.size()-1], Obj, GeoId, PosId); // last selected element
|
||||
|
||||
const Part::Geometry *geo = Obj->getGeometry(GeoId);
|
||||
|
||||
// Currently it is only supported for ellipses
|
||||
if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
|
||||
// Priority list
|
||||
// EllipseMajorDiameter = 1,
|
||||
// EllipseMinorDiameter = 2,
|
||||
// EllipseFocus1 = 3,
|
||||
// EllipseFocus2 = 4
|
||||
|
||||
if(ellipseids.size()>1){
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("You can not internally constraint an ellipse on other ellipse. Select only one ellipse."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pointids.size()>2) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Maximum 2 points are supported."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (lineids.size()>2) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Maximum 2 lines are supported."));
|
||||
return;
|
||||
}
|
||||
|
||||
// look for which internal constraints are already applied
|
||||
bool major=false;
|
||||
bool minor=false;
|
||||
bool focus1=false;
|
||||
bool focus2=false;
|
||||
bool extra_elements=false;
|
||||
|
||||
const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
|
||||
|
||||
for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin();
|
||||
it != vals.end(); ++it) {
|
||||
if((*it)->Type == Sketcher::InternalAlignment && (*it)->First == GeoId)
|
||||
{
|
||||
switch((*it)->AlignmentType){
|
||||
case Sketcher::EllipseMajorDiameter:
|
||||
major=true;
|
||||
break;
|
||||
case Sketcher::EllipseMinorDiameter:
|
||||
minor=true;
|
||||
break;
|
||||
case Sketcher::EllipseFocus1:
|
||||
focus1=true;
|
||||
break;
|
||||
case Sketcher::EllipseFocus2:
|
||||
focus2=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(major && minor && focus1 && focus2) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Nothing to constraint"),
|
||||
QObject::tr("Currently all internal geometry of the ellipse is already exposed."));
|
||||
return;
|
||||
}
|
||||
|
||||
if((!(focus1 && focus2) && pointids.size()>=1) || // if some element is missing and we are adding an element of that type
|
||||
(!(major && minor) && lineids.size()>=1) ){
|
||||
|
||||
openCommand("add internal alignment constraint");
|
||||
|
||||
if(pointids.size()>=1)
|
||||
{
|
||||
if(!focus1) {
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseFocus1',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),pointids[0],Sketcher::start,ellipseids[0]);
|
||||
}
|
||||
else if(!focus2) {
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseFocus2',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),pointids[0],Sketcher::start,ellipseids[0]);
|
||||
focus2=true;
|
||||
}
|
||||
else
|
||||
extra_elements=true;
|
||||
}
|
||||
|
||||
if(pointids.size()==2)
|
||||
{
|
||||
if(!focus2) {
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseFocus2',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),pointids[1],Sketcher::start,ellipseids[0]);
|
||||
}
|
||||
else
|
||||
extra_elements=true;
|
||||
}
|
||||
|
||||
if(lineids.size()>=1)
|
||||
{
|
||||
if(!major) {
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseMajorDiameter',%d,%d)) ",
|
||||
selection[0].getFeatName(),lineids[0],ellipseids[0]);
|
||||
|
||||
const Part::GeomLineSegment *geo = static_cast<const Part::GeomLineSegment *>(Obj->getGeometry(lineids[0]));
|
||||
|
||||
if(!geo->Construction)
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",selection[0].getFeatName(),lineids[0]);
|
||||
|
||||
}
|
||||
else if(!minor) {
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseMinorDiameter',%d,%d)) ",
|
||||
selection[0].getFeatName(),lineids[0],ellipseids[0]);
|
||||
|
||||
const Part::GeomLineSegment *geo = static_cast<const Part::GeomLineSegment *>(Obj->getGeometry(lineids[0]));
|
||||
|
||||
if(!geo->Construction)
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",selection[0].getFeatName(),lineids[0]);
|
||||
|
||||
minor=true;
|
||||
}
|
||||
else
|
||||
extra_elements=true;
|
||||
}
|
||||
if(lineids.size()==2)
|
||||
{
|
||||
if(!minor){
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseMinorDiameter',%d,%d)) ",
|
||||
selection[0].getFeatName(),lineids[1],ellipseids[0]);
|
||||
|
||||
const Part::GeomLineSegment *geo = static_cast<const Part::GeomLineSegment *>(Obj->getGeometry(lineids[1]));
|
||||
|
||||
if(!geo->Construction)
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",selection[0].getFeatName(),lineids[1]);
|
||||
}
|
||||
else
|
||||
extra_elements=true;
|
||||
}
|
||||
|
||||
// finish the transaction and update
|
||||
commitCommand();
|
||||
updateActive();
|
||||
|
||||
if(extra_elements){
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Extra elements"),
|
||||
QObject::tr("More elements than possible for the given ellipse were provided. These were ignored."));
|
||||
}
|
||||
|
||||
// clear the selection (convenience)
|
||||
getSelection().clearSelection();
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Extra elements"),
|
||||
QObject::tr("More elements than possible for the given ellipse were provided. These were ignored."));
|
||||
}
|
||||
}
|
||||
else if(geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
|
||||
// Priority list
|
||||
// EllipseMajorDiameter = 1,
|
||||
// EllipseMinorDiameter = 2,
|
||||
// EllipseFocus1 = 3,
|
||||
// EllipseFocus2 = 4
|
||||
|
||||
if(arcsofellipseids.size()>1){
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("You can not internally constraint an arc of ellipse on other arc of ellipse. Select only one arc of ellipse."));
|
||||
return;
|
||||
}
|
||||
|
||||
if(ellipseids.size()>0){
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("You can not internally constraint an ellipse on an arc of ellipse. Select only one ellipse or arc of ellipse."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pointids.size()>2) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Maximum 2 points are supported."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (lineids.size()>2) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Maximum 2 lines are supported."));
|
||||
return;
|
||||
}
|
||||
|
||||
// look for which internal constraints are already applied
|
||||
bool major=false;
|
||||
bool minor=false;
|
||||
bool focus1=false;
|
||||
bool focus2=false;
|
||||
bool extra_elements=false;
|
||||
|
||||
const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
|
||||
|
||||
for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin();
|
||||
it != vals.end(); ++it) {
|
||||
if((*it)->Type == Sketcher::InternalAlignment && (*it)->First == GeoId)
|
||||
{
|
||||
switch((*it)->AlignmentType){
|
||||
case Sketcher::EllipseMajorDiameter:
|
||||
major=true;
|
||||
break;
|
||||
case Sketcher::EllipseMinorDiameter:
|
||||
minor=true;
|
||||
break;
|
||||
case Sketcher::EllipseFocus1:
|
||||
focus1=true;
|
||||
break;
|
||||
case Sketcher::EllipseFocus2:
|
||||
focus2=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(major && minor && focus1 && focus2) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Nothing to constraint"),
|
||||
QObject::tr("Currently all internal geometry of the arc of ellipse is already exposed."));
|
||||
return;
|
||||
}
|
||||
|
||||
if((!(focus1 && focus2) && pointids.size()>=1) || // if some element is missing and we are adding an element of that type
|
||||
(!(major && minor) && lineids.size()>=1) ){
|
||||
|
||||
openCommand("add internal alignment constraint");
|
||||
|
||||
if(pointids.size()>=1)
|
||||
{
|
||||
if(!focus1) {
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseFocus1',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),pointids[0],Sketcher::start,arcsofellipseids[0]);
|
||||
}
|
||||
else if(!focus2) {
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseFocus2',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),pointids[0],Sketcher::start,arcsofellipseids[0]);
|
||||
focus2=true;
|
||||
}
|
||||
else
|
||||
extra_elements=true;
|
||||
}
|
||||
|
||||
if(pointids.size()==2)
|
||||
{
|
||||
if(!focus2) {
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseFocus2',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),pointids[1],Sketcher::start,arcsofellipseids[0]);
|
||||
}
|
||||
else
|
||||
extra_elements=true;
|
||||
}
|
||||
|
||||
if(lineids.size()>=1)
|
||||
{
|
||||
if(!major) {
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseMajorDiameter',%d,%d)) ",
|
||||
selection[0].getFeatName(),lineids[0],arcsofellipseids[0]);
|
||||
|
||||
const Part::GeomLineSegment *geo = static_cast<const Part::GeomLineSegment *>(Obj->getGeometry(lineids[0]));
|
||||
|
||||
if(!geo->Construction)
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",selection[0].getFeatName(),lineids[0]);
|
||||
|
||||
}
|
||||
else if(!minor) {
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseMinorDiameter',%d,%d)) ",
|
||||
selection[0].getFeatName(),lineids[0],arcsofellipseids[0]);
|
||||
|
||||
const Part::GeomLineSegment *geo = static_cast<const Part::GeomLineSegment *>(Obj->getGeometry(lineids[0]));
|
||||
|
||||
if(!geo->Construction)
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",selection[0].getFeatName(),lineids[0]);
|
||||
|
||||
minor=true;
|
||||
}
|
||||
else
|
||||
extra_elements=true;
|
||||
}
|
||||
if(lineids.size()==2)
|
||||
{
|
||||
if(!minor){
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseMinorDiameter',%d,%d)) ",
|
||||
selection[0].getFeatName(),lineids[1],arcsofellipseids[0]);
|
||||
|
||||
const Part::GeomLineSegment *geo = static_cast<const Part::GeomLineSegment *>(Obj->getGeometry(lineids[1]));
|
||||
|
||||
if(!geo->Construction)
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",selection[0].getFeatName(),lineids[1]);
|
||||
}
|
||||
else
|
||||
extra_elements=true;
|
||||
}
|
||||
|
||||
// finish the transaction and update
|
||||
commitCommand();
|
||||
updateActive();
|
||||
|
||||
if(extra_elements){
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Extra elements"),
|
||||
QObject::tr("More elements than possible for the given ellipse were provided. These were ignored."));
|
||||
}
|
||||
|
||||
// clear the selection (convenience)
|
||||
getSelection().clearSelection();
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Extra elements"),
|
||||
QObject::tr("More elements than possible for the given arc of ellipse were provided. These were ignored."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Currently internal geometry is only supported for ellipse or arc of ellipse. The last selected element must be an ellipse or an arc of ellipse."));
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSketcherConstrainInternalAlignment::isActive(void)
|
||||
{
|
||||
return isCreateConstraintActive( getActiveGuiDocument() );
|
||||
}
|
||||
|
||||
void CreateSketcherCommandsConstraints(void)
|
||||
{
|
||||
@@ -2048,4 +2453,5 @@ void CreateSketcherCommandsConstraints(void)
|
||||
rcCmdMgr.addCommand(new CmdSketcherConstrainEqual());
|
||||
rcCmdMgr.addCommand(new CmdSketcherConstrainPointOnObject());
|
||||
rcCmdMgr.addCommand(new CmdSketcherConstrainSymmetric());
|
||||
rcCmdMgr.addCommand(new CmdSketcherConstrainInternalAlignment());
|
||||
}
|
||||
|
||||
@@ -1793,7 +1793,580 @@ bool CmdSketcherCreateCircle::isActive(void)
|
||||
{
|
||||
return isCreateGeoActive(getActiveGuiDocument());
|
||||
}
|
||||
// ======================================================================================
|
||||
|
||||
/* XPM */
|
||||
static const char *cursor_createellipse[]={
|
||||
"32 32 3 1",
|
||||
"+ c white",
|
||||
"# c red",
|
||||
". c None",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"................................",
|
||||
"+++++...+++++...................",
|
||||
"................................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+..............#####......",
|
||||
"..................###.....#.....",
|
||||
"...............###.......##.....",
|
||||
".............##..........##.....",
|
||||
"...........##............##.....",
|
||||
"..........##.....###....##......",
|
||||
".........##.....#.#.....#.......",
|
||||
"........##.....###....##........",
|
||||
"........##...........##.........",
|
||||
".......##..........###..........",
|
||||
"......##........####............",
|
||||
"......#.....####................",
|
||||
"......######....................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................"};
|
||||
|
||||
class DrawSketchHandlerEllipse : public DrawSketchHandler
|
||||
{
|
||||
public:
|
||||
DrawSketchHandlerEllipse() : Mode(STATUS_SEEK_First),EditCurve(34){}
|
||||
virtual ~DrawSketchHandlerEllipse(){}
|
||||
/// mode table
|
||||
enum SelectMode {
|
||||
STATUS_SEEK_First, /**< enum value ----. */
|
||||
STATUS_SEEK_Second, /**< enum value ----. */
|
||||
STATUS_SEEK_Third, /**< enum value ----. */
|
||||
STATUS_Close
|
||||
};
|
||||
|
||||
virtual void activated(ViewProviderSketch *sketchgui)
|
||||
{
|
||||
setCursor(QPixmap(cursor_createellipse),7,7);
|
||||
}
|
||||
|
||||
virtual void mouseMove(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_SEEK_First) {
|
||||
setPositionText(onSketchPos);
|
||||
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.f,0.f))) { // TODO: ellipse prio 1
|
||||
renderSuggestConstraintsCursor(sugConstr1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Mode==STATUS_SEEK_Second) {
|
||||
double rx0 = onSketchPos.fX - EditCurve[0].fX;
|
||||
double ry0 = onSketchPos.fY - EditCurve[0].fY;
|
||||
for (int i=0; i < 16; i++) {
|
||||
double angle = i*M_PI/16.0;
|
||||
double rx = rx0 * cos(angle) + ry0 * sin(angle);
|
||||
double ry = -rx0 * sin(angle) + ry0 * cos(angle);
|
||||
EditCurve[1+i] = Base::Vector2D(EditCurve[0].fX + rx, EditCurve[0].fY + ry);
|
||||
EditCurve[17+i] = Base::Vector2D(EditCurve[0].fX - rx, EditCurve[0].fY - ry);
|
||||
}
|
||||
EditCurve[33] = EditCurve[1];
|
||||
|
||||
// Display radius for user
|
||||
float radius = (onSketchPos - EditCurve[0]).Length();
|
||||
|
||||
SbString text;
|
||||
text.sprintf(" (%.1fR,%.1fR)", radius,radius);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2D(0.f,0.f),
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Mode==STATUS_SEEK_Third) {
|
||||
double rx0 = EditCurve[1].fX - EditCurve[0].fX; // first semidiameter
|
||||
double ry0 = EditCurve[1].fY - EditCurve[0].fY; // first semidiameter
|
||||
|
||||
// angle between the major axis of the ellipse and the X axis
|
||||
double a = (EditCurve[1]-EditCurve[0]).Length();
|
||||
double phi = atan2f(EditCurve[1].fY-EditCurve[0].fY,EditCurve[1].fX-EditCurve[0].fX);
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatpoint = acos((onSketchPos.fX-EditCurve[0].fX+(onSketchPos.fY-EditCurve[0].fY)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
|
||||
double b=(onSketchPos.fY-EditCurve[0].fY-a*cos(angleatpoint)*sin(phi))/(sin(angleatpoint)*cos(phi));
|
||||
|
||||
for (int i=1; i < 16; i++) {
|
||||
double angle = i*M_PI/16.0;
|
||||
double rx = a * cos(angle) * cos(phi) - b * sin(angle) * sin(phi);
|
||||
double ry = a * cos(angle) * sin(phi) + b * sin(angle) * cos(phi);
|
||||
EditCurve[1+i] = Base::Vector2D(EditCurve[0].fX + rx, EditCurve[0].fY + ry);
|
||||
EditCurve[17+i] = Base::Vector2D(EditCurve[0].fX - rx, EditCurve[0].fY - ry);
|
||||
}
|
||||
EditCurve[33] = EditCurve[1];
|
||||
EditCurve[17] = EditCurve[16];
|
||||
|
||||
// Display radius for user
|
||||
SbString text;
|
||||
text.sprintf(" (%.1fR,%.1fR)", a, b);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2D(0.f,0.f),
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
applyCursor();
|
||||
}
|
||||
|
||||
virtual bool pressButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_SEEK_First){
|
||||
EditCurve[0] = onSketchPos;
|
||||
Mode = STATUS_SEEK_Second;
|
||||
}
|
||||
else if(Mode==STATUS_SEEK_Second) {
|
||||
EditCurve[1] = onSketchPos;
|
||||
Mode = STATUS_SEEK_Third;
|
||||
}
|
||||
else {
|
||||
EditCurve[2] = onSketchPos;
|
||||
Mode = STATUS_Close;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool releaseButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_Close) {
|
||||
unsetCursor();
|
||||
resetPositionText();
|
||||
|
||||
// angle between the major axis of the ellipse and the X axis
|
||||
double a = (EditCurve[1]-EditCurve[0]).Length();
|
||||
double phi = atan2f(EditCurve[1].fY-EditCurve[0].fY,EditCurve[1].fX-EditCurve[0].fX);
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatpoint = acos((EditCurve[2].fX-EditCurve[0].fX+(EditCurve[2].fY-EditCurve[0].fY)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
|
||||
double b=(EditCurve[2].fY-EditCurve[0].fY-a*cos(angleatpoint)*sin(phi))/(sin(angleatpoint)*cos(phi));
|
||||
|
||||
Base::Vector2D majAxisDir,minAxisDir,minAxisPoint,majAxisPoint;
|
||||
// We always create a CCW ellipse, because we want our XY reference system to be in the +X +Y direction
|
||||
// Our normal will then always be in the +Z axis (local +Z axis of the sketcher)
|
||||
|
||||
if(a>b)
|
||||
{
|
||||
// force second semidiameter to be perpendicular to first semidiamater
|
||||
majAxisDir = EditCurve[1] - EditCurve[0];
|
||||
Base::Vector2D perp(-majAxisDir.fY,majAxisDir.fX);
|
||||
perp.Normalize();
|
||||
perp.Scale(abs(b));
|
||||
minAxisPoint = EditCurve[0]+perp;
|
||||
majAxisPoint = EditCurve[0]+majAxisDir;
|
||||
}
|
||||
else {
|
||||
// force second semidiameter to be perpendicular to first semidiamater
|
||||
minAxisDir = EditCurve[1] - EditCurve[0];
|
||||
Base::Vector2D perp(minAxisDir.fY,-minAxisDir.fX);
|
||||
perp.Normalize();
|
||||
perp.Scale(abs(b));
|
||||
majAxisPoint = EditCurve[0]+perp;
|
||||
minAxisPoint = EditCurve[0]+minAxisDir;
|
||||
}
|
||||
|
||||
Gui::Command::openCommand("Add sketch ellipse");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.addGeometry(Part.Ellipse"
|
||||
"(App.Vector(%f,%f,0),App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
majAxisPoint.fX, majAxisPoint.fY,
|
||||
minAxisPoint.fX, minAxisPoint.fY,
|
||||
EditCurve[0].fX, EditCurve[0].fY);
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::updateActive();
|
||||
|
||||
// add auto constraints for the center point
|
||||
if (sugConstr1.size() > 0) {
|
||||
createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::mid);
|
||||
sugConstr1.clear();
|
||||
}
|
||||
|
||||
// add suggested constraints for circumference
|
||||
if (sugConstr2.size() > 0) {
|
||||
//createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::none);
|
||||
sugConstr2.clear();
|
||||
}
|
||||
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
|
||||
}
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
SelectMode Mode;
|
||||
std::vector<Base::Vector2D> EditCurve;
|
||||
std::vector<AutoConstraint> sugConstr1, sugConstr2;
|
||||
|
||||
};
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherCreateEllipse);
|
||||
|
||||
CmdSketcherCreateEllipse::CmdSketcherCreateEllipse()
|
||||
: Command("Sketcher_CreateEllipse")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = QT_TR_NOOP("Sketcher");
|
||||
sMenuText = QT_TR_NOOP("Create ellipse");
|
||||
sToolTipText = QT_TR_NOOP("Create an ellipse in the sketch");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Sketcher_CreateEllipse";
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
void CmdSketcherCreateEllipse::activated(int iMsg)
|
||||
{
|
||||
ActivateHandler(getActiveGuiDocument(),new DrawSketchHandlerEllipse() );
|
||||
}
|
||||
|
||||
bool CmdSketcherCreateEllipse::isActive(void)
|
||||
{
|
||||
return isCreateGeoActive(getActiveGuiDocument());
|
||||
}
|
||||
|
||||
// ======================================================================================
|
||||
|
||||
/* XPM */
|
||||
static const char *cursor_createarcofellipse[]={
|
||||
"32 32 3 1",
|
||||
"+ c white",
|
||||
"# c red",
|
||||
". c None",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"................................",
|
||||
"+++++...+++++...................",
|
||||
"................................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+................##.......",
|
||||
"......+..............##.........",
|
||||
"......+............##...........",
|
||||
"......+...........##............",
|
||||
"................##..............",
|
||||
"...............##...............",
|
||||
"..............##................",
|
||||
".............###................",
|
||||
"............##.........###......",
|
||||
"...........##.........#.#.......",
|
||||
"...........##.........###.......",
|
||||
"..........##....................",
|
||||
".........##.....................",
|
||||
"........##......................",
|
||||
"........##......................",
|
||||
"........##......................",
|
||||
"........#.....####..............",
|
||||
"........######..................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................"};
|
||||
|
||||
class DrawSketchHandlerArcOfEllipse : public DrawSketchHandler
|
||||
{
|
||||
public:
|
||||
DrawSketchHandlerArcOfEllipse() : Mode(STATUS_SEEK_First),EditCurve(34){}
|
||||
virtual ~DrawSketchHandlerArcOfEllipse(){}
|
||||
/// mode table
|
||||
enum SelectMode {
|
||||
STATUS_SEEK_First, /**< enum value ----. */
|
||||
STATUS_SEEK_Second, /**< enum value ----. */
|
||||
STATUS_SEEK_Third, /**< enum value ----. */
|
||||
STATUS_SEEK_Fourth, /**< enum value ----. */
|
||||
STATUS_Close
|
||||
};
|
||||
|
||||
virtual void activated(ViewProviderSketch *sketchgui)
|
||||
{
|
||||
setCursor(QPixmap(cursor_createarcofellipse),7,7);
|
||||
}
|
||||
|
||||
virtual void mouseMove(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_SEEK_First) {
|
||||
setPositionText(onSketchPos);
|
||||
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.f,0.f))) { // TODO: ellipse prio 1
|
||||
renderSuggestConstraintsCursor(sugConstr1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Mode==STATUS_SEEK_Second) {
|
||||
double rx0 = onSketchPos.fX - EditCurve[0].fX;
|
||||
double ry0 = onSketchPos.fY - EditCurve[0].fY;
|
||||
for (int i=0; i < 16; i++) {
|
||||
double angle = i*M_PI/16.0;
|
||||
double rx = rx0 * cos(angle) + ry0 * sin(angle);
|
||||
double ry = -rx0 * sin(angle) + ry0 * cos(angle);
|
||||
EditCurve[1+i] = Base::Vector2D(EditCurve[0].fX + rx, EditCurve[0].fY + ry);
|
||||
EditCurve[17+i] = Base::Vector2D(EditCurve[0].fX - rx, EditCurve[0].fY - ry);
|
||||
}
|
||||
EditCurve[33] = EditCurve[1];
|
||||
|
||||
// Display radius for user
|
||||
float radius = (onSketchPos - EditCurve[0]).Length();
|
||||
|
||||
SbString text;
|
||||
text.sprintf(" (%.1fR,%.1fR)", radius,radius);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2D(0.f,0.f),
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Mode==STATUS_SEEK_Third) {
|
||||
double rx0 = EditCurve[1].fX - EditCurve[0].fX; // first semidiameter
|
||||
double ry0 = EditCurve[1].fY - EditCurve[0].fY; // first semidiameter
|
||||
|
||||
// angle between the major axis of the ellipse and the X axis
|
||||
double a = (EditCurve[1]-EditCurve[0]).Length();
|
||||
double phi = atan2f(EditCurve[1].fY-EditCurve[0].fY,EditCurve[1].fX-EditCurve[0].fX);
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatpoint = acos((onSketchPos.fX-EditCurve[0].fX+(onSketchPos.fY-EditCurve[0].fY)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
|
||||
double b=(onSketchPos.fY-EditCurve[0].fY-a*cos(angleatpoint)*sin(phi))/(sin(angleatpoint)*cos(phi));
|
||||
|
||||
for (int i=1; i < 16; i++) {
|
||||
double angle = i*M_PI/16.0;
|
||||
double rx = a * cos(angle) * cos(phi) - b * sin(angle) * sin(phi);
|
||||
double ry = a * cos(angle) * sin(phi) + b * sin(angle) * cos(phi);
|
||||
EditCurve[1+i] = Base::Vector2D(EditCurve[0].fX + rx, EditCurve[0].fY + ry);
|
||||
EditCurve[17+i] = Base::Vector2D(EditCurve[0].fX - rx, EditCurve[0].fY - ry);
|
||||
}
|
||||
EditCurve[33] = EditCurve[1];
|
||||
EditCurve[17] = EditCurve[16];
|
||||
|
||||
// Display radius for user
|
||||
SbString text;
|
||||
text.sprintf(" (%.1fR,%.1fR)", a, b);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2D(0.f,0.f),
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Mode==STATUS_SEEK_Fourth) { // here we differ from ellipse creation
|
||||
|
||||
double rx0 = axisPoint.fX - centerPoint.fX; // first semidiameter
|
||||
double ry0 = axisPoint.fY - centerPoint.fY; // first semidiameter
|
||||
|
||||
// angle between the major axis of the ellipse and the X axis
|
||||
double a = (axisPoint-centerPoint).Length();
|
||||
double phi = atan2(axisPoint.fY-centerPoint.fY,axisPoint.fX-centerPoint.fX);
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatpoint = acos((startingPoint.fX-centerPoint.fX+(startingPoint.fY-centerPoint.fY)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
|
||||
double b=abs((startingPoint.fY-centerPoint.fY-a*cos(angleatpoint)*sin(phi))/(sin(angleatpoint)*cos(phi)));
|
||||
|
||||
double rxs = startingPoint.fX - centerPoint.fX;
|
||||
double rys = startingPoint.fY - centerPoint.fY;
|
||||
startAngle = atan2(a*(rys*cos(phi)-rxs*sin(phi)), b*(rxs*cos(phi)+rys*sin(phi))); // eccentric anomaly angle
|
||||
|
||||
double angle1 = atan2(a*((onSketchPos.fY - centerPoint.fY)*cos(phi)-(onSketchPos.fX - centerPoint.fX)*sin(phi)),
|
||||
b*((onSketchPos.fX - centerPoint.fX)*cos(phi)+(onSketchPos.fY - centerPoint.fY)*sin(phi)))- startAngle;
|
||||
|
||||
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI ;
|
||||
arcAngle = abs(angle1-arcAngle) < abs(angle2-arcAngle) ? angle1 : angle2;
|
||||
|
||||
for (int i=0; i < 34; i++) {
|
||||
double angle = startAngle+i*arcAngle/34.0;
|
||||
double rx = a * cos(angle) * cos(phi) - b * sin(angle) * sin(phi);
|
||||
double ry = a * cos(angle) * sin(phi) + b * sin(angle) * cos(phi);
|
||||
EditCurve[i] = Base::Vector2D(centerPoint.fX + rx, centerPoint.fY + ry);
|
||||
}
|
||||
// EditCurve[33] = EditCurve[1];
|
||||
// EditCurve[17] = EditCurve[16];
|
||||
|
||||
// Display radii and angle for user
|
||||
SbString text;
|
||||
text.sprintf(" (%.1fR,%.1fR,%.1fdeg)", a, b, arcAngle * 180 / M_PI);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr4, onSketchPos, Base::Vector2D(0.f,0.f),
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
applyCursor();
|
||||
}
|
||||
|
||||
virtual bool pressButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_SEEK_First){
|
||||
EditCurve[0] = onSketchPos;
|
||||
centerPoint = onSketchPos;
|
||||
Mode = STATUS_SEEK_Second;
|
||||
}
|
||||
else if(Mode==STATUS_SEEK_Second) {
|
||||
EditCurve[1] = onSketchPos;
|
||||
axisPoint = onSketchPos;
|
||||
Mode = STATUS_SEEK_Third;
|
||||
}
|
||||
else if(Mode==STATUS_SEEK_Third) {
|
||||
startingPoint = onSketchPos;
|
||||
arcAngle = 0.;
|
||||
arcAngle_t= 0.;
|
||||
Mode = STATUS_SEEK_Fourth;
|
||||
}
|
||||
else { // Fourth
|
||||
endPoint = onSketchPos;
|
||||
|
||||
Mode = STATUS_Close;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool releaseButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_Close) {
|
||||
unsetCursor();
|
||||
resetPositionText();
|
||||
|
||||
// angle between the major axis of the ellipse and the X axis
|
||||
double a = (axisPoint-centerPoint).Length();
|
||||
double phi = atan2(axisPoint.fY-centerPoint.fY,axisPoint.fX-centerPoint.fX);
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatpoint = acos((startingPoint.fX-centerPoint.fX+(startingPoint.fY-centerPoint.fY)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
|
||||
double b=abs((startingPoint.fY-centerPoint.fY-a*cos(angleatpoint)*sin(phi))/(sin(angleatpoint)*cos(phi)));
|
||||
|
||||
double angle1 = atan2(a*((endPoint.fY - centerPoint.fY)*cos(phi)-(endPoint.fX - centerPoint.fX)*sin(phi)),
|
||||
b*((endPoint.fX - centerPoint.fX)*cos(phi)+(endPoint.fY - centerPoint.fY)*sin(phi)))- startAngle;
|
||||
|
||||
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI ;
|
||||
arcAngle = abs(angle1-arcAngle) < abs(angle2-arcAngle) ? angle1 : angle2;
|
||||
|
||||
if (arcAngle > 0)
|
||||
endAngle = startAngle + arcAngle;
|
||||
else {
|
||||
endAngle = startAngle;
|
||||
startAngle += arcAngle;
|
||||
}
|
||||
|
||||
Base::Vector2D majAxisDir,minAxisDir,minAxisPoint,majAxisPoint;
|
||||
// We always create a CCW ellipse, because we want our XY reference system to be in the +X +Y direction
|
||||
// Our normal will then always be in the +Z axis (local +Z axis of the sketcher)
|
||||
|
||||
if(a>b)
|
||||
{
|
||||
// force second semidiameter to be perpendicular to first semidiamater
|
||||
majAxisDir = axisPoint - centerPoint;
|
||||
Base::Vector2D perp(-majAxisDir.fY,majAxisDir.fX);
|
||||
perp.Normalize();
|
||||
perp.Scale(abs(b));
|
||||
minAxisPoint = centerPoint+perp;
|
||||
majAxisPoint = centerPoint+majAxisDir;
|
||||
}
|
||||
else {
|
||||
// force second semidiameter to be perpendicular to first semidiamater
|
||||
minAxisDir = axisPoint - centerPoint;
|
||||
Base::Vector2D perp(minAxisDir.fY,-minAxisDir.fX);
|
||||
perp.Normalize();
|
||||
perp.Scale(abs(b));
|
||||
majAxisPoint = centerPoint+perp;
|
||||
minAxisPoint = centerPoint+minAxisDir;
|
||||
endAngle += M_PI/2;
|
||||
startAngle += M_PI/2;
|
||||
}
|
||||
|
||||
//startAngle=-M_PI/4;
|
||||
//endAngle=M_PI/4;
|
||||
|
||||
Gui::Command::openCommand("Add sketch arc of ellipse");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.addGeometry(Part.ArcOfEllipse"
|
||||
"(Part.Ellipse(App.Vector(%f,%f,0),App.Vector(%f,%f,0),App.Vector(%f,%f,0)),"
|
||||
"%f,%f))",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
majAxisPoint.fX, majAxisPoint.fY,
|
||||
minAxisPoint.fX, minAxisPoint.fY,
|
||||
centerPoint.fX, centerPoint.fY,
|
||||
startAngle, endAngle); //arcAngle > 0 ? 0 : 1);
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::updateActive();
|
||||
|
||||
// add auto constraints for the center point
|
||||
if (sugConstr1.size() > 0) {
|
||||
createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::mid);
|
||||
sugConstr1.clear();
|
||||
}
|
||||
|
||||
// add suggested constraints for circumference
|
||||
if (sugConstr2.size() > 0) {
|
||||
//createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::none);
|
||||
sugConstr2.clear();
|
||||
}
|
||||
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
|
||||
}
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
SelectMode Mode;
|
||||
std::vector<Base::Vector2D> EditCurve;
|
||||
Base::Vector2D centerPoint, axisPoint, startingPoint, endPoint;
|
||||
double rx, ry, startAngle, endAngle, arcAngle, arcAngle_t;
|
||||
std::vector<AutoConstraint> sugConstr1, sugConstr2, sugConstr3, sugConstr4;
|
||||
|
||||
};
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherCreateArcOfEllipse);
|
||||
|
||||
CmdSketcherCreateArcOfEllipse::CmdSketcherCreateArcOfEllipse()
|
||||
: Command("Sketcher_CreateArcOfEllipse")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = QT_TR_NOOP("Sketcher");
|
||||
sMenuText = QT_TR_NOOP("Create an arc of ellipse");
|
||||
sToolTipText = QT_TR_NOOP("Create an arc of ellipse in the sketch");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Sketcher_Elliptical_Arc";
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
void CmdSketcherCreateArcOfEllipse::activated(int iMsg)
|
||||
{
|
||||
ActivateHandler(getActiveGuiDocument(),new DrawSketchHandlerArcOfEllipse() );
|
||||
}
|
||||
|
||||
bool CmdSketcherCreateArcOfEllipse::isActive(void)
|
||||
{
|
||||
return isCreateGeoActive(getActiveGuiDocument());
|
||||
}
|
||||
|
||||
// ======================================================================================
|
||||
|
||||
@@ -2548,6 +3121,7 @@ namespace SketcherGui {
|
||||
geom->getTypeId() == Part::GeomCircle::getClassTypeId()||
|
||||
geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
|
||||
return true;
|
||||
// TODO: ellipse
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2628,6 +3202,7 @@ public:
|
||||
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomCircle::getClassTypeId()
|
||||
// TODO: ellipse
|
||||
) {
|
||||
try {
|
||||
Gui::Command::openCommand("Trim edge");
|
||||
@@ -3548,6 +4123,8 @@ void CreateSketcherCommandsCreateGeo(void)
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreateCircle());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreate3PointCircle());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCompCreateCircle());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreateEllipse());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreateArcOfEllipse());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreateLine());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreatePolyline());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreateRectangle());
|
||||
|
||||
@@ -679,6 +679,285 @@ bool CmdSketcherSelectElementsAssociatedWithConstraints::isActive(void)
|
||||
return isSketcherAcceleratorActive( getActiveGuiDocument(), true );
|
||||
}
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherRestoreInternalAlignmentGeometry);
|
||||
|
||||
CmdSketcherRestoreInternalAlignmentGeometry::CmdSketcherRestoreInternalAlignmentGeometry()
|
||||
:Command("Sketcher_RestoreInternalAlignmentGeometry")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = QT_TR_NOOP("Sketcher");
|
||||
sMenuText = QT_TR_NOOP("Show/hide internal geometry");
|
||||
sToolTipText = QT_TR_NOOP("Show all internal geometry / hide unused internal geometry");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Sketcher_Element_Ellipse_All";
|
||||
sAccel = "CTRL+SHIFT+E";
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
void CmdSketcherRestoreInternalAlignmentGeometry::activated(int iMsg)
|
||||
{
|
||||
// get the selection
|
||||
std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
|
||||
Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
|
||||
|
||||
// only one sketch with its subelements are allowed to be selected
|
||||
if (selection.size() != 1) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select elements from a single sketch."));
|
||||
return;
|
||||
}
|
||||
|
||||
// get the needed lists and objects
|
||||
const std::vector<std::string> &SubNames = selection[0].getSubNames();
|
||||
const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
|
||||
|
||||
std::string doc_name = Obj->getDocument()->getName();
|
||||
std::string obj_name = Obj->getNameInDocument();
|
||||
std::stringstream ss;
|
||||
|
||||
getSelection().clearSelection();
|
||||
|
||||
// go through the selected subelements
|
||||
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
|
||||
// only handle edges
|
||||
if (it->size() > 4 && it->substr(0,4) == "Edge") {
|
||||
int GeoId = std::atoi(it->substr(4,4000).c_str()) - 1;
|
||||
const Part::Geometry *geo = Obj->getGeometry(GeoId);
|
||||
// Only for supported types
|
||||
if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId() || geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
// First we search what has to be restored
|
||||
bool major=false;
|
||||
bool minor=false;
|
||||
bool focus1=false;
|
||||
bool focus2=false;
|
||||
bool extra_elements=false;
|
||||
|
||||
int majorelementindex=-1;
|
||||
int minorelementindex=-1;
|
||||
int focus1elementindex=-1;
|
||||
int focus2elementindex=-1;
|
||||
|
||||
const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
|
||||
|
||||
for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin();
|
||||
it != vals.end(); ++it) {
|
||||
if((*it)->Type == Sketcher::InternalAlignment && (*it)->Second == GeoId)
|
||||
{
|
||||
switch((*it)->AlignmentType){
|
||||
case Sketcher::EllipseMajorDiameter:
|
||||
major=true;
|
||||
majorelementindex=(*it)->First;
|
||||
break;
|
||||
case Sketcher::EllipseMinorDiameter:
|
||||
minor=true;
|
||||
minorelementindex=(*it)->First;
|
||||
break;
|
||||
case Sketcher::EllipseFocus1:
|
||||
focus1=true;
|
||||
focus1elementindex=(*it)->First;
|
||||
break;
|
||||
case Sketcher::EllipseFocus2:
|
||||
focus2=true;
|
||||
focus2elementindex=(*it)->First;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(major && minor && focus1 && focus2)
|
||||
{
|
||||
// Hide unused geometry here
|
||||
int majorconstraints=0; // number of constraints associated to the geoid of the major axis
|
||||
int minorconstraints=0;
|
||||
int focus1constraints=0;
|
||||
int focus2constraints=0;
|
||||
|
||||
for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin();
|
||||
it != vals.end(); ++it) {
|
||||
|
||||
if((*it)->Second == majorelementindex || (*it)->First == majorelementindex || (*it)->Third == majorelementindex)
|
||||
majorconstraints++;
|
||||
else if((*it)->Second == minorelementindex || (*it)->First == minorelementindex || (*it)->Third == minorelementindex)
|
||||
minorconstraints++;
|
||||
else if((*it)->Second == focus1elementindex || (*it)->First == focus1elementindex || (*it)->Third == focus1elementindex)
|
||||
focus1constraints++;
|
||||
else if((*it)->Second == focus2elementindex || (*it)->First == focus2elementindex || (*it)->Third == focus2elementindex)
|
||||
focus2constraints++;
|
||||
}
|
||||
// those with less than 2 constraints must be removed
|
||||
if(majorconstraints>=2 && minorconstraints>=2 && focus1constraints>=2 && focus2constraints>=2)
|
||||
return; // nothing to delete
|
||||
|
||||
App::Document* doc = App::GetApplication().getActiveDocument();
|
||||
|
||||
if (!doc) return;
|
||||
|
||||
doc->openTransaction("Delete");
|
||||
|
||||
if(majorconstraints<2) {
|
||||
ss.str(std::string());
|
||||
ss << "Edge" << majorelementindex + 1;
|
||||
Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str());
|
||||
}
|
||||
|
||||
if(minorconstraints<2) {
|
||||
ss.str(std::string());
|
||||
ss << "Edge" << minorelementindex + 1;
|
||||
Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str());
|
||||
}
|
||||
|
||||
if(focus1constraints<2) {
|
||||
ss.str(std::string());
|
||||
int vertex = Obj->getVertexIndexGeoPos(focus1elementindex,Sketcher::start);
|
||||
if(vertex>-1){
|
||||
ss << "Vertex" << vertex + 1;
|
||||
Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if(focus2constraints<2) {
|
||||
ss.str(std::string());
|
||||
int vertex = Obj->getVertexIndexGeoPos(focus2elementindex,Sketcher::start);
|
||||
if(vertex>-1){
|
||||
ss << "Vertex" << vertex + 1;
|
||||
Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str(), ss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
SketcherGui::ViewProviderSketch* vp = dynamic_cast<SketcherGui::ViewProviderSketch*>(getActiveGuiDocument()->getInEdit());
|
||||
|
||||
if (vp) {
|
||||
std::vector<Gui::SelectionObject> sel = Gui::Selection().getSelectionEx(doc->getName());
|
||||
vp->onDelete(sel[0].getSubNames());
|
||||
}
|
||||
|
||||
|
||||
doc->commitTransaction();
|
||||
return;
|
||||
}
|
||||
|
||||
Gui::Command::openCommand("Expose ellipse internal geometry");
|
||||
|
||||
int currentgeoid= Obj->getHighestCurveIndex();
|
||||
int incrgeo= 0;
|
||||
int majorindex=-1;
|
||||
int minorindex=-1;
|
||||
|
||||
Base::Vector3d center;
|
||||
double majord;
|
||||
double minord;
|
||||
double phi;
|
||||
|
||||
if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId()){
|
||||
const Part::GeomEllipse *ellipse = static_cast<const Part::GeomEllipse *>(geo);
|
||||
|
||||
center=ellipse->getCenter();
|
||||
majord=ellipse->getMajorRadius();
|
||||
minord=ellipse->getMinorRadius();
|
||||
phi=ellipse->getAngleXU();
|
||||
}
|
||||
else {
|
||||
const Part::GeomArcOfEllipse *aoe = static_cast<const Part::GeomArcOfEllipse *>(geo);
|
||||
|
||||
center=aoe->getCenter();
|
||||
majord=aoe->getMajorRadius();
|
||||
minord=aoe->getMinorRadius();
|
||||
phi=aoe->getAngleXU();
|
||||
}
|
||||
|
||||
majord*=0.99;
|
||||
minord*=0.99;
|
||||
|
||||
|
||||
Base::Vector3d majorpositiveend = center + majord * Base::Vector3d(cos(phi),sin(phi),0);
|
||||
Base::Vector3d majornegativeend = center - majord * Base::Vector3d(cos(phi),sin(phi),0);
|
||||
Base::Vector3d minorpositiveend = center + minord * Base::Vector3d(-sin(phi),cos(phi),0);
|
||||
Base::Vector3d minornegativeend = center - minord * Base::Vector3d(-sin(phi),cos(phi),0);
|
||||
|
||||
double df= sqrt(majord*majord-minord*minord);
|
||||
|
||||
Base::Vector3d focus1P = center + df * Base::Vector3d(cos(phi),sin(phi),0);
|
||||
Base::Vector3d focus2P = center - df * Base::Vector3d(cos(phi),sin(phi),0);
|
||||
|
||||
try{
|
||||
if(!major)
|
||||
{
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
|
||||
Obj->getNameInDocument(),
|
||||
majornegativeend.x,majornegativeend.y,majorpositiveend.x,majorpositiveend.y); // create line for major axis
|
||||
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseMajorDiameter',%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+incrgeo+1,GeoId); // constrain major axis
|
||||
majorindex=currentgeoid+incrgeo+1;
|
||||
incrgeo++;
|
||||
}
|
||||
if(!minor)
|
||||
{
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
|
||||
Obj->getNameInDocument(),
|
||||
minorpositiveend.x,minorpositiveend.y,minornegativeend.x,minornegativeend.y); // create line for minor axis
|
||||
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseMinorDiameter',%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+incrgeo+1,GeoId); // constrain minor axis
|
||||
minorindex=currentgeoid+incrgeo+1;
|
||||
incrgeo++;
|
||||
}
|
||||
if(!focus1)
|
||||
{
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Point(App.Vector(%f,%f,0)))",
|
||||
Obj->getNameInDocument(),
|
||||
focus1P.x,focus1P.y);
|
||||
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseFocus1',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+incrgeo+1,Sketcher::start,GeoId); // constrain major axis
|
||||
incrgeo++;
|
||||
}
|
||||
if(!focus2)
|
||||
{
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Point(App.Vector(%f,%f,0)))",
|
||||
Obj->getNameInDocument(),
|
||||
focus2P.x,focus2P.y);
|
||||
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('InternalAlignment:EllipseFocus2',%d,%d,%d)) ",
|
||||
Obj->getNameInDocument(),currentgeoid+incrgeo+1,Sketcher::start,GeoId); // constrain major axis
|
||||
}
|
||||
|
||||
// Make lines construction lines
|
||||
if(majorindex!=-1){
|
||||
doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",Obj->getNameInDocument(),majorindex);
|
||||
}
|
||||
|
||||
if(minorindex!=-1){
|
||||
doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",Obj->getNameInDocument(),minorindex);
|
||||
}
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::updateActive();
|
||||
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::updateActive();
|
||||
}
|
||||
|
||||
} // if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId())
|
||||
else {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Currently internal geometry is only supported for ellipse and arc of ellipse. The last selected element must be an ellipse or an arc of ellipse."));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSketcherRestoreInternalAlignmentGeometry::isActive(void)
|
||||
{
|
||||
return isSketcherAcceleratorActive( getActiveGuiDocument(), true );
|
||||
}
|
||||
|
||||
|
||||
void CreateSketcherCommandsConstraintAccel(void)
|
||||
{
|
||||
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
|
||||
@@ -692,4 +971,5 @@ void CreateSketcherCommandsConstraintAccel(void)
|
||||
rcCmdMgr.addCommand(new CmdSketcherSelectRedundantConstraints());
|
||||
rcCmdMgr.addCommand(new CmdSketcherSelectConflictingConstraints());
|
||||
rcCmdMgr.addCommand(new CmdSketcherSelectElementsAssociatedWithConstraints());
|
||||
rcCmdMgr.addCommand(new CmdSketcherRestoreInternalAlignmentGeometry());
|
||||
}
|
||||
|
||||
@@ -241,6 +241,27 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint> &suggested
|
||||
tangDeviation = projDist;
|
||||
}
|
||||
|
||||
} else if ((*it)->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
// TODO: Ellipse
|
||||
const Part::GeomEllipse *ellipse = dynamic_cast<const Part::GeomEllipse *>((*it));
|
||||
|
||||
Base::Vector3d center = ellipse->getCenter();
|
||||
Base::Vector3d tmpPos(Pos.fX, Pos.fY, 0.f);
|
||||
|
||||
double radius = ellipse->getMajorRadius();
|
||||
|
||||
Base::Vector3d projPnt(0.f, 0.f, 0.f);
|
||||
projPnt = projPnt.ProjToLine(center - tmpPos, Base::Vector3d(Dir.fX, Dir.fY));
|
||||
double projDist = projPnt.Length();
|
||||
|
||||
if ( (projDist < radius + tangDeviation ) && (projDist > radius - tangDeviation)) {
|
||||
//Find if nearest
|
||||
if (projDist < tangDeviation) {
|
||||
tangId = i;
|
||||
tangDeviation = projDist;
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((*it)->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>((*it));
|
||||
|
||||
|
||||
@@ -72,8 +72,10 @@ void EditDatumDialog::exec(bool atCursor)
|
||||
{
|
||||
// Return if constraint doesn't have editable value
|
||||
if (Constr->Type == Sketcher::Distance ||
|
||||
Constr->Type == Sketcher::DistanceX || Constr->Type == Sketcher::DistanceY ||
|
||||
Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Angle) {
|
||||
Constr->Type == Sketcher::DistanceX ||
|
||||
Constr->Type == Sketcher::DistanceY ||
|
||||
Constr->Type == Sketcher::Radius ||
|
||||
Constr->Type == Sketcher::Angle) {
|
||||
|
||||
if (sketch->hasConflicts()) {
|
||||
QMessageBox::critical(qApp->activeWindow(), QObject::tr("Distance constraint"),
|
||||
|
||||
@@ -73,7 +73,7 @@ void PropertyConstraintListItem::initialize()
|
||||
(*it)->Type == Sketcher::DistanceX ||
|
||||
(*it)->Type == Sketcher::DistanceY ||
|
||||
(*it)->Type == Sketcher::Radius ||
|
||||
(*it)->Type == Sketcher::Angle) {
|
||||
(*it)->Type == Sketcher::Angle ) {
|
||||
|
||||
PropertyUnitItem* item = static_cast<PropertyUnitItem*>(PropertyUnitItem::create());
|
||||
|
||||
@@ -146,10 +146,10 @@ QVariant PropertyConstraintListItem::value(const App::Property* prop) const
|
||||
(*it)->Type == Sketcher::DistanceX ||
|
||||
(*it)->Type == Sketcher::DistanceY ||
|
||||
(*it)->Type == Sketcher::Radius ||
|
||||
(*it)->Type == Sketcher::Angle) {
|
||||
(*it)->Type == Sketcher::Angle ) {
|
||||
|
||||
Base::Quantity quant;
|
||||
if ((*it)->Type == Sketcher::Angle) {
|
||||
if ((*it)->Type == Sketcher::Angle ) {
|
||||
double datum = Base::toDegrees<double>((*it)->Value);
|
||||
quant.setUnit(Base::Unit::Angle);
|
||||
quant.setValue(datum);
|
||||
@@ -220,7 +220,7 @@ bool PropertyConstraintListItem::event (QEvent* ev)
|
||||
(*it)->Type == Sketcher::DistanceX ||
|
||||
(*it)->Type == Sketcher::DistanceY ||
|
||||
(*it)->Type == Sketcher::Radius ||
|
||||
(*it)->Type == Sketcher::Angle) {
|
||||
(*it)->Type == Sketcher::Angle ) {
|
||||
|
||||
// Get the internal name
|
||||
QString internalName = QString::fromLatin1("Constraint%1").arg(id+1);
|
||||
|
||||
@@ -319,14 +319,8 @@ void TaskSketcherConstrains::on_listWidgetConstraints_itemChanged(QListWidgetIte
|
||||
QString unitStr;
|
||||
switch(v->Type) {
|
||||
case Sketcher::Distance:
|
||||
unitStr = Base::Quantity(v->Value,Base::Unit::Length).getUserString();
|
||||
break;
|
||||
case Sketcher::DistanceX:
|
||||
unitStr = Base::Quantity(v->Value,Base::Unit::Length).getUserString();
|
||||
break;
|
||||
case Sketcher::DistanceY:
|
||||
unitStr = Base::Quantity(v->Value,Base::Unit::Length).getUserString();
|
||||
break;
|
||||
case Sketcher::Radius:
|
||||
unitStr = Base::Quantity(v->Value,Base::Unit::Length).getUserString();
|
||||
break;
|
||||
@@ -360,10 +354,18 @@ void TaskSketcherConstrains::slotConstraintsChanged(void)
|
||||
QIcon tang ( Gui::BitmapFactory().pixmap("Constraint_Tangent") );
|
||||
QIcon dist ( Gui::BitmapFactory().pixmap("Constraint_Length") );
|
||||
QIcon radi ( Gui::BitmapFactory().pixmap("Constraint_Radius") );
|
||||
QIcon majradi ( Gui::BitmapFactory().pixmap("Constraint_Ellipse_Major_Radius") );
|
||||
QIcon minradi ( Gui::BitmapFactory().pixmap("Constraint_Ellipse_Minor_Radius") );
|
||||
QIcon angl ( Gui::BitmapFactory().pixmap("Constraint_InternalAngle") );
|
||||
QIcon ellipseXUAngl ( Gui::BitmapFactory().pixmap("Constraint_Ellipse_Axis_Angle") );
|
||||
QIcon equal( Gui::BitmapFactory().pixmap("Constraint_EqualLength") );
|
||||
QIcon pntoo( Gui::BitmapFactory().pixmap("Constraint_PointOnObject") );
|
||||
QIcon symm ( Gui::BitmapFactory().pixmap("Constraint_Symmetric") );
|
||||
QIcon iaellipseminoraxis ( Gui::BitmapFactory().pixmap("Constraint_InternalAlignment_Ellipse_MinorAxis") );
|
||||
QIcon iaellipsemajoraxis ( Gui::BitmapFactory().pixmap("Constraint_InternalAlignment_Ellipse_MajorAxis") );
|
||||
QIcon iaellipsefocus1 ( Gui::BitmapFactory().pixmap("Constraint_InternalAlignment_Ellipse_Focus1") );
|
||||
QIcon iaellipsefocus2 ( Gui::BitmapFactory().pixmap("Constraint_InternalAlignment_Ellipse_Focus2") );
|
||||
QIcon iaellipseother ( Gui::BitmapFactory().pixmap("Constraint_InternalAlignment") );
|
||||
|
||||
assert(sketchView);
|
||||
// Build up ListView with the constraints
|
||||
@@ -464,6 +466,27 @@ void TaskSketcherConstrains::slotConstraintsChanged(void)
|
||||
ui->listWidgetConstraints->addItem(item);
|
||||
}
|
||||
break;
|
||||
case Sketcher::InternalAlignment:
|
||||
if (Filter<2 || (Filter==3 && !(*it)->Name.empty()))
|
||||
switch((*it)->AlignmentType){
|
||||
case Sketcher::EllipseMajorDiameter:
|
||||
ui->listWidgetConstraints->addItem(new ConstraintItem(iaellipsemajoraxis,name,i-1,(*it)->Type));
|
||||
break;
|
||||
case Sketcher::EllipseMinorDiameter:
|
||||
ui->listWidgetConstraints->addItem(new ConstraintItem(iaellipseminoraxis,name,i-1,(*it)->Type));
|
||||
break;
|
||||
case Sketcher::EllipseFocus1:
|
||||
ui->listWidgetConstraints->addItem(new ConstraintItem(iaellipsefocus1,name,i-1,(*it)->Type));
|
||||
break;
|
||||
case Sketcher::EllipseFocus2:
|
||||
ui->listWidgetConstraints->addItem(new ConstraintItem(iaellipsefocus2,name,i-1,(*it)->Type));
|
||||
break;
|
||||
case Sketcher::Undef:
|
||||
default:
|
||||
ui->listWidgetConstraints->addItem(new ConstraintItem(iaellipseother,name,i-1,(*it)->Type));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ui->listWidgetConstraints->addItem(new ConstraintItem(name,i-1,(*it)->Type));
|
||||
break;
|
||||
|
||||
@@ -148,7 +148,7 @@ void ElementView::contextMenuEvent (QContextMenuEvent* event)
|
||||
CONTEXT_ITEM("Constraint_Length","Length Constraint","Sketcher_ConstrainDistance",doLengthConstraint,true)
|
||||
CONTEXT_ITEM("Constraint_Radius","Radius Constraint","Sketcher_ConstrainRadius",doRadiusConstraint,true)
|
||||
CONTEXT_ITEM("Constraint_InternalAngle","Angle Constraint","Sketcher_ConstrainAngle",doAngleConstraint,true)
|
||||
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
CONTEXT_ITEM("Sketcher_AlterConstruction","Toggle construction line","Sketcher_ToggleConstruction",doToggleConstruction,true)
|
||||
@@ -638,7 +638,12 @@ void TaskSketcherElements::slotElementsChanged(void)
|
||||
QIcon Sketcher_Element_Line_EndPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Line_EndPoint") );
|
||||
QIcon Sketcher_Element_Line_StartingPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Line_StartingPoint") );
|
||||
QIcon Sketcher_Element_Point_StartingPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Point_StartingPoint") );
|
||||
|
||||
QIcon Sketcher_Element_Ellipse_Edge( Gui::BitmapFactory().pixmap("Sketcher_Element_Ellipse_Edge_2") );
|
||||
QIcon Sketcher_Element_Ellipse_MidPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Ellipse_CentrePoint") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_Edge( Gui::BitmapFactory().pixmap("Sketcher_Element_Elliptical_Arc_Edge") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_MidPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Elliptical_Arc_Centre_Point") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_StartingPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Elliptical_Arc_Start_Point") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_EndPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Elliptical_Arc_End_Point") );
|
||||
QIcon none( Gui::BitmapFactory().pixmap("Sketcher_Element_SelectionTypeInvalid") );
|
||||
|
||||
assert(sketchView);
|
||||
@@ -654,29 +659,41 @@ void TaskSketcherElements::slotElementsChanged(void)
|
||||
Base::Type type = (*it)->getTypeId();
|
||||
|
||||
ui->listWidgetElements->addItem(new ElementItem(
|
||||
(type == Part::GeomPoint::getClassTypeId() && element==1) ? Sketcher_Element_Point_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==0) ? Sketcher_Element_Line_Edge :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==1) ? Sketcher_Element_Line_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==2) ? Sketcher_Element_Line_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==0) ? Sketcher_Element_Arc_Edge :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==1) ? Sketcher_Element_Arc_StartingPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==2) ? Sketcher_Element_Arc_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==3) ? Sketcher_Element_Arc_MidPoint :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==0) ? Sketcher_Element_Circle_Edge :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==3) ? Sketcher_Element_Circle_MidPoint :
|
||||
(type == Part::GeomPoint::getClassTypeId() && element==1) ? Sketcher_Element_Point_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==0) ? Sketcher_Element_Line_Edge :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==1) ? Sketcher_Element_Line_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==2) ? Sketcher_Element_Line_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==0) ? Sketcher_Element_Arc_Edge :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==1) ? Sketcher_Element_Arc_StartingPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==2) ? Sketcher_Element_Arc_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==3) ? Sketcher_Element_Arc_MidPoint :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==0) ? Sketcher_Element_Circle_Edge :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==3) ? Sketcher_Element_Circle_MidPoint :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==0) ? Sketcher_Element_Ellipse_Edge :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==3) ? Sketcher_Element_Ellipse_MidPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfEllipse_Edge :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfEllipse_StartingPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfEllipse_EndPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfEllipse_MidPoint :
|
||||
none,
|
||||
type == Part::GeomPoint::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Point") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Point"))) :
|
||||
type == Part::GeomLineSegment::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Line") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Line"))) :
|
||||
type == Part::GeomArcOfCircle::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Arc") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Arc"))) :
|
||||
type == Part::GeomCircle::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Circle") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Circle"))) :
|
||||
type == Part::GeomPoint::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Point") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Point"))) :
|
||||
type == Part::GeomLineSegment::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Line") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Line"))) :
|
||||
type == Part::GeomArcOfCircle::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Arc") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Arc"))) :
|
||||
type == Part::GeomCircle::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Circle") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Circle"))) :
|
||||
type == Part::GeomEllipse::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Ellipse") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Ellipse"))) :
|
||||
type == Part::GeomArcOfEllipse::getClassTypeId() ? ( isNamingBoxChecked ?
|
||||
(tr("Elliptical Arc") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Elliptical Arc"))) :
|
||||
( isNamingBoxChecked ?
|
||||
(tr("Other") + QString::fromLatin1("(Edge%1)").arg(i)):
|
||||
(QString::fromLatin1("%1-").arg(i)+tr("Other"))),
|
||||
@@ -749,16 +766,17 @@ void TaskSketcherElements::on_listWidgetElements_filterShortcutPressed()
|
||||
|
||||
switch(element)
|
||||
{
|
||||
|
||||
case 0: // Edge
|
||||
element = ( type == Part::GeomCircle::getClassTypeId() ) ? 3 : 1;
|
||||
element = ( type == Part::GeomCircle::getClassTypeId() || type == Part::GeomEllipse::getClassTypeId() ) ? 3 : 1;
|
||||
break;
|
||||
case 1: // StartingPoint
|
||||
element = ( type == Part::GeomCircle::getClassTypeId() ) ? 3 :
|
||||
( type == Part::GeomPoint::getClassTypeId() ) ? 1 : 2;
|
||||
element = ( type == Part::GeomCircle::getClassTypeId() || type == Part::GeomEllipse::getClassTypeId() ) ? 3 :
|
||||
( type == Part::GeomPoint::getClassTypeId() ) ? 1 : 2;
|
||||
break;
|
||||
case 2: // EndPoint
|
||||
element = ( type == Part::GeomLineSegment::getClassTypeId() ) ? 0 :
|
||||
( type == Part::GeomPoint::getClassTypeId() ) ? 1 : 3;
|
||||
( type == Part::GeomPoint::getClassTypeId() ) ? 1 : 3;
|
||||
break;
|
||||
case 3: // MidPoint
|
||||
element = ( type == Part::GeomPoint::getClassTypeId() ) ? 1 : 0;
|
||||
@@ -850,22 +868,34 @@ void TaskSketcherElements::updateIcons(int element)
|
||||
QIcon Sketcher_Element_Line_EndPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Line_EndPoint") );
|
||||
QIcon Sketcher_Element_Line_StartingPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Line_StartingPoint") );
|
||||
QIcon Sketcher_Element_Point_StartingPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Point_StartingPoint") );
|
||||
QIcon Sketcher_Element_Ellipse_Edge( Gui::BitmapFactory().pixmap("Sketcher_Element_Ellipse_Edge_2") );
|
||||
QIcon Sketcher_Element_Ellipse_MidPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Ellipse_CentrePoint") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_Edge( Gui::BitmapFactory().pixmap("Sketcher_Element_Elliptical_Arc_Edge") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_MidPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Elliptical_Arc_Centre_Point") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_StartingPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Elliptical_Arc_Start_Point") );
|
||||
QIcon Sketcher_Element_ArcOfEllipse_EndPoint( Gui::BitmapFactory().pixmap("Sketcher_Element_Elliptical_Arc_End_Point") );
|
||||
QIcon none( Gui::BitmapFactory().pixmap("Sketcher_Element_SelectionTypeInvalid") );
|
||||
|
||||
for (int i=0;i<ui->listWidgetElements->count(); i++) {
|
||||
Base::Type type = static_cast<ElementItem *>(ui->listWidgetElements->item(i))->GeometryType;
|
||||
|
||||
ui->listWidgetElements->item(i)->setIcon(
|
||||
(type == Part::GeomPoint::getClassTypeId() && element==1) ? Sketcher_Element_Point_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==0) ? Sketcher_Element_Line_Edge :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==1) ? Sketcher_Element_Line_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==2) ? Sketcher_Element_Line_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==0) ? Sketcher_Element_Arc_Edge :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==1) ? Sketcher_Element_Arc_StartingPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==2) ? Sketcher_Element_Arc_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==3) ? Sketcher_Element_Arc_MidPoint :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==0) ? Sketcher_Element_Circle_Edge :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==3) ? Sketcher_Element_Circle_MidPoint :
|
||||
(type == Part::GeomPoint::getClassTypeId() && element==1) ? Sketcher_Element_Point_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==0) ? Sketcher_Element_Line_Edge :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==1) ? Sketcher_Element_Line_StartingPoint :
|
||||
(type == Part::GeomLineSegment::getClassTypeId() && element==2) ? Sketcher_Element_Line_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==0) ? Sketcher_Element_Arc_Edge :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==1) ? Sketcher_Element_Arc_StartingPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==2) ? Sketcher_Element_Arc_EndPoint :
|
||||
(type == Part::GeomArcOfCircle::getClassTypeId() && element==3) ? Sketcher_Element_Arc_MidPoint :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==0) ? Sketcher_Element_Circle_Edge :
|
||||
(type == Part::GeomCircle::getClassTypeId() && element==3) ? Sketcher_Element_Circle_MidPoint :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==0) ? Sketcher_Element_Ellipse_Edge :
|
||||
(type == Part::GeomEllipse::getClassTypeId() && element==3) ? Sketcher_Element_Ellipse_MidPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==0) ? Sketcher_Element_ArcOfEllipse_Edge :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==1) ? Sketcher_Element_ArcOfEllipse_StartingPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==2) ? Sketcher_Element_ArcOfEllipse_EndPoint :
|
||||
(type == Part::GeomArcOfEllipse::getClassTypeId() && element==3) ? Sketcher_Element_ArcOfEllipse_MidPoint :
|
||||
none);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
# include <Poly_Polygon3D.hxx>
|
||||
# include <Geom_BSplineCurve.hxx>
|
||||
# include <Geom_Circle.hxx>
|
||||
# include <Geom_Ellipse.hxx>
|
||||
# include <Geom_TrimmedCurve.hxx>
|
||||
# include <Inventor/actions/SoGetBoundingBoxAction.h>
|
||||
# include <Inventor/SoPath.h>
|
||||
@@ -715,7 +716,9 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe
|
||||
const Part::Geometry *geo = getSketchObject()->getGeometry(edit->DragCurve);
|
||||
if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
geo->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomEllipse::getClassTypeId()||
|
||||
geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { // TODO: ellipse
|
||||
Gui::Command::openCommand("Drag Curve");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.movePoint(%i,%i,App.Vector(%f,%f,0),%i)"
|
||||
,getObject()->getNameInDocument()
|
||||
@@ -912,8 +915,10 @@ void ViewProviderSketch::editDoubleClicked(void)
|
||||
|
||||
// if its the right constraint
|
||||
if (Constr->Type == Sketcher::Distance ||
|
||||
Constr->Type == Sketcher::DistanceX || Constr->Type == Sketcher::DistanceY ||
|
||||
Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Angle) {
|
||||
Constr->Type == Sketcher::DistanceX ||
|
||||
Constr->Type == Sketcher::DistanceY ||
|
||||
Constr->Type == Sketcher::Radius ||
|
||||
Constr->Type == Sketcher::Angle) {
|
||||
|
||||
// Coin's SoIdleSensor causes problems on some platform while Qt seems to work properly (#0001517)
|
||||
EditDatumDialog *editDatumDialog = new EditDatumDialog(this, *it);
|
||||
@@ -1161,14 +1166,15 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2D &toPo
|
||||
p1 = arc->getCenter();
|
||||
p2 = p1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo);
|
||||
double radius = circle->getRadius();
|
||||
p1 = circle->getCenter();
|
||||
Base::Vector3d tmpDir = Base::Vector3d(toPos.fX, toPos.fY, 0) - p1;
|
||||
double angle = atan2(tmpDir.y, tmpDir.x);
|
||||
p2 = p1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
|
||||
} else
|
||||
}
|
||||
else
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
@@ -1815,7 +1821,7 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s &startPos, const SbVec2s &
|
||||
Gui::Selection().addSelection(doc->getName(), sketchObject->getNameInDocument(), ss.str().c_str());
|
||||
}
|
||||
|
||||
} else if ((*it)->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
} else if ((*it)->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
// ----- Check if circle lies inside box selection -----/
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(*it);
|
||||
pnt0 = circle->getCenter();
|
||||
@@ -1850,6 +1856,50 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s &startPos, const SbVec2s &
|
||||
}
|
||||
}
|
||||
|
||||
if (bpolyInside) {
|
||||
ss.clear();
|
||||
ss.str("");
|
||||
ss << "Edge" << GeoId + 1;
|
||||
Gui::Selection().addSelection(doc->getName(), sketchObject->getNameInDocument(),ss.str().c_str());
|
||||
}
|
||||
}
|
||||
} else if ((*it)->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
// ----- Check if circle lies inside box selection -----/
|
||||
const Part::GeomEllipse *ellipse = dynamic_cast<const Part::GeomEllipse *>(*it);
|
||||
pnt0 = ellipse->getCenter();
|
||||
VertexId += 1;
|
||||
|
||||
Plm.multVec(pnt0, pnt0);
|
||||
pnt0 = proj(pnt0);
|
||||
|
||||
if (polygon.Contains(Base::Vector2D(pnt0.x, pnt0.y))) {
|
||||
std::stringstream ss;
|
||||
ss << "Vertex" << VertexId + 1;
|
||||
Gui::Selection().addSelection(doc->getName(), sketchObject->getNameInDocument(), ss.str().c_str());
|
||||
|
||||
int countSegments = 12;
|
||||
float segment = float(2 * M_PI) / countSegments;
|
||||
|
||||
// circumscribed polygon radius
|
||||
float a = float(ellipse->getMajorRadius()) / cos(segment/2);
|
||||
float b = float(ellipse->getMinorRadius()) / cos(segment/2);
|
||||
float phi = float(ellipse->getAngleXU());
|
||||
|
||||
bool bpolyInside = true;
|
||||
pnt0 = ellipse->getCenter();
|
||||
float angle = 0.f;
|
||||
for (int i = 0; i < countSegments; ++i, angle += segment) {
|
||||
pnt = Base::Vector3d(pnt0.x + a * cos(angle) * cos(phi) - b * sin(angle) * sin(phi),
|
||||
pnt0.y + a * cos(angle) * sin(phi) + b * sin(angle) * cos(phi),
|
||||
0.f);
|
||||
Plm.multVec(pnt, pnt);
|
||||
pnt = proj(pnt);
|
||||
if (!polygon.Contains(Base::Vector2D(pnt.x, pnt.y))) {
|
||||
bpolyInside = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bpolyInside) {
|
||||
ss.clear();
|
||||
ss.str("");
|
||||
@@ -2082,7 +2132,7 @@ void ViewProviderSketch::updateColor(void)
|
||||
bool hasMaterial = false;
|
||||
|
||||
SoMaterial *m;
|
||||
if (!hasDatumLabel && type != Sketcher::Coincident) {
|
||||
if (!hasDatumLabel && type != Sketcher::Coincident && type !=InternalAlignment) {
|
||||
hasMaterial = true;
|
||||
m = dynamic_cast<SoMaterial *>(s->getChild(CONSTRAINT_SEPARATOR_INDEX_MATERIAL_OR_DATUMLABEL));
|
||||
}
|
||||
@@ -2095,9 +2145,9 @@ void ViewProviderSketch::updateColor(void)
|
||||
m->diffuseColor = SelectColor;
|
||||
} else if (type == Sketcher::Coincident) {
|
||||
int index;
|
||||
index = edit->ActSketch.getPointId(constraint->First, constraint->FirstPos) + 1;
|
||||
index = edit->ActSketch.getVisiblePointId(constraint->First, constraint->FirstPos) + 1;
|
||||
if (index >= 0 && index < PtNum) pcolor[index] = SelectColor;
|
||||
index = edit->ActSketch.getPointId(constraint->Second, constraint->SecondPos) + 1;
|
||||
index = edit->ActSketch.getVisiblePointId(constraint->Second, constraint->SecondPos) + 1;
|
||||
if (index >= 0 && index < PtNum) pcolor[index] = SelectColor;
|
||||
}
|
||||
} else if (edit->PreselectConstraintSet.count(i)) {
|
||||
@@ -2735,6 +2785,25 @@ void ViewProviderSketch::draw(bool temp)
|
||||
edit->CurvIdToGeoId.push_back(GeoId);
|
||||
Points.push_back(center);
|
||||
}
|
||||
else if ((*it)->getTypeId() == Part::GeomEllipse::getClassTypeId()) { // add an ellipse
|
||||
const Part::GeomEllipse *ellipse = dynamic_cast<const Part::GeomEllipse *>(*it);
|
||||
Handle_Geom_Ellipse curve = Handle_Geom_Ellipse::DownCast(ellipse->handle());
|
||||
|
||||
int countSegments = 50;
|
||||
Base::Vector3d center = ellipse->getCenter();
|
||||
double segment = (2 * M_PI) / countSegments;
|
||||
for (int i=0; i < countSegments; i++) {
|
||||
gp_Pnt pnt = curve->Value(i*segment);
|
||||
Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
|
||||
}
|
||||
|
||||
gp_Pnt pnt = curve->Value(0);
|
||||
Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
|
||||
|
||||
Index.push_back(countSegments+1);
|
||||
edit->CurvIdToGeoId.push_back(GeoId);
|
||||
Points.push_back(center);
|
||||
}
|
||||
else if ((*it)->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { // add an arc
|
||||
const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(*it);
|
||||
Handle_Geom_TrimmedCurve curve = Handle_Geom_TrimmedCurve::DownCast(arc->handle());
|
||||
@@ -2768,6 +2837,39 @@ void ViewProviderSketch::draw(bool temp)
|
||||
Points.push_back(end);
|
||||
Points.push_back(center);
|
||||
}
|
||||
else if ((*it)->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { // add an arc
|
||||
const Part::GeomArcOfEllipse *arc = dynamic_cast<const Part::GeomArcOfEllipse *>(*it);
|
||||
Handle_Geom_TrimmedCurve curve = Handle_Geom_TrimmedCurve::DownCast(arc->handle());
|
||||
|
||||
double startangle, endangle;
|
||||
arc->getRange(startangle, endangle);
|
||||
if (startangle > endangle) // if arc is reversed
|
||||
std::swap(startangle, endangle);
|
||||
|
||||
double range = endangle-startangle;
|
||||
int countSegments = std::max(6, int(50.0 * range / (2 * M_PI)));
|
||||
double segment = range / countSegments;
|
||||
|
||||
Base::Vector3d center = arc->getCenter();
|
||||
Base::Vector3d start = arc->getStartPoint();
|
||||
Base::Vector3d end = arc->getEndPoint();
|
||||
|
||||
for (int i=0; i < countSegments; i++) {
|
||||
gp_Pnt pnt = curve->Value(startangle);
|
||||
Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
|
||||
startangle += segment;
|
||||
}
|
||||
|
||||
// end point
|
||||
gp_Pnt pnt = curve->Value(endangle);
|
||||
Coords.push_back(Base::Vector3d(pnt.X(), pnt.Y(), pnt.Z()));
|
||||
|
||||
Index.push_back(countSegments+1);
|
||||
edit->CurvIdToGeoId.push_back(GeoId);
|
||||
Points.push_back(start);
|
||||
Points.push_back(end);
|
||||
Points.push_back(center);
|
||||
}
|
||||
else if ((*it)->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) { // add a bspline
|
||||
const Part::GeomBSplineCurve *spline = dynamic_cast<const Part::GeomBSplineCurve *>(*it);
|
||||
Handle_Geom_BSplineCurve curve = Handle_Geom_BSplineCurve::DownCast(spline->handle());
|
||||
@@ -2875,7 +2977,8 @@ Restart:
|
||||
// root separator for this constraint
|
||||
SoSeparator *sep = dynamic_cast<SoSeparator *>(edit->constrGroup->getChild(i));
|
||||
const Constraint *Constr = *it;
|
||||
|
||||
|
||||
bool major_radius = false; // this is checked in the radius to reuse code
|
||||
// distinquish different constraint types to build up
|
||||
switch (Constr->Type) {
|
||||
case Horizontal: // write the new position of the Horizontal constraint Same as vertical position.
|
||||
@@ -2929,7 +3032,7 @@ Restart:
|
||||
norm1 = Base::Vector3d(cos(midangle),sin(midangle),0);
|
||||
dir1 = Base::Vector3d(-norm1.y,norm1.x,0);
|
||||
midpos1 = arc->getCenter() + arc->getRadius() * norm1;
|
||||
} else if (geo1->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
} else if (geo1->getTypeId() == Part::GeomCircle::getClassTypeId()) { // TODO: ellipse
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo1);
|
||||
norm1 = Base::Vector3d(cos(M_PI/4),sin(M_PI/4),0);
|
||||
dir1 = Base::Vector3d(-norm1.y,norm1.x,0);
|
||||
@@ -2950,7 +3053,7 @@ Restart:
|
||||
norm2 = Base::Vector3d(cos(midangle),sin(midangle),0);
|
||||
dir2 = Base::Vector3d(-norm2.y,norm2.x,0);
|
||||
midpos2 = arc->getCenter() + arc->getRadius() * norm2;
|
||||
} else if (geo2->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
} else if (geo2->getTypeId() == Part::GeomCircle::getClassTypeId()) { // TODO: ellipse
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo2);
|
||||
norm2 = Base::Vector3d(cos(M_PI/4),sin(M_PI/4),0);
|
||||
dir2 = Base::Vector3d(-norm2.y,norm2.x,0);
|
||||
@@ -2996,7 +3099,7 @@ Restart:
|
||||
geo2->getTypeId() != Part::GeomLineSegment::getClassTypeId()) {
|
||||
if (Constr->Type == Equal) {
|
||||
double r1,r2,angle1,angle2;
|
||||
if (geo1->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
if (geo1->getTypeId() == Part::GeomCircle::getClassTypeId()) { // TODO: ellipse
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo1);
|
||||
r1 = circle->getRadius();
|
||||
angle1 = M_PI/4;
|
||||
@@ -3008,10 +3111,16 @@ Restart:
|
||||
arc->getRange(startangle, endangle);
|
||||
angle1 = (startangle + endangle)/2;
|
||||
midpos1 = arc->getCenter();
|
||||
} else if (geo1->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
// TODO: ellipse
|
||||
const Part::GeomEllipse *ellipse = dynamic_cast<const Part::GeomEllipse *>(geo1);
|
||||
r1 = ellipse->getMajorRadius();
|
||||
angle1 = -ellipse->getAngleXU();
|
||||
midpos1 = ellipse->getCenter();
|
||||
} else
|
||||
break;
|
||||
|
||||
if (geo2->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
if (geo2->getTypeId() == Part::GeomCircle::getClassTypeId()) { // TODO: ellipse
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo2);
|
||||
r2 = circle->getRadius();
|
||||
angle2 = M_PI/4;
|
||||
@@ -3023,7 +3132,14 @@ Restart:
|
||||
arc->getRange(startangle, endangle);
|
||||
angle2 = (startangle + endangle)/2;
|
||||
midpos2 = arc->getCenter();
|
||||
} else
|
||||
} else if (geo2->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
// TODO: ellipse
|
||||
const Part::GeomEllipse *ellipse = dynamic_cast<const Part::GeomEllipse *>(geo2);
|
||||
r2 = ellipse->getMajorRadius();
|
||||
angle2 = -ellipse->getAngleXU();
|
||||
midpos2 = ellipse->getCenter();
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
norm1 = Base::Vector3d(cos(angle1),sin(angle1),0);
|
||||
@@ -3196,7 +3312,7 @@ Restart:
|
||||
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo1);
|
||||
Base::Vector3d dir = (lineSeg->getEndPoint() - lineSeg->getStartPoint()).Normalize();
|
||||
Base::Vector3d norm(-dir.y, dir.x, 0);
|
||||
if (geo2->getTypeId()== Part::GeomCircle::getClassTypeId()) {
|
||||
if (geo2->getTypeId()== Part::GeomCircle::getClassTypeId()) { // TODO: ellipse
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo2);
|
||||
// tangency between a line and a circle
|
||||
float length = (circle->getCenter() - lineSeg->getStartPoint())*dir;
|
||||
@@ -3204,6 +3320,24 @@ Restart:
|
||||
pos = lineSeg->getStartPoint() + dir * length;
|
||||
relPos = norm * 1; //TODO Huh?
|
||||
}
|
||||
else if (geo2->getTypeId()== Part::GeomEllipse::getClassTypeId() ||
|
||||
geo2->getTypeId()== Part::GeomArcOfEllipse::getClassTypeId()) { // TODO: ellipse
|
||||
|
||||
Base::Vector3d center;
|
||||
if(geo2->getTypeId()== Part::GeomEllipse::getClassTypeId()){
|
||||
const Part::GeomEllipse *ellipse = dynamic_cast<const Part::GeomEllipse *>(geo2);
|
||||
center=ellipse->getCenter();
|
||||
} else {
|
||||
const Part::GeomArcOfEllipse *aoc = dynamic_cast<const Part::GeomArcOfEllipse *>(geo2);
|
||||
center=aoc->getCenter();
|
||||
}
|
||||
|
||||
// tangency between a line and an ellipse
|
||||
float length = (center - lineSeg->getStartPoint())*dir;
|
||||
|
||||
pos = lineSeg->getStartPoint() + dir * length;
|
||||
relPos = norm * 1;
|
||||
}
|
||||
else if (geo2->getTypeId()== Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geo2);
|
||||
// tangency between a line and an arc
|
||||
@@ -3214,7 +3348,7 @@ Restart:
|
||||
}
|
||||
}
|
||||
|
||||
if (geo1->getTypeId()== Part::GeomCircle::getClassTypeId() &&
|
||||
if (geo1->getTypeId()== Part::GeomCircle::getClassTypeId() && // TODO: ellipse
|
||||
geo2->getTypeId()== Part::GeomCircle::getClassTypeId()) {
|
||||
const Part::GeomCircle *circle1 = dynamic_cast<const Part::GeomCircle *>(geo1);
|
||||
const Part::GeomCircle *circle2 = dynamic_cast<const Part::GeomCircle *>(geo2);
|
||||
@@ -3223,12 +3357,12 @@ Restart:
|
||||
pos = circle1->getCenter() + dir * circle1->getRadius();
|
||||
relPos = dir * 1;
|
||||
}
|
||||
else if (geo2->getTypeId()== Part::GeomCircle::getClassTypeId()) {
|
||||
else if (geo2->getTypeId()== Part::GeomCircle::getClassTypeId()) { // TODO: ellipse
|
||||
std::swap(geo1,geo2);
|
||||
}
|
||||
|
||||
if (geo1->getTypeId()== Part::GeomCircle::getClassTypeId() &&
|
||||
geo2->getTypeId()== Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
geo2->getTypeId()== Part::GeomArcOfCircle::getClassTypeId()) { // TODO: ellipse
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo1);
|
||||
const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geo2);
|
||||
// tangency between a circle and an arc
|
||||
@@ -3368,7 +3502,7 @@ Restart:
|
||||
asciiText->pnts.finishEditing();
|
||||
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case Radius:
|
||||
{
|
||||
assert(Constr->First >= -extGeoCount && Constr->First < intGeoCount);
|
||||
@@ -3386,13 +3520,14 @@ Restart:
|
||||
pnt1 = arc->getCenter();
|
||||
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
|
||||
}
|
||||
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo);
|
||||
double radius = circle->getRadius();
|
||||
double angle = (double) Constr->LabelPosition;
|
||||
pnt1 = circle->getCenter();
|
||||
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
|
||||
} else
|
||||
}
|
||||
else
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
@@ -3584,6 +3719,12 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
|
||||
edit->vConstrType.push_back((*it)->Type);
|
||||
}
|
||||
break;
|
||||
case InternalAlignment:
|
||||
{
|
||||
// TODO: Implement visual representation (if any)
|
||||
edit->vConstrType.push_back((*it)->Type);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
edit->vConstrType.push_back(None);
|
||||
}
|
||||
|
||||
@@ -136,12 +136,16 @@ inline void SketcherAddWorkspaceArcs<Gui::MenuItem>(Gui::MenuItem& geom){
|
||||
geom << "Sketcher_CreateArc"
|
||||
<< "Sketcher_Create3PointArc"
|
||||
<< "Sketcher_CreateCircle"
|
||||
<< "Sketcher_Create3PointCircle";
|
||||
<< "Sketcher_Create3PointCircle"
|
||||
<< "Sketcher_CreateEllipse"
|
||||
<< "Sketcher_CreateArcOfEllipse";
|
||||
}
|
||||
template <>
|
||||
inline void SketcherAddWorkspaceArcs<Gui::ToolBarItem>(Gui::ToolBarItem& geom){
|
||||
geom << "Sketcher_CompCreateArc"
|
||||
<< "Sketcher_CompCreateCircle";
|
||||
<< "Sketcher_CompCreateCircle"
|
||||
<< "Sketcher_CreateEllipse"
|
||||
<< "Sketcher_CreateArcOfEllipse";
|
||||
}
|
||||
template <typename T>
|
||||
void SketcherAddWorkspaceRegularPolygon(T& geom);
|
||||
@@ -177,9 +181,32 @@ inline void SketcherAddWorkbenchGeometries(T& geom){
|
||||
/*<< "Sketcher_CreateDraftLine"*/;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline void SketcherAddWorkbenchConstraints(T& cons){
|
||||
inline void SketcherAddWorkbenchConstraints(T& cons);
|
||||
|
||||
template <>
|
||||
inline void SketcherAddWorkbenchConstraints<Gui::MenuItem>(Gui::MenuItem& cons){
|
||||
cons << "Sketcher_ConstrainCoincident"
|
||||
<< "Sketcher_ConstrainPointOnObject"
|
||||
<< "Sketcher_ConstrainVertical"
|
||||
<< "Sketcher_ConstrainHorizontal"
|
||||
<< "Sketcher_ConstrainParallel"
|
||||
<< "Sketcher_ConstrainPerpendicular"
|
||||
<< "Sketcher_ConstrainTangent"
|
||||
<< "Sketcher_ConstrainEqual"
|
||||
<< "Sketcher_ConstrainSymmetric"
|
||||
<< "Separator"
|
||||
<< "Sketcher_ConstrainLock"
|
||||
<< "Sketcher_ConstrainDistanceX"
|
||||
<< "Sketcher_ConstrainDistanceY"
|
||||
<< "Sketcher_ConstrainDistance"
|
||||
<< "Sketcher_ConstrainRadius"
|
||||
<< "Sketcher_ConstrainAngle"
|
||||
<< "Sketcher_ConstrainInternalAlignment";
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void SketcherAddWorkbenchConstraints<Gui::ToolBarItem>(Gui::ToolBarItem& cons){
|
||||
cons << "Sketcher_ConstrainCoincident"
|
||||
<< "Sketcher_ConstrainPointOnObject"
|
||||
<< "Sketcher_ConstrainVertical"
|
||||
@@ -196,7 +223,6 @@ inline void SketcherAddWorkbenchConstraints(T& cons){
|
||||
<< "Sketcher_ConstrainDistance"
|
||||
<< "Sketcher_ConstrainRadius"
|
||||
<< "Sketcher_ConstrainAngle";
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -212,13 +238,15 @@ inline void SketcherAddWorkbenchTools<Gui::MenuItem>(Gui::MenuItem& consaccel){
|
||||
<< "Sketcher_SelectHorizontalAxis"
|
||||
<< "Sketcher_SelectRedundantConstraints"
|
||||
<< "Sketcher_SelectConflictingConstraints"
|
||||
<< "Sketcher_SelectElementsAssociatedWithConstraints";
|
||||
<< "Sketcher_SelectElementsAssociatedWithConstraints"
|
||||
<< "Sketcher_RestoreInternalAlignmentGeometry";
|
||||
}
|
||||
template <>
|
||||
inline void SketcherAddWorkbenchTools<Gui::ToolBarItem>(Gui::ToolBarItem& consaccel){
|
||||
consaccel << "Sketcher_CloseShape"
|
||||
<< "Sketcher_ConnectLines"
|
||||
<< "Sketcher_SelectConstraints";
|
||||
<< "Sketcher_SelectConstraints"
|
||||
<< "Sketcher_RestoreInternalAlignmentGeometry";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
Reference in New Issue
Block a user