Merge branch 'master' of ssh://free-cad.git.sourceforge.net/gitroot/free-cad/free-cad
This commit is contained in:
commit
87bc9cbe74
|
@ -256,6 +256,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
|||
<< "Sketcher_ViewSketch"
|
||||
<< "Sketcher_MapSketch"
|
||||
<< "Separator"
|
||||
<< "Sketcher_CreatePoint"
|
||||
<< "Sketcher_CreateArc"
|
||||
<< "Sketcher_CreateCircle"
|
||||
<< "Sketcher_CreateLine"
|
||||
|
@ -484,6 +485,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
|||
<< "Sketcher_NewSketch"
|
||||
<< "Sketcher_LeaveSketch"
|
||||
<< "Separator"
|
||||
<< "Sketcher_CreatePoint"
|
||||
<< "Sketcher_CreateArc"
|
||||
<< "Sketcher_CreateCircle"
|
||||
<< "Sketcher_CreateLine"
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "TopoShapeCompSolidPy.h"
|
||||
#include "TopoShapeShellPy.h"
|
||||
#include "LinePy.h"
|
||||
#include "PointPy.h"
|
||||
#include "CirclePy.h"
|
||||
#include "EllipsePy.h"
|
||||
#include "ArcPy.h"
|
||||
|
@ -106,6 +107,7 @@ void PartExport initPart()
|
|||
Base::Interpreter().addType(&Part::TopoShapeShellPy ::Type,partModule,"Shell");
|
||||
|
||||
Base::Interpreter().addType(&Part::LinePy ::Type,partModule,"Line");
|
||||
Base::Interpreter().addType(&Part::PointPy ::Type,partModule,"Point");
|
||||
Base::Interpreter().addType(&Part::CirclePy ::Type,partModule,"Circle");
|
||||
Base::Interpreter().addType(&Part::EllipsePy ::Type,partModule,"Ellipse");
|
||||
Base::Interpreter().addType(&Part::HyperbolaPy ::Type,partModule,"Hyperbola");
|
||||
|
|
|
@ -34,6 +34,7 @@ generate_from_xml(GeometryPy)
|
|||
generate_from_xml(GeometryCurvePy)
|
||||
generate_from_xml(GeometrySurfacePy)
|
||||
generate_from_xml(LinePy)
|
||||
generate_from_xml(PointPy)
|
||||
generate_from_xml(BezierCurvePy)
|
||||
generate_from_xml(BSplineCurvePy)
|
||||
generate_from_xml(PlanePy)
|
||||
|
@ -154,6 +155,8 @@ SET(Python_SRCS
|
|||
GeometrySurfacePyImp.cpp
|
||||
LinePy.xml
|
||||
LinePyImp.cpp
|
||||
PointPy.xml
|
||||
PointPyImp.cpp
|
||||
BezierCurvePy.xml
|
||||
BezierCurvePyImp.cpp
|
||||
BSplineCurvePy.xml
|
||||
|
|
|
@ -53,8 +53,8 @@ std::string LinePy::representation(void) const
|
|||
Base::Vector3d start = getGeomLineSegmentPtr()->getStartPoint();
|
||||
Base::Vector3d end = getGeomLineSegmentPtr()->getEndPoint();
|
||||
str << "<Line ("
|
||||
<< start.x << ";" <<start.y << "," <<start.z << ") ("
|
||||
<< end.x << ";" <<end.y << "," <<end.z << ") >";
|
||||
<< start.x << "," <<start.y << "," <<start.z << ") ("
|
||||
<< end.x << "," <<end.y << "," <<end.z << ") >";
|
||||
//}
|
||||
|
||||
return str.str();
|
||||
|
|
|
@ -14,6 +14,7 @@ BUILT_SOURCES=\
|
|||
GeometryCurvePy.cpp \
|
||||
GeometrySurfacePy.cpp \
|
||||
LinePy.cpp \
|
||||
PointPy.cpp \
|
||||
BezierCurvePy.cpp \
|
||||
BSplineCurvePy.cpp \
|
||||
PlanePy.cpp \
|
||||
|
@ -53,6 +54,7 @@ libPart_la_BUILT=\
|
|||
GeometryCurvePy.h \
|
||||
GeometrySurfacePy.h \
|
||||
LinePy.h \
|
||||
PointPy.h \
|
||||
BezierCurvePy.h \
|
||||
BSplineCurvePy.h \
|
||||
PlanePy.h \
|
||||
|
@ -94,6 +96,7 @@ libPart_la_SOURCES=\
|
|||
GeometryCurvePyImp.cpp \
|
||||
GeometrySurfacePyImp.cpp \
|
||||
LinePyImp.cpp \
|
||||
PointPyImp.cpp \
|
||||
BezierCurvePyImp.cpp \
|
||||
BSplineCurvePyImp.cpp \
|
||||
PlanePyImp.cpp \
|
||||
|
@ -273,6 +276,7 @@ EXTRA_DIST = \
|
|||
GeometryCurvePy.xml \
|
||||
GeometrySurfacePy.xml \
|
||||
LinePy.xml \
|
||||
PointPy.xml \
|
||||
BezierCurvePy.xml \
|
||||
BSplineCurvePy.xml \
|
||||
PlanePy.xml \
|
||||
|
|
45
src/Mod/Part/App/PointPy.xml
Normal file
45
src/Mod/Part/App/PointPy.xml
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="GeometryPy"
|
||||
Name="PointPy"
|
||||
Twin="GeomPoint"
|
||||
TwinPointer="GeomPoint"
|
||||
Include="Mod/Part/App/Geometry.h"
|
||||
Namespace="Part"
|
||||
FatherInclude="Mod/Part/App/GeometryPy.h"
|
||||
FatherNamespace="Part"
|
||||
Constructor="true">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer@users.sourceforge.net" />
|
||||
<UserDocu>Describes a point
|
||||
To create a point there are several ways:
|
||||
Part.Point()
|
||||
Creates a default point
|
||||
|
||||
Part.Point(Point)
|
||||
Creates a copy of the given point
|
||||
|
||||
Part.Point(Vector)
|
||||
Creates a line for the given coordinates</UserDocu>
|
||||
</Documentation>
|
||||
<Attribute Name="X" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>X component of this point.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="X" Type="Float"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Y" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Y component of this point.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Y" Type="Float"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Z" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Z component of this point.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Z" Type="Float"/>
|
||||
</Attribute>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
174
src/Mod/Part/App/PointPyImp.cpp
Normal file
174
src/Mod/Part/App/PointPyImp.cpp
Normal file
|
@ -0,0 +1,174 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2012 Konstantinos Poulios <logari81[at]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.hxx>
|
||||
# include <Geom_CartesianPoint.hxx>
|
||||
# include <GC_MakeLine.hxx>
|
||||
# include <GC_MakeSegment.hxx>
|
||||
# include <Precision.hxx>
|
||||
#endif
|
||||
|
||||
#include <Base/VectorPy.h>
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
|
||||
#include "Geometry.h"
|
||||
#include "PointPy.h"
|
||||
#include "PointPy.cpp"
|
||||
|
||||
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 PointPy::representation(void) const
|
||||
{
|
||||
std::stringstream str;
|
||||
Base::Vector3d coords = getGeomPointPtr()->getPoint();
|
||||
str << "<Point (" << coords.x << "," << coords.y << "," << coords.z << ") >";
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *PointPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
{
|
||||
// create a new instance of PointPy and the Twin object
|
||||
return new PointPy(new GeomPoint);
|
||||
}
|
||||
|
||||
// constructor method
|
||||
int PointPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
{
|
||||
|
||||
if (PyArg_ParseTuple(args, "")) {
|
||||
// default point
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
PyObject *pPoint;
|
||||
if (PyArg_ParseTuple(args, "O!", &(PointPy::Type), &pPoint)) {
|
||||
// Copy point
|
||||
PointPy* pcPoint = static_cast<PointPy*>(pPoint);
|
||||
// get Geom_CartesianPoint of that point
|
||||
Handle_Geom_CartesianPoint that_point = Handle_Geom_CartesianPoint::DownCast
|
||||
(pcPoint->getGeomPointPtr()->handle());
|
||||
// get Geom_CartesianPoint of this point
|
||||
Handle_Geom_CartesianPoint this_point = Handle_Geom_CartesianPoint::DownCast
|
||||
(this->getGeomPointPtr()->handle());
|
||||
|
||||
// Assign the coordinates
|
||||
this_point->SetPnt(that_point->Pnt());
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
PyObject *pV;
|
||||
if (PyArg_ParseTuple(args, "O!", &(Base::VectorPy::Type), &pV)) {
|
||||
Base::Vector3d v = static_cast<Base::VectorPy*>(pV)->value();
|
||||
Handle_Geom_CartesianPoint this_point = Handle_Geom_CartesianPoint::DownCast
|
||||
(this->getGeomPointPtr()->handle());
|
||||
this_point->SetCoord(v.x,v.y,v.z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "Point constructor accepts:\n"
|
||||
"-- empty parameter list\n"
|
||||
"-- Point\n"
|
||||
"-- Coordinates vector");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py::Float PointPy::getX(void) const
|
||||
{
|
||||
Handle_Geom_CartesianPoint this_point = Handle_Geom_CartesianPoint::DownCast
|
||||
(this->getGeomPointPtr()->handle());
|
||||
return Py::Float(this_point->X());
|
||||
}
|
||||
|
||||
void PointPy::setX(Py::Float X)
|
||||
{
|
||||
Handle_Geom_CartesianPoint this_point = Handle_Geom_CartesianPoint::DownCast
|
||||
(this->getGeomPointPtr()->handle());
|
||||
|
||||
try {
|
||||
this_point->SetX(double(X));
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Py::Exception(e->GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
Py::Float PointPy::getY(void) const
|
||||
{
|
||||
Handle_Geom_CartesianPoint this_point = Handle_Geom_CartesianPoint::DownCast
|
||||
(this->getGeomPointPtr()->handle());
|
||||
return Py::Float(this_point->Y());
|
||||
}
|
||||
|
||||
void PointPy::setY(Py::Float Y)
|
||||
{
|
||||
Handle_Geom_CartesianPoint this_point = Handle_Geom_CartesianPoint::DownCast
|
||||
(this->getGeomPointPtr()->handle());
|
||||
|
||||
try {
|
||||
this_point->SetY(double(Y));
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Py::Exception(e->GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
Py::Float PointPy::getZ(void) const
|
||||
{
|
||||
Handle_Geom_CartesianPoint this_point = Handle_Geom_CartesianPoint::DownCast
|
||||
(this->getGeomPointPtr()->handle());
|
||||
return Py::Float(this_point->Z());
|
||||
}
|
||||
|
||||
void PointPy::setZ(Py::Float Z)
|
||||
{
|
||||
Handle_Geom_CartesianPoint this_point = Handle_Geom_CartesianPoint::DownCast
|
||||
(this->getGeomPointPtr()->handle());
|
||||
|
||||
try {
|
||||
this_point->SetZ(double(Z));
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Py::Exception(e->GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyObject *PointPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PointPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -125,7 +125,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
|||
|
||||
Gui::MenuItem* geom = new Gui::MenuItem();
|
||||
geom->setCommand("Sketcher geometries");
|
||||
*geom /*<< "Sketcher_CreatePoint"*/
|
||||
*geom << "Sketcher_CreatePoint"
|
||||
<< "Sketcher_CreateArc"
|
||||
<< "Sketcher_CreateCircle"
|
||||
<< "Sketcher_CreateLine"
|
||||
|
@ -194,7 +194,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
|||
|
||||
part = new Gui::ToolBarItem(root);
|
||||
part->setCommand("Sketcher geometries");
|
||||
*part /*<< "Sketcher_CreatePoint" */
|
||||
*part << "Sketcher_CreatePoint"
|
||||
<< "Sketcher_CreateArc"
|
||||
<< "Sketcher_CreateCircle"
|
||||
<< "Sketcher_CreateLine"
|
||||
|
|
|
@ -150,7 +150,11 @@ const char* nameByType(Sketch::GeoType type)
|
|||
|
||||
int Sketch::addGeometry(const Part::Geometry *geo, bool fixed)
|
||||
{
|
||||
if (geo->getTypeId() == GeomLineSegment::getClassTypeId()) { // add a line
|
||||
if (geo->getTypeId() == GeomPoint::getClassTypeId()) { // add a point
|
||||
const GeomPoint *point = dynamic_cast<const GeomPoint*>(geo);
|
||||
// create the definition struct for that geom
|
||||
return addPoint(*point, fixed);
|
||||
} else if (geo->getTypeId() == GeomLineSegment::getClassTypeId()) { // add a line
|
||||
const GeomLineSegment *lineSeg = dynamic_cast<const GeomLineSegment*>(geo);
|
||||
// create the definition struct for that geom
|
||||
return addLineSegment(*lineSeg, fixed);
|
||||
|
@ -174,24 +178,30 @@ void Sketch::addGeometry(const std::vector<Part::Geometry *> &geo, bool fixed)
|
|||
addGeometry(*it, fixed);
|
||||
}
|
||||
|
||||
int Sketch::addPoint(const Base::Vector3d &newPoint, bool fixed)
|
||||
int Sketch::addPoint(const Part::GeomPoint &point, bool fixed)
|
||||
{
|
||||
std::vector<double *> ¶ms = fixed ? FixParameters : Parameters;
|
||||
|
||||
// create our own copy
|
||||
GeomPoint *p = static_cast<GeomPoint*>(point.clone());
|
||||
// points in a sketch are always construction elements
|
||||
p->Construction = true;
|
||||
// create the definition struct for that geom
|
||||
GeoDef def;
|
||||
def.geo = 0;
|
||||
def.geo = p;
|
||||
def.type = Point;
|
||||
|
||||
// set the parameter for the solver
|
||||
params.push_back(new double(newPoint.x));
|
||||
params.push_back(new double(newPoint.y));
|
||||
params.push_back(new double(p->getPoint().x));
|
||||
params.push_back(new double(p->getPoint().y));
|
||||
|
||||
// set the points for later constraints
|
||||
GCS::Point p1;
|
||||
p1.x = params[params.size()-2];
|
||||
p1.y = params[params.size()-1];
|
||||
def.startPointId = Points.size();
|
||||
def.endPointId = Points.size();
|
||||
def.midPointId = Points.size();
|
||||
Points.push_back(p1);
|
||||
|
||||
// store complete set
|
||||
|
@ -393,7 +403,10 @@ Py::Tuple Sketch::getPyGeometry(void) const
|
|||
Py::Tuple tuple(Geoms.size());
|
||||
int i=0;
|
||||
for (std::vector<GeoDef>::const_iterator it=Geoms.begin(); it != Geoms.end(); ++it, i++) {
|
||||
if (it->type == Line) {
|
||||
if (it->type == Point) {
|
||||
Base::Vector3d temp(*(Points[it->startPointId].x),*(Points[it->startPointId].y),0);
|
||||
tuple[i] = Py::asObject(new VectorPy(temp));
|
||||
} else if (it->type == Line) {
|
||||
GeomLineSegment *lineSeg = dynamic_cast<GeomLineSegment*>(it->geo->clone());
|
||||
tuple[i] = Py::asObject(new LinePy(lineSeg));
|
||||
} else if (it->type == Arc) {
|
||||
|
@ -402,9 +415,6 @@ Py::Tuple Sketch::getPyGeometry(void) const
|
|||
} else if (it->type == Circle) {
|
||||
GeomCircle *circle = dynamic_cast<GeomCircle*>(it->geo->clone());
|
||||
tuple[i] = Py::asObject(new CirclePy(circle));
|
||||
} else if (it->type == Point) {
|
||||
Base::Vector3d temp(*(Points[Geoms[i].startPointId].x),*(Points[Geoms[i].startPointId].y),0);
|
||||
tuple[i] = Py::asObject(new VectorPy(temp));
|
||||
} else if (it->type == Ellipse) {
|
||||
GeomEllipse *ellipse = dynamic_cast<GeomEllipse*>(it->geo->clone());
|
||||
tuple[i] = Py::asObject(new EllipsePy(ellipse));
|
||||
|
@ -1517,7 +1527,13 @@ bool Sketch::updateGeometry()
|
|||
int i=0;
|
||||
for (std::vector<GeoDef>::const_iterator it=Geoms.begin(); it != Geoms.end(); ++it, i++) {
|
||||
try {
|
||||
if (it->type == Line) {
|
||||
if (it->type == Point) {
|
||||
GeomPoint *point = dynamic_cast<GeomPoint*>(it->geo);
|
||||
point->setPoint(Vector3d(*Points[it->startPointId].x,
|
||||
*Points[it->startPointId].y,
|
||||
0.0)
|
||||
);
|
||||
} else if (it->type == Line) {
|
||||
GeomLineSegment *lineSeg = dynamic_cast<GeomLineSegment*>(it->geo);
|
||||
lineSeg->setPoints(Vector3d(*Lines[it->index].p1.x,
|
||||
*Lines[it->index].p1.y,
|
||||
|
@ -1653,7 +1669,18 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (Geoms[geoId].type == Line) {
|
||||
if (Geoms[geoId].type == Point) {
|
||||
if (pos == start) {
|
||||
GCS::Point &point = Points[Geoms[geoId].startPointId];
|
||||
GCS::Point p0;
|
||||
MoveParameters.resize(2); // px,py
|
||||
p0.x = &MoveParameters[0];
|
||||
p0.y = &MoveParameters[1];
|
||||
*p0.x = *point.x;
|
||||
*p0.y = *point.y;
|
||||
GCSsys.addConstraintP2PCoincident(p0,point,-1);
|
||||
}
|
||||
} else if (Geoms[geoId].type == Line) {
|
||||
if (pos == start || pos == end) {
|
||||
MoveParameters.resize(2); // x,y
|
||||
GCS::Point p0;
|
||||
|
@ -1771,6 +1798,11 @@ int Sketch::movePoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool rela
|
|||
MoveParameters[i] = InitParameters[i] + toPoint.x;
|
||||
MoveParameters[i+1] = InitParameters[i+1] + toPoint.y;
|
||||
}
|
||||
} else if (Geoms[geoId].type == Point) {
|
||||
if (pos == start) {
|
||||
MoveParameters[0] = toPoint.x;
|
||||
MoveParameters[1] = toPoint.y;
|
||||
}
|
||||
} else if (Geoms[geoId].type == Line) {
|
||||
if (pos == start || pos == end) {
|
||||
MoveParameters[0] = toPoint.x;
|
||||
|
|
|
@ -108,7 +108,7 @@ public:
|
|||
/// add dedicated geometry
|
||||
//@{
|
||||
/// add a point
|
||||
int addPoint(const Base::Vector3d &point, bool fixed=false);
|
||||
int addPoint(const Part::GeomPoint &point, bool fixed=false);
|
||||
/// add an infinite line
|
||||
int addLine(const Part::GeomLineSegment &line, bool fixed=false);
|
||||
/// add a line segment
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
# include <gp_Circ.hxx>
|
||||
# include <BRepAdaptor_Surface.hxx>
|
||||
# include <BRepAdaptor_Curve.hxx>
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <Geom_Plane.hxx>
|
||||
# include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
# include <BRepOffsetAPI_NormalProjection.hxx>
|
||||
|
@ -75,6 +76,7 @@ SketchObject::SketchObject()
|
|||
VLine->Construction = true;
|
||||
ExternalGeo.push_back(HLine);
|
||||
ExternalGeo.push_back(VLine);
|
||||
rebuildVertexIndex();
|
||||
}
|
||||
|
||||
SketchObject::~SketchObject()
|
||||
|
@ -1225,15 +1227,17 @@ void SketchObject::rebuildExternalGeometry(void)
|
|||
invPlm.multVec(p2,p2);
|
||||
|
||||
if (Base::Distance(p1,p2) < Precision::Confusion()) {
|
||||
std::string msg = SubElement + " perpendicular to the sketch plane cannot be used as external geometry";
|
||||
throw Base::Exception(msg.c_str());
|
||||
Base::Vector3d p = (p1 + p2) / 2;
|
||||
Part::GeomPoint* point = new Part::GeomPoint(p);
|
||||
point->Construction = true;
|
||||
ExternalGeo.push_back(point);
|
||||
}
|
||||
else {
|
||||
Part::GeomLineSegment* line = new Part::GeomLineSegment();
|
||||
line->setPoints(p1,p2);
|
||||
line->Construction = true;
|
||||
ExternalGeo.push_back(line);
|
||||
}
|
||||
|
||||
Part::GeomLineSegment* line = new Part::GeomLineSegment();
|
||||
line->setPoints(p1,p2);
|
||||
|
||||
line->Construction = true;
|
||||
ExternalGeo.push_back(line);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
|
@ -1255,15 +1259,17 @@ void SketchObject::rebuildExternalGeometry(void)
|
|||
Base::Vector3d p2(P2.X(),P2.Y(),P2.Z());
|
||||
|
||||
if (Base::Distance(p1,p2) < Precision::Confusion()) {
|
||||
std::string msg = SubElement + " perpendicular to the sketch plane cannot be used as external geometry";
|
||||
throw Base::Exception(msg.c_str());
|
||||
Base::Vector3d p = (p1 + p2) / 2;
|
||||
Part::GeomPoint* point = new Part::GeomPoint(p);
|
||||
point->Construction = true;
|
||||
ExternalGeo.push_back(point);
|
||||
}
|
||||
else {
|
||||
Part::GeomLineSegment* line = new Part::GeomLineSegment();
|
||||
line->setPoints(p1,p2);
|
||||
line->Construction = true;
|
||||
ExternalGeo.push_back(line);
|
||||
}
|
||||
|
||||
Part::GeomLineSegment* line = new Part::GeomLineSegment();
|
||||
line->setPoints(p1,p2);
|
||||
|
||||
line->Construction = true;
|
||||
ExternalGeo.push_back(line);
|
||||
}
|
||||
else if (curve.GetType() == GeomAbs_Circle) {
|
||||
gp_Circ c = curve.Circle();
|
||||
|
@ -1303,7 +1309,12 @@ void SketchObject::rebuildExternalGeometry(void)
|
|||
}
|
||||
break;
|
||||
case TopAbs_VERTEX:
|
||||
throw Base::Exception("Vertices cannot be used as external geometry for sketches");
|
||||
{
|
||||
gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(refSubShape));
|
||||
Part::GeomPoint* point = new Part::GeomPoint(Base::Vector3d(p.X(),p.Y(),p.Z()));
|
||||
point->Construction = true;
|
||||
ExternalGeo.push_back(point);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw Base::Exception("Unknown type of geometry");
|
||||
|
@ -1326,9 +1337,14 @@ void SketchObject::rebuildVertexIndex(void)
|
|||
int imax=getHighestCurveIndex();
|
||||
int i=0;
|
||||
const std::vector< Part::Geometry * > geometry = getCompleteGeometry();
|
||||
if (geometry.size() <= 2)
|
||||
return;
|
||||
for (std::vector< Part::Geometry * >::const_iterator it = geometry.begin();
|
||||
it != geometry.end(); ++it) {
|
||||
if ((*it)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
it != geometry.end()-2; ++it) {
|
||||
if ((*it)->getTypeId() == Part::GeomPoint::getClassTypeId()) {
|
||||
VertexId2GeoId.push_back(i);
|
||||
VertexId2PosId.push_back(start);
|
||||
} else if ((*it)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
VertexId2GeoId.push_back(i);
|
||||
VertexId2PosId.push_back(start);
|
||||
VertexId2GeoId.push_back(i);
|
||||
|
|
|
@ -488,8 +488,10 @@ class DrawSketchHandlerLineSet: public DrawSketchHandler
|
|||
{
|
||||
public:
|
||||
DrawSketchHandlerLineSet()
|
||||
: Mode(STATUS_SEEK_First),EditCurve(2),firstPoint(-1),previousCurve(-1){}
|
||||
virtual ~DrawSketchHandlerLineSet(){}
|
||||
: Mode(STATUS_SEEK_First),LineMode(LINE_MODE_Line),EditCurve(2),
|
||||
firstVertex(-1),firstCurve(-1),previousCurve(-1),previousPosId(-1),
|
||||
isTangent(false) {}
|
||||
virtual ~DrawSketchHandlerLineSet() {}
|
||||
/// mode table
|
||||
enum SelectMode {
|
||||
STATUS_SEEK_First, /**< enum value ----. */
|
||||
|
@ -498,6 +500,41 @@ public:
|
|||
STATUS_Close
|
||||
};
|
||||
|
||||
enum SelectLineMode
|
||||
{
|
||||
LINE_MODE_Arc,
|
||||
LINE_MODE_Line
|
||||
};
|
||||
|
||||
virtual void registerPressedKey(bool pressed, int key)
|
||||
{
|
||||
if (key == SoKeyboardEvent::A && pressed && previousCurve != -1) {
|
||||
if (LineMode != LINE_MODE_Arc) {
|
||||
Base::Vector2D onSketchPos = EditCurve[isTangent ? 2 : 1];
|
||||
LineMode = LINE_MODE_Arc;
|
||||
if (previousCurve != -1)
|
||||
isTangent = true;
|
||||
else
|
||||
isTangent = false;
|
||||
EditCurve.resize(32);
|
||||
mouseMove(onSketchPos); // trigger an update of EditCurve
|
||||
}
|
||||
else {
|
||||
Base::Vector2D onSketchPos = EditCurve[29];
|
||||
LineMode = LINE_MODE_Line;
|
||||
if (previousCurve != -1) {
|
||||
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(previousCurve);
|
||||
if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
|
||||
isTangent = true;
|
||||
else
|
||||
isTangent = false;
|
||||
}
|
||||
EditCurve.resize(isTangent ? 3 : 2);
|
||||
mouseMove(onSketchPos); // trigger an update of EditCurve
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void activated(ViewProviderSketch *sketchgui)
|
||||
{
|
||||
setCursor(QPixmap(cursor_createlineset),7,7);
|
||||
|
@ -513,11 +550,71 @@ public:
|
|||
}
|
||||
}
|
||||
else if (Mode==STATUS_SEEK_Second){
|
||||
EditCurve[1] = onSketchPos;
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - EditCurve[0])) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
if (LineMode == LINE_MODE_Line) {
|
||||
EditCurve[isTangent ? 2 : 1] = onSketchPos;
|
||||
if (isTangent) {
|
||||
Base::Vector2D Tangent(dirVec.x,dirVec.y);
|
||||
EditCurve[1].ProjToLine(EditCurve[2] - EditCurve[0], Tangent);
|
||||
EditCurve[1] = EditCurve[0] + EditCurve[1];
|
||||
}
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (!isTangent) {
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - EditCurve[0])) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (LineMode == LINE_MODE_Arc) {
|
||||
Base::Vector2D Tangent(dirVec.x,dirVec.y);
|
||||
float theta = Tangent.GetAngle(onSketchPos - EditCurve[0]);
|
||||
arcRadius = (onSketchPos - EditCurve[0]).Length()/(2.0*sin(theta));
|
||||
// At this point we need a unit normal vector pointing torwards
|
||||
// the center of the arc we are drawing. Derivation of the formula
|
||||
// used here can be found at http://people.richland.edu/james/lecture/m116/matrices/area.html
|
||||
float x1 = EditCurve[0].fX;
|
||||
float y1 = EditCurve[0].fY;
|
||||
float x2 = x1 + Tangent.fX;
|
||||
float y2 = y1 + Tangent.fY;
|
||||
float x3 = onSketchPos.fX;
|
||||
float y3 = onSketchPos.fY;
|
||||
if ((x2*y3-x3*y2)-(x1*y3-x3*y1)+(x1*y2-x2*y1) > 0)
|
||||
arcRadius *= -1;
|
||||
|
||||
Base::Vector3d centerVec = dirVec % Base::Vector3d(0.f,0.f,1.0);
|
||||
centerVec.Normalize(); // this step should actually be redundant
|
||||
|
||||
CenterPoint = EditCurve[0] + Base::Vector2D(arcRadius * centerVec.x, arcRadius * centerVec.y);
|
||||
|
||||
float rx = EditCurve[0].fX - CenterPoint.fX;
|
||||
float ry = EditCurve[0].fY - CenterPoint.fY;
|
||||
|
||||
startAngle = atan2(ry,rx);
|
||||
|
||||
float rxe = onSketchPos.fX - CenterPoint.fX;
|
||||
float rye = onSketchPos.fY - CenterPoint.fY;
|
||||
float arcAngle = atan2(-rxe*ry + rye*rx, rxe*rx + rye*ry);
|
||||
if (arcRadius >= 0 && arcAngle > 0)
|
||||
arcAngle -= 2*M_PI;
|
||||
if (arcRadius < 0 && arcAngle < 0)
|
||||
arcAngle += 2*M_PI;
|
||||
endAngle = startAngle + arcAngle;
|
||||
|
||||
for (int i=1; i <= 29; i++) {
|
||||
float angle = i*arcAngle/29.0;
|
||||
float dx = rx * cos(angle) - ry * sin(angle);
|
||||
float dy = rx * sin(angle) + ry * cos(angle);
|
||||
EditCurve[i] = Base::Vector2D(CenterPoint.fX + dx, CenterPoint.fY + dy);
|
||||
}
|
||||
|
||||
EditCurve[30] = CenterPoint;
|
||||
EditCurve[31] = EditCurve[0];
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2D(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
applyCursor();
|
||||
|
@ -527,24 +624,42 @@ public:
|
|||
{
|
||||
if (Mode==STATUS_SEEK_First) {
|
||||
// remember our first point
|
||||
firstPoint = getHighestVertexIndex() + 1;
|
||||
firstVertex = getHighestVertexIndex() + 1;
|
||||
firstCurve = getHighestCurveIndex() + 1;
|
||||
// TODO: here we should check if there is a preselected point
|
||||
// and set up a transition from the neighbouring segment.
|
||||
// (peviousCurve, previousPosId, dirVec, isTangent)
|
||||
// in that case we should set firstCurve and firstVertex to -1
|
||||
// in order to disable closing the wire
|
||||
if (LineMode == LINE_MODE_Line)
|
||||
EditCurve.resize(isTangent ? 3 : 2);
|
||||
else if (LineMode == LINE_MODE_Arc)
|
||||
EditCurve.resize(32);
|
||||
EditCurve[0] = onSketchPos;
|
||||
Mode = STATUS_SEEK_Second;
|
||||
}
|
||||
else if (Mode==STATUS_SEEK_Second) {
|
||||
EditCurve[1] = onSketchPos;
|
||||
if (LineMode == LINE_MODE_Line) {
|
||||
EditCurve[isTangent ? 2 : 1] = onSketchPos;
|
||||
if (isTangent) {
|
||||
Base::Vector2D Tangent(dirVec.x,dirVec.y);
|
||||
EditCurve[1].ProjToLine(EditCurve[2] - EditCurve[0], Tangent);
|
||||
EditCurve[1] = EditCurve[0] + EditCurve[1];
|
||||
}
|
||||
}
|
||||
else if (LineMode == LINE_MODE_Arc)
|
||||
EditCurve[29] = onSketchPos; // not so important
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
applyCursor();
|
||||
// exit on clicking exactly at the same position (e.g. double click)
|
||||
if (EditCurve[1] == EditCurve[0]) {
|
||||
if (onSketchPos == EditCurve[0]) {
|
||||
unsetCursor();
|
||||
EditCurve.clear();
|
||||
resetPositionText();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
|
||||
}
|
||||
if (sketchgui->getPreselectPoint() == firstPoint)
|
||||
if (sketchgui->getPreselectPoint() == firstVertex)
|
||||
Mode = STATUS_Close;
|
||||
else
|
||||
Mode = STATUS_Do;
|
||||
|
@ -554,32 +669,53 @@ public:
|
|||
|
||||
virtual bool releaseButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_Do || Mode==STATUS_Close) {
|
||||
// open the transaction
|
||||
Gui::Command::openCommand("add sketch wire");
|
||||
// issue the geometry
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
EditCurve[0].fX,EditCurve[0].fY,EditCurve[1].fX,EditCurve[1].fY);
|
||||
if (Mode == STATUS_Do || Mode == STATUS_Close) {
|
||||
|
||||
if (LineMode == LINE_MODE_Line) {
|
||||
// open the transaction
|
||||
Gui::Command::openCommand("Add line to sketch wire");
|
||||
// issue the geometry
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
EditCurve[0].fX,EditCurve[0].fY,EditCurve[1].fX,EditCurve[1].fY);
|
||||
}
|
||||
else if (LineMode == LINE_MODE_Arc) { // We're dealing with an Arc
|
||||
Gui::Command::openCommand("Add arc to sketch wire");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.addGeometry(Part.ArcOfCircle"
|
||||
"(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),%f),%f,%f))",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
CenterPoint.fX, CenterPoint.fY, std::abs(arcRadius),
|
||||
std::min(startAngle,endAngle), std::max(startAngle,endAngle));
|
||||
}
|
||||
// issue the constraint
|
||||
if (previousCurve != -1) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,2,%i,1)) "
|
||||
,sketchgui->getObject()->getNameInDocument()
|
||||
,previousCurve-1,previousCurve
|
||||
);
|
||||
}
|
||||
|
||||
if (Mode==STATUS_Close) {
|
||||
// close the loop by constrain to the first curve point
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,2,%i,1)) "
|
||||
,sketchgui->getObject()->getNameInDocument()
|
||||
,previousCurve,firstCurve
|
||||
);
|
||||
|
||||
int lastCurve = previousCurve+1;
|
||||
int lastStartPosId = (LineMode == LINE_MODE_Arc && startAngle > endAngle) ? 2 : 1;
|
||||
int lastEndPosId = (LineMode == LINE_MODE_Arc && startAngle > endAngle) ? 1 : 2;
|
||||
// in case of a tangency constraint, the coincident constraint is redundant
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('%s',%i,%i,%i,%i)) ",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
isTangent ? "Tangent" : "Coincident",
|
||||
previousCurve, previousPosId /* == 2 */, lastCurve, lastStartPosId);
|
||||
if (Mode == STATUS_Close) {
|
||||
int firstGeoId;
|
||||
Sketcher::PointPos firstPosId;
|
||||
sketchgui->getSketchObject()->getGeoVertexIndex(firstVertex, firstGeoId, firstPosId);
|
||||
//assert(firstCurve == firstGeoId);
|
||||
// close the loop by constrain to the first curve point
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Coincident',%i,%i,%i,%i)) ",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
lastCurve,lastEndPosId,firstCurve,firstPosId);
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::updateActive();
|
||||
}
|
||||
|
||||
if (Mode == STATUS_Close) {
|
||||
if (sugConstr2.size() > 0) {
|
||||
// exclude any coincidence constraints
|
||||
std::vector<AutoConstraint> sugConstr;
|
||||
|
@ -602,7 +738,7 @@ public:
|
|||
Gui::Command::updateActive();
|
||||
|
||||
// Add auto constraints
|
||||
if (sugConstr1.size() > 0) {
|
||||
if (sugConstr1.size() > 0) { // this is relevant only to the very first point
|
||||
createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::start);
|
||||
sugConstr1.clear();
|
||||
}
|
||||
|
@ -612,35 +748,63 @@ public:
|
|||
sugConstr2.clear();
|
||||
}
|
||||
|
||||
//remember the vertex for the next rounds constraint...
|
||||
previousCurve = getHighestCurveIndex() + 1;
|
||||
// remember the vertex for the next rounds constraint..
|
||||
previousCurve = getHighestCurveIndex();
|
||||
previousPosId = (LineMode == LINE_MODE_Arc && startAngle > endAngle) ? 1 : 2;
|
||||
|
||||
// setup for the next line segment
|
||||
// Use updated endPoint as autoconstraints can modify the position
|
||||
// Need to determine if the previous element was a line or an arc or ???
|
||||
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(getHighestCurveIndex());
|
||||
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geom);
|
||||
EditCurve[0] = Base::Vector2D(lineSeg->getEndPoint().x, lineSeg->getEndPoint().y);
|
||||
dirVec.Set(lineSeg->getEndPoint().x - lineSeg->getStartPoint().x,
|
||||
lineSeg->getEndPoint().y - lineSeg->getStartPoint().y,
|
||||
0.f);
|
||||
}
|
||||
else
|
||||
EditCurve[0] = onSketchPos;
|
||||
else if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
assert(LineMode == LINE_MODE_Arc);
|
||||
const Part::GeomArcOfCircle *arcSeg = dynamic_cast<const Part::GeomArcOfCircle *>(geom);
|
||||
if (startAngle > endAngle) {
|
||||
EditCurve[0] = Base::Vector2D(arcSeg->getStartPoint().x,arcSeg->getStartPoint().y);
|
||||
dirVec = Base::Vector3d(0.f,0.f,-1.0) % (arcSeg->getStartPoint()-arcSeg->getCenter());
|
||||
}
|
||||
else { // cw arcs are rendered in reverse
|
||||
EditCurve[0] = Base::Vector2D(arcSeg->getEndPoint().x,arcSeg->getEndPoint().y);
|
||||
dirVec = Base::Vector3d(0.f,0.f,1.0) % (arcSeg->getEndPoint()-arcSeg->getCenter());
|
||||
}
|
||||
}
|
||||
dirVec.Normalize();
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
applyCursor();
|
||||
|
||||
Mode = STATUS_SEEK_Second;
|
||||
isTangent = (LineMode == LINE_MODE_Arc);
|
||||
LineMode = LINE_MODE_Line;
|
||||
EditCurve.resize(isTangent ? 3 : 2);
|
||||
EditCurve[1] = EditCurve[0];
|
||||
if (isTangent)
|
||||
EditCurve[2] = EditCurve[0];
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
SelectMode Mode;
|
||||
SelectLineMode LineMode;
|
||||
|
||||
std::vector<Base::Vector2D> EditCurve;
|
||||
Base::Vector2D lastPos;
|
||||
int firstPoint;
|
||||
int firstVertex;
|
||||
int firstCurve;
|
||||
int previousPosId;
|
||||
int previousCurve;
|
||||
std::vector<AutoConstraint> sugConstr1, sugConstr2;
|
||||
|
||||
Base::Vector2D CenterPoint;
|
||||
Base::Vector3d dirVec;
|
||||
bool isTangent;
|
||||
float startAngle, endAngle, arcRadius;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1086,6 +1250,102 @@ bool CmdSketcherCreateCircle::isActive(void)
|
|||
|
||||
// ======================================================================================
|
||||
|
||||
/* XPM */
|
||||
static const char *cursor_createpoint[]={
|
||||
"32 32 3 1",
|
||||
"+ c white",
|
||||
"# c red",
|
||||
". c None",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"................................",
|
||||
"+++++...+++++...................",
|
||||
"................................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"......+.........................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
".................++++...........",
|
||||
"................++++++..........",
|
||||
"...............++++++++.........",
|
||||
"...............++++++++.........",
|
||||
"...............++++++++.........",
|
||||
"...............++++++++.........",
|
||||
"................++++++..........",
|
||||
".................++++...........",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................"};
|
||||
|
||||
class DrawSketchHandlerPoint: public DrawSketchHandler
|
||||
{
|
||||
public:
|
||||
DrawSketchHandlerPoint() : selectionDone(false) {}
|
||||
virtual ~DrawSketchHandlerPoint() {}
|
||||
|
||||
virtual void activated(ViewProviderSketch *sketchgui)
|
||||
{
|
||||
setCursor(QPixmap(cursor_createpoint),7,7);
|
||||
}
|
||||
|
||||
virtual void mouseMove(Base::Vector2D onSketchPos)
|
||||
{
|
||||
setPositionText(onSketchPos);
|
||||
if (seekAutoConstraint(sugConstr, onSketchPos, Base::Vector2D(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr);
|
||||
}
|
||||
applyCursor();
|
||||
}
|
||||
|
||||
virtual bool pressButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
EditPoint = onSketchPos;
|
||||
selectionDone = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool releaseButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (selectionDone){
|
||||
unsetCursor();
|
||||
resetPositionText();
|
||||
|
||||
Gui::Command::openCommand("Add sketch point");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Point(App.Vector(%f,%f,0)))",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
EditPoint.fX,EditPoint.fY);
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::updateActive();
|
||||
|
||||
// add auto constraints for the line segment start
|
||||
if (sugConstr.size() > 0) {
|
||||
createAutoConstraints(sugConstr, getHighestCurveIndex(), Sketcher::start);
|
||||
sugConstr.clear();
|
||||
}
|
||||
|
||||
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
|
||||
}
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
bool selectionDone;
|
||||
Base::Vector2D EditPoint;
|
||||
std::vector<AutoConstraint> sugConstr;
|
||||
};
|
||||
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherCreatePoint);
|
||||
|
||||
CmdSketcherCreatePoint::CmdSketcherCreatePoint()
|
||||
|
@ -1103,11 +1363,12 @@ CmdSketcherCreatePoint::CmdSketcherCreatePoint()
|
|||
|
||||
void CmdSketcherCreatePoint::activated(int iMsg)
|
||||
{
|
||||
ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerPoint());
|
||||
}
|
||||
|
||||
bool CmdSketcherCreatePoint::isActive(void)
|
||||
{
|
||||
return false;
|
||||
return isCreateGeoActive(getActiveGuiDocument());
|
||||
}
|
||||
|
||||
// ======================================================================================
|
||||
|
@ -1582,8 +1843,9 @@ namespace SketcherGui {
|
|||
if (!sSubName || sSubName[0] == '\0')
|
||||
return false;
|
||||
std::string element(sSubName);
|
||||
// for the moment we allow only edges
|
||||
if (element.substr(0,4) == "Edge") {
|
||||
// for the moment we allow only edges and vertices
|
||||
if ((element.size() > 4 && element.substr(0,4) == "Edge") ||
|
||||
(element.size() > 6 && element.substr(0,6) == "Vertex")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1656,7 +1918,8 @@ public:
|
|||
|
||||
virtual void mouseMove(Base::Vector2D onSketchPos)
|
||||
{
|
||||
applyCursor();
|
||||
if (Gui::Selection().getPreselection().pObjectName)
|
||||
applyCursor();
|
||||
}
|
||||
|
||||
virtual bool pressButton(Base::Vector2D onSketchPos)
|
||||
|
@ -1674,7 +1937,8 @@ public:
|
|||
{
|
||||
if (msg.Type == Gui::SelectionChanges::AddSelection) {
|
||||
std::string subName(msg.pSubName);
|
||||
if (subName.size() > 4 && subName.substr(0,4) == "Edge") {
|
||||
if ((subName.size() > 4 && subName.substr(0,4) == "Edge") ||
|
||||
(subName.size() > 6 && subName.substr(0,6) == "Vertex")) {
|
||||
try {
|
||||
Gui::Command::openCommand("Add external geometry");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addExternal(\"%s\",\"%s\")",
|
||||
|
@ -1726,7 +1990,7 @@ void CreateSketcherCommandsCreateGeo(void)
|
|||
{
|
||||
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
|
||||
|
||||
//rcCmdMgr.addCommand(new CmdSketcherCreatePoint());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreatePoint());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreateArc());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreateCircle());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCreateLine());
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
virtual bool pressButton(Base::Vector2D onSketchPos)=0;
|
||||
virtual bool releaseButton(Base::Vector2D onSketchPos)=0;
|
||||
virtual bool onSelectionChanged(const Gui::SelectionChanges& msg) { return false; };
|
||||
virtual void registerPressedKey(bool pressed, int key){};
|
||||
|
||||
virtual void quit(void);
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ struct EditData {
|
|||
CurvesMaterials(0),
|
||||
PointsCoordinate(0),
|
||||
CurvesCoordinate(0),
|
||||
CurveSet(0),
|
||||
CurveSet(0), EditCurveSet(0), RootCrossSet(0),
|
||||
PointSet(0)
|
||||
{}
|
||||
|
||||
|
@ -159,12 +159,13 @@ struct EditData {
|
|||
bool blockedPreselection;
|
||||
bool FullyConstrained;
|
||||
|
||||
// pointer to the Solver
|
||||
// instance of the solver
|
||||
Sketcher::Sketch ActSketch;
|
||||
// container to track our own selected parts
|
||||
std::set<int> SelPointSet;
|
||||
std::set<int> SelCurvSet; // also holds cross axes at -1 and -2
|
||||
std::set<int> SelConstraintSet;
|
||||
std::vector<int> CurvIdToGeoId; // conversion of SoLineSet index to GeoId
|
||||
|
||||
// helper data structure for the constraint rendering
|
||||
std::vector<ConstraintType> vConstrType;
|
||||
|
@ -281,6 +282,11 @@ bool ViewProviderSketch::keyPressed(bool pressed, int key)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (edit && edit->sketchHandler)
|
||||
edit->sketchHandler->registerPressedKey(pressed,key);
|
||||
}
|
||||
}
|
||||
|
||||
return true; // handle all other key events
|
||||
|
@ -610,16 +616,16 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe
|
|||
|
||||
Gui::MenuItem *geom = new Gui::MenuItem();
|
||||
geom->setCommand("Sketcher geoms");
|
||||
*geom /*<< "Sketcher_CreatePoint"*/
|
||||
<< "Sketcher_CreateArc"
|
||||
<< "Sketcher_CreateCircle"
|
||||
<< "Sketcher_CreateLine"
|
||||
<< "Sketcher_CreatePolyline"
|
||||
<< "Sketcher_CreateRectangle"
|
||||
<< "Sketcher_CreateFillet"
|
||||
<< "Sketcher_Trimming"
|
||||
<< "Sketcher_External"
|
||||
<< "Sketcher_ToggleConstruction"
|
||||
*geom << "Sketcher_CreatePoint"
|
||||
<< "Sketcher_CreateArc"
|
||||
<< "Sketcher_CreateCircle"
|
||||
<< "Sketcher_CreateLine"
|
||||
<< "Sketcher_CreatePolyline"
|
||||
<< "Sketcher_CreateRectangle"
|
||||
<< "Sketcher_CreateFillet"
|
||||
<< "Sketcher_Trimming"
|
||||
<< "Sketcher_External"
|
||||
<< "Sketcher_ToggleConstruction"
|
||||
/*<< "Sketcher_CreateText"*/
|
||||
/*<< "Sketcher_CreateDraftLine"*/;
|
||||
|
||||
|
@ -748,8 +754,8 @@ bool ViewProviderSketch::mouseMove(const SbVec3f &point, const SbVec3f &normal,
|
|||
bool preselectChanged;
|
||||
if (Mode!=STATUS_SKETCH_DragPoint && Mode!=STATUS_SKETCH_DragCurve &&
|
||||
Mode!=STATUS_SKETCH_DragConstraint) {
|
||||
int PtIndex,CurvIndex,ConstrIndex,CrossIndex;
|
||||
preselectChanged = detectPreselection(pp,PtIndex,CurvIndex,ConstrIndex,CrossIndex);
|
||||
int PtIndex,GeoIndex,ConstrIndex,CrossIndex;
|
||||
preselectChanged = detectPreselection(pp,PtIndex,GeoIndex,ConstrIndex,CrossIndex);
|
||||
}
|
||||
|
||||
switch (Mode) {
|
||||
|
@ -1179,12 +1185,12 @@ void ViewProviderSketch::onSelectionChanged(const Gui::SelectionChanges& msg)
|
|||
}
|
||||
}
|
||||
|
||||
bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtIndex, int &CurvIndex, int &ConstrIndex, int &CrossIndex)
|
||||
bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtIndex, int &GeoIndex, int &ConstrIndex, int &CrossIndex)
|
||||
{
|
||||
assert(edit);
|
||||
|
||||
PtIndex = -1;
|
||||
CurvIndex = -1; // valid values are 0,1,2,... for normal geometry and -3,-4,-5,... for external geometry
|
||||
GeoIndex = -1; // valid values are 0,1,2,... for normal geometry and -3,-4,-5,... for external geometry
|
||||
CrossIndex = -1;
|
||||
ConstrIndex = -1;
|
||||
|
||||
|
@ -1208,12 +1214,8 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI
|
|||
const SoDetail *curve_detail = Point->getDetail(edit->CurveSet);
|
||||
if (curve_detail && curve_detail->getTypeId() == SoLineDetail::getClassTypeId()) {
|
||||
// get the index
|
||||
CurvIndex = static_cast<const SoLineDetail *>(curve_detail)->getLineIndex();
|
||||
int maxGeoId = getSketchObject()->getHighestCurveIndex();
|
||||
if (CurvIndex > maxGeoId) { // hit on external geometry
|
||||
int extGeoCount = getSketchObject()->getExternalGeometryCount();
|
||||
CurvIndex = -extGeoCount + (CurvIndex - maxGeoId - 1);
|
||||
}
|
||||
int CurvIndex = static_cast<const SoLineDetail *>(curve_detail)->getLineIndex();
|
||||
GeoIndex = edit->CurvIdToGeoId[CurvIndex];
|
||||
}
|
||||
// checking for a hit in the cross
|
||||
} else if (tail == edit->RootCrossSet) {
|
||||
|
@ -1254,12 +1256,12 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI
|
|||
edit->sketchHandler->applyCursor();
|
||||
return true;
|
||||
}
|
||||
} else if (CurvIndex != -1 && CurvIndex != edit->PreselectCurve) { // if a new curve is hit
|
||||
} else if (GeoIndex != -1 && GeoIndex != edit->PreselectCurve) { // if a new curve is hit
|
||||
std::stringstream ss;
|
||||
if (CurvIndex >= 0)
|
||||
ss << "Edge" << CurvIndex;
|
||||
if (GeoIndex >= 0)
|
||||
ss << "Edge" << GeoIndex;
|
||||
else // external geometry
|
||||
ss << "ExternalEdge" << -CurvIndex - 3; // convert index start from -3 to 0
|
||||
ss << "ExternalEdge" << -GeoIndex - 3; // convert index start from -3 to 0
|
||||
bool accepted =
|
||||
Gui::Selection().setPreselect(getSketchObject()->getDocument()->getName()
|
||||
,getSketchObject()->getNameInDocument()
|
||||
|
@ -1270,7 +1272,7 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI
|
|||
edit->blockedPreselection = !accepted;
|
||||
if (accepted) {
|
||||
resetPreselectPoint();
|
||||
edit->PreselectCurve = CurvIndex;
|
||||
edit->PreselectCurve = GeoIndex;
|
||||
edit->PreselectCross = -1;
|
||||
edit->PreselectConstraint = -1;
|
||||
if (edit->sketchHandler)
|
||||
|
@ -1321,7 +1323,7 @@ bool ViewProviderSketch::detectPreselection(const SoPickedPoint *Point, int &PtI
|
|||
edit->sketchHandler->applyCursor();
|
||||
return true;
|
||||
}
|
||||
} else if ((PtIndex == -1 && CurvIndex == -1 && CrossIndex == -1 && ConstrIndex == -1) &&
|
||||
} else if ((PtIndex == -1 && GeoIndex == -1 && CrossIndex == -1 && ConstrIndex == -1) &&
|
||||
(edit->PreselectPoint != -1 || edit->PreselectCurve != -1 || edit->PreselectCross != -1
|
||||
|| edit->PreselectConstraint != -1 || edit->blockedPreselection)) {
|
||||
// we have just left a preselection
|
||||
|
@ -1379,7 +1381,7 @@ void ViewProviderSketch::updateColor(void)
|
|||
int intGeoCount = getSketchObject()->getHighestCurveIndex() + 1;
|
||||
int extGeoCount = getSketchObject()->getExternalGeometryCount();
|
||||
for (int i=0; i < CurvNum; i++) {
|
||||
int GeoId = (i < intGeoCount) ? i : -(extGeoCount - (i - intGeoCount));
|
||||
int GeoId = edit->CurvIdToGeoId[i];
|
||||
if (edit->SelCurvSet.find(GeoId) != edit->SelCurvSet.end())
|
||||
color[i] = SelectColor;
|
||||
else if (edit->PreselectCurve == GeoId)
|
||||
|
@ -1624,8 +1626,16 @@ void ViewProviderSketch::draw(bool temp)
|
|||
assert(int(geomlist->size()) == extGeoCount + intGeoCount);
|
||||
assert(int(geomlist->size()) >= 2);
|
||||
|
||||
for (std::vector<Part::Geometry *>::const_iterator it = geomlist->begin(); it != geomlist->end()-2; ++it) {
|
||||
if ((*it)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { // add a line
|
||||
edit->CurvIdToGeoId.clear();
|
||||
int GeoId = 0;
|
||||
for (std::vector<Part::Geometry *>::const_iterator it = geomlist->begin(); it != geomlist->end()-2; ++it, GeoId++) {
|
||||
if (GeoId >= intGeoCount)
|
||||
GeoId = -extGeoCount;
|
||||
if ((*it)->getTypeId() == Part::GeomPoint::getClassTypeId()) { // add a point
|
||||
const Part::GeomPoint *point = dynamic_cast<const Part::GeomPoint *>(*it);
|
||||
Points.push_back(point->getPoint());
|
||||
}
|
||||
else if ((*it)->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { // add a line
|
||||
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(*it);
|
||||
// create the definition struct for that geom
|
||||
Coords.push_back(lineSeg->getStartPoint());
|
||||
|
@ -1633,6 +1643,7 @@ void ViewProviderSketch::draw(bool temp)
|
|||
Points.push_back(lineSeg->getStartPoint());
|
||||
Points.push_back(lineSeg->getEndPoint());
|
||||
Index.push_back(2);
|
||||
edit->CurvIdToGeoId.push_back(GeoId);
|
||||
}
|
||||
else if ((*it)->getTypeId() == Part::GeomCircle::getClassTypeId()) { // add a circle
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(*it);
|
||||
|
@ -1650,6 +1661,7 @@ void ViewProviderSketch::draw(bool temp)
|
|||
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
|
||||
|
@ -1680,6 +1692,7 @@ void ViewProviderSketch::draw(bool temp)
|
|||
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);
|
||||
Points.push_back(start);
|
||||
Points.push_back(end);
|
||||
|
@ -1713,6 +1726,7 @@ void ViewProviderSketch::draw(bool temp)
|
|||
}
|
||||
|
||||
Index.push_back(countSegments+1);
|
||||
edit->CurvIdToGeoId.push_back(GeoId);
|
||||
}
|
||||
else {
|
||||
;
|
||||
|
|
|
@ -126,7 +126,7 @@ public:
|
|||
/// helper to detect preselection
|
||||
//bool handlePreselection(const SoPickedPoint *pp);
|
||||
/// helper to detect preselection
|
||||
bool detectPreselection(const SoPickedPoint *Point, int &PtIndex,int &CurvIndex, int &ConstrIndex, int &CrossIndex);
|
||||
bool detectPreselection(const SoPickedPoint *Point, int &PtIndex,int &GeoIndex, int &ConstrIndex, int &CrossIndex);
|
||||
/// helper change the color of the sketch according to selection and solver status
|
||||
void updateColor(void);
|
||||
/// get the pointer to the sketch document object
|
||||
|
|
|
@ -60,7 +60,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
|||
sketch->setCommand("S&ketch");
|
||||
Gui::MenuItem* geom = new Gui::MenuItem();
|
||||
geom->setCommand("Sketcher geometries");
|
||||
*geom /*<< "Sketcher_CreatePoint"*/
|
||||
*geom << "Sketcher_CreatePoint"
|
||||
<< "Sketcher_CreateArc"
|
||||
<< "Sketcher_CreateCircle"
|
||||
<< "Sketcher_CreateLine"
|
||||
|
@ -112,7 +112,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
|||
|
||||
part = new Gui::ToolBarItem(root);
|
||||
part->setCommand("Sketcher geometries");
|
||||
*part /*<< "Sketcher_CreatePoint" */
|
||||
*part << "Sketcher_CreatePoint"
|
||||
<< "Sketcher_CreateArc"
|
||||
<< "Sketcher_CreateCircle"
|
||||
<< "Sketcher_CreateLine"
|
||||
|
|
Loading…
Reference in New Issue
Block a user