Merge branch 'master' of ssh://git.code.sf.net/p/free-cad/code

This commit is contained in:
Yorik van Havre 2015-01-11 15:55:32 -02:00
commit af65c413d1
17 changed files with 594 additions and 50 deletions

View File

@ -170,7 +170,14 @@ int DocumentObjectPy::setCustomAttributes(const char* attr, PyObject *obj)
throw Py::AttributeError(s.str());
}
prop->setPyObject(obj);
try {
prop->setPyObject(obj);
}
catch (const Base::TypeError& e) {
std::stringstream s;
s << "Property '" << prop->getName() << "': " << e.what();
throw Py::TypeError(s.str());
}
return 1;
}

View File

@ -57,8 +57,24 @@ SOURCE_GROUP("Features" FILES ${Features_SRCS})
SOURCE_GROUP("Algorithms" FILES ${DrawingAlgos_SRCS})
SET(Drawing_Templates
Templates/A0_Landscape_ISO7200.svg
Templates/A0_Landscape_plain.svg
Templates/A0_Portrait_plain.svg
Templates/A1_Landscape_ISO7200.svg
Templates/A1_Landscape_plain.svg
Templates/A1_Portrait_plain.svg
Templates/A2_Landscape_ISO7200.svg
Templates/A2_Landscape_plain.svg
Templates/A2_Portrait_plain.svg
Templates/A3_Landscape.svg
Templates/A3_Landscape_ISO7200.svg
Templates/A3_Landscape_plain.svg
Templates/A3_Portrait_plain.svg
Templates/A4_Landscape.svg
Templates/A4_Landscape_ISO7200.svg
Templates/A4_Landscape_plain.svg
Templates/A4_Portrait_ISO7200.svg
Templates/A4_Portrait_plain.svg
)
if(MSVC)

View File

@ -25,6 +25,7 @@
#ifndef _PreComp_
# include <sstream>
# include <cmath>
# include <BRepAdaptor_Curve.hxx>
# include <Geom_Circle.hxx>
# include <gp_Circ.hxx>
@ -33,6 +34,7 @@
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <HLRBRep_Algo.hxx>
#include <TopoDS_Shape.hxx>
@ -71,6 +73,7 @@
#include <GeomConvert_BSplineCurveToBezierCurve.hxx>
#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <BRepLProp_CLProps.hxx>
#include "DrawingExport.h"
#include <Base/Tools.h>
@ -78,6 +81,87 @@
using namespace Drawing;
TopoDS_Edge DrawingOutput::asCircle(const BRepAdaptor_Curve& c) const
{
double curv=0;
gp_Pnt pnt, center;
// approximate the circle center from three positions
BRepLProp_CLProps prop(c,c.FirstParameter(),2,Precision::Confusion());
curv += prop.Curvature();
prop.CentreOfCurvature(pnt);
center.ChangeCoord().Add(pnt.Coord());
prop.SetParameter(0.5*(c.FirstParameter()+c.LastParameter()));
curv += prop.Curvature();
prop.CentreOfCurvature(pnt);
center.ChangeCoord().Add(pnt.Coord());
prop.SetParameter(c.LastParameter());
curv += prop.Curvature();
prop.CentreOfCurvature(pnt);
center.ChangeCoord().Add(pnt.Coord());
center.ChangeCoord().Divide(3);
curv /= 3;
// get circle from curvature information
double radius = 1 / curv;
TopLoc_Location location;
Handle(Poly_Polygon3D) polygon = BRep_Tool::Polygon3D(c.Edge(), location);
if (!polygon.IsNull()) {
const TColgp_Array1OfPnt& nodes = polygon->Nodes();
for (int i = nodes.Lower(); i <= nodes.Upper(); i++) {
gp_Pnt p = nodes(i);
double dist = p.Distance(center);
if (std::abs(dist - radius) > 0.001)
return TopoDS_Edge();
}
gp_Circ circ;
circ.SetLocation(center);
circ.SetRadius(radius);
gp_Pnt p1 = nodes(nodes.Lower());
gp_Pnt p2 = nodes(nodes.Upper());
double dist = p1.Distance(p2);
if (dist < Precision::Confusion()) {
BRepBuilderAPI_MakeEdge mkEdge(circ);
return mkEdge.Edge();
}
else {
gp_Vec dir1(center, p1);
dir1.Normalize();
gp_Vec dir2(center, p2);
dir2.Normalize();
p1 = gp_Pnt(center.XYZ() + radius * dir1.XYZ());
p2 = gp_Pnt(center.XYZ() + radius * dir2.XYZ());
BRepBuilderAPI_MakeEdge mkEdge(circ, p1, p2);
return mkEdge.Edge();
}
}
return TopoDS_Edge();
}
TopoDS_Edge DrawingOutput::asBSpline(const BRepAdaptor_Curve& c, int maxDegree) const
{
Standard_Real tol3D = 0.001;
Standard_Integer maxSegment = 10;
Handle_BRepAdaptor_HCurve hCurve = new BRepAdaptor_HCurve(c);
// approximate the curve using a tolerance
Approx_Curve3d approx(hCurve,tol3D,GeomAbs_C0,maxSegment,maxDegree);
if (approx.IsDone() && approx.HasResult()) {
// have the result
Handle_Geom_BSplineCurve spline = approx.Curve();
BRepBuilderAPI_MakeEdge mkEdge(spline, spline->FirstParameter(), spline->LastParameter());
return mkEdge.Edge();
}
return TopoDS_Edge();
}
SVGOutput::SVGOutput()
{
}
@ -97,7 +181,17 @@ std::string SVGOutput::exportEdges(const TopoDS_Shape& input)
printEllipse(adapt, i, result);
}
else if (adapt.GetType() == GeomAbs_BSplineCurve) {
printBSpline(adapt, i, result);
TopoDS_Edge circle = asCircle(adapt);
if (circle.IsNull()) {
printBSpline(adapt, i, result);
}
else {
BRepAdaptor_Curve adapt_circle(circle);
printCircle(adapt_circle, result);
}
}
else if (adapt.GetType() == GeomAbs_BezierCurve) {
printBezier(adapt, i, result);
}
// fallback
else {
@ -181,6 +275,70 @@ void SVGOutput::printEllipse(const BRepAdaptor_Curve& c, int id, std::ostream& o
}
}
void SVGOutput::printBezier(const BRepAdaptor_Curve& c, int id, std::ostream& out)
{
try {
std::stringstream str;
str << "<path d=\"M";
Handle_Geom_BezierCurve bezier = c.Bezier();
Standard_Integer poles = bezier->NbPoles();
// if it's a bezier with degree higher than 3 convert it into a B-spline
if (bezier->Degree() > 3 || bezier->IsRational()) {
TopoDS_Edge edge = asBSpline(c, 3);
if (!edge.IsNull()) {
BRepAdaptor_Curve spline(edge);
printBSpline(spline, id, out);
}
else {
Standard_Failure::Raise("do it the generic way");
}
return;
}
gp_Pnt p1 = bezier->Pole(1);
str << p1.X() << "," << p1.Y();
if (bezier->Degree() == 3) {
if (poles != 4)
Standard_Failure::Raise("do it the generic way");
gp_Pnt p2 = bezier->Pole(2);
gp_Pnt p3 = bezier->Pole(3);
gp_Pnt p4 = bezier->Pole(4);
str << " C"
<< p2.X() << "," << p2.Y() << " "
<< p3.X() << "," << p3.Y() << " "
<< p4.X() << "," << p4.Y() << " ";
}
else if (bezier->Degree() == 2) {
if (poles != 3)
Standard_Failure::Raise("do it the generic way");
gp_Pnt p2 = bezier->Pole(2);
gp_Pnt p3 = bezier->Pole(3);
str << " Q"
<< p2.X() << "," << p2.Y() << " "
<< p3.X() << "," << p3.Y() << " ";
}
else if (bezier->Degree() == 1) {
if (poles != 2)
Standard_Failure::Raise("do it the generic way");
gp_Pnt p2 = bezier->Pole(2);
str << " L" << p2.X() << "," << p2.Y() << " ";
}
else {
Standard_Failure::Raise("do it the generic way");
}
str << "\" />";
out << str.str();
}
catch (Standard_Failure) {
printGeneric(c, id, out);
}
}
void SVGOutput::printBSpline(const BRepAdaptor_Curve& c, int id, std::ostream& out)
{
try {

View File

@ -25,6 +25,7 @@
#define DRAWING_EXPORT_H
#include <string>
#include <TopoDS_Edge.hxx>
class TopoDS_Shape;
class BRepAdaptor_Curve;
@ -32,7 +33,16 @@ class BRepAdaptor_Curve;
namespace Drawing
{
class DrawingExport SVGOutput
class DrawingExport DrawingOutput
{
public:
// If the curve is approximately a circle it will be returned,
// otherwise a null edge is returned.
TopoDS_Edge asCircle(const BRepAdaptor_Curve&) const;
TopoDS_Edge asBSpline(const BRepAdaptor_Curve&, int maxDegree) const;
};
class DrawingExport SVGOutput : public DrawingOutput
{
public:
SVGOutput();
@ -42,11 +52,12 @@ private:
void printCircle(const BRepAdaptor_Curve&, std::ostream&);
void printEllipse(const BRepAdaptor_Curve&, int id, std::ostream&);
void printBSpline(const BRepAdaptor_Curve&, int id, std::ostream&);
void printBezier(const BRepAdaptor_Curve&, int id, std::ostream&);
void printGeneric(const BRepAdaptor_Curve&, int id, std::ostream&);
};
/* dxf output section - Dan Falck 2011/09/25 */
class DrawingExport DXFOutput
class DrawingExport DXFOutput : public DrawingOutput
{
public:
DXFOutput();

View File

@ -126,15 +126,39 @@ Gui::Action * CmdDrawingNewPage::createAction(void)
QAction* defaultAction = 0;
int defaultId = 0;
QString lastPaper;
int lastId = -1;
std::string path = App::Application::getResourceDir();
path += "Mod/Drawing/Templates/";
QDir dir(QString::fromUtf8(path.c_str()), QString::fromAscii("*.svg"));
for (unsigned int i=0; i<dir.count(); i++ ) {
QRegExp rx(QString::fromAscii("(A|B|C|D|E)(\\d)_(Landscape|Portrait).svg"));
QRegExp rx(QString::fromAscii("(A|B|C|D|E)(\\d)_(Landscape|Portrait)(_.*\\.|\\.)svg$"));
if (rx.indexIn(dir[i]) > -1) {
QString paper = rx.cap(1);
int id = rx.cap(2).toInt();
QString orientation = rx.cap(3);
QString info = rx.cap(4).mid(1);
info.chop(1);
if (!info.isEmpty()) {
info[0] = info[0].toUpper();
}
// group by paper size
if (!lastPaper.isEmpty()) {
if (lastPaper != paper) {
QAction* sep = pcAction->addAction(QString());
sep->setSeparator(true);
}
else if (lastId != id) {
QAction* sep = pcAction->addAction(QString());
sep->setSeparator(true);
}
}
lastPaper = paper;
lastId = id;
QFile file(QString::fromAscii(":/icons/actions/drawing-landscape-A0.svg"));
QAction* a = pcAction->addAction(QString());
if (file.open(QFile::ReadOnly)) {
@ -147,6 +171,7 @@ Gui::Action * CmdDrawingNewPage::createAction(void)
a->setProperty("TemplatePaper", paper);
a->setProperty("TemplateOrientation", orientation);
a->setProperty("TemplateId", id);
a->setProperty("TemplateInfo", info);
a->setProperty("Template", dir.absoluteFilePath(dir[i]));
if (id == 3) {
@ -157,6 +182,7 @@ Gui::Action * CmdDrawingNewPage::createAction(void)
}
_pcAction = pcAction;
languageChange();
if (defaultAction) {
pcAction->setIcon(defaultAction->icon());
@ -179,6 +205,8 @@ void CmdDrawingNewPage::languageChange()
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
QList<QAction*> a = pcAction->actions();
for (QList<QAction*>::iterator it = a.begin(); it != a.end(); ++it) {
if ((*it)->isSeparator())
continue;
QString paper = (*it)->property("TemplatePaper").toString();
int id = (*it)->property("TemplateId").toInt();
QString orientation = (*it)->property("TemplateOrientation").toString();
@ -186,19 +214,38 @@ void CmdDrawingNewPage::languageChange()
orientation = QCoreApplication::translate("Drawing_NewPage", "Landscape", 0, QCoreApplication::CodecForTr);
else if (orientation.compare(QLatin1String("portrait"), Qt::CaseInsensitive) == 0)
orientation = QCoreApplication::translate("Drawing_NewPage", "Portrait", 0, QCoreApplication::CodecForTr);
QString info = (*it)->property("TemplateInfo").toString();
(*it)->setText(QCoreApplication::translate(
"Drawing_NewPage", "%1%2 %3", 0,
QCoreApplication::CodecForTr)
.arg(paper)
.arg(id)
.arg(orientation));
(*it)->setToolTip(QCoreApplication::translate(
"Drawing_NewPage", "Insert new %1%2 %3 drawing", 0,
QCoreApplication::CodecForTr)
.arg(paper)
.arg(id)
.arg(orientation));
if (info.isEmpty()) {
(*it)->setText(QCoreApplication::translate(
"Drawing_NewPage", "%1%2 %3", 0,
QCoreApplication::CodecForTr)
.arg(paper)
.arg(id)
.arg(orientation));
(*it)->setToolTip(QCoreApplication::translate(
"Drawing_NewPage", "Insert new %1%2 %3 drawing", 0,
QCoreApplication::CodecForTr)
.arg(paper)
.arg(id)
.arg(orientation));
}
else {
(*it)->setText(QCoreApplication::translate(
"Drawing_NewPage", "%1%2 %3 (%4)", 0,
QCoreApplication::CodecForTr)
.arg(paper)
.arg(id)
.arg(orientation)
.arg(info));
(*it)->setToolTip(QCoreApplication::translate(
"Drawing_NewPage", "Insert new %1%2 %3 (%4) drawing", 0,
QCoreApplication::CodecForTr)
.arg(paper)
.arg(id)
.arg(orientation)
.arg(info));
}
}
}

View File

@ -332,7 +332,9 @@ void DrawingView::setDocumentObject(const std::string& name)
void DrawingView::closeEvent(QCloseEvent* ev)
{
ev->accept();
MDIView::closeEvent(ev);
if (!ev->isAccepted())
return;
// when closing the view from GUI notify the view provider to mark it invisible
if (_pcDocument && !m_objectName.empty()) {

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:freecad="http://www.freecadweb.org/wiki/index.php?title=Svg_Namespace"
width="1189mm"
height="841mm"
viewBox="0 0 1189 841">
<!-- Working space 20 10 1179 831 -->
<!-- Title block 999 771 1179 831 -->
<g>
<rect
id="drawing-border"
style="fill:none;stroke:#000000;stroke-width:0.7;stroke-linecap:miter;stroke-miterlimit:4"
width="1159"
height="821"
x="20"
y="10" />
<!-- width-30, height-20 -->
<g
transform="translate(979,544)">
<!-- A4 Portrait based for other formats width-210, height-297 -->
<!-- page rect translation
w h rw rh tx ty
A4-P 210 297 180 277 0 0
A3-L 420 297 390 277 210 0
A2-L 594 420 564 400 384 123
A1-L 841 594 811 574 631 297
A0-L 1189 841 1159 821 979 544
-->
<g
id="titleblock-structure"
style="fill:none;stroke:#000000;stroke-width:0.35;stroke-linecap:miter;stroke-miterlimit:4">
<rect width="180" height="60" x="20" y="227" />
<path d="m 20,239 h 180" />
<path d="m 80,227 v 12" />
<path d="m 140,239 v 48" />
<path d="m 160,239 v 12" />
<path d="m 180,239 v 12" />
<path d="m 140,251 h 60" />
<path d="m 140,275 h 60" />
<path d="m 180,275 v 12" />
</g>
<g
id="titleblock-text-non-editable"
style="font-size:3px;text-anchor:start;fill:#000000;font-family:osifont"
xml:space="preserve">
<text x="21" y="230">Created by:</text>
<text x="81" y="230">Title:</text>
<text x="21" y="242">Supplementary information:</text>
<text x="141" y="242">Size:</text>
<text x="161" y="242">Sheet:</text>
<text x="181" y="242">Scale:</text>
<text x="141" y="254">Part number:</text>
<text x="141" y="266">Drawing number:</text>
<text x="141" y="278">Date:</text>
<text x="181" y="278">Revision:</text>
</g>
<g
id="titleblock-text-editable"
style="font-size:5px;text-anchor:middle;fill:#000000;font-family:osifont"
xml:space="preserve">
<text freecad:editable="Author" x="50" y="236"><tspan>AUTHOR NAME</tspan></text>
<text freecad:editable="Title" x="140" y="236"><tspan>DRAWING TITLE</tspan></text>
<text freecad:editable="SI-1:" x="80" y="248"><tspan></tspan></text>
<text freecad:editable="SI-2:" x="80" y="260"><tspan>FreeCAD DRAWING</tspan></text>
<text freecad:editable="SI-3:" x="80" y="272"><tspan></tspan></text>
<text freecad:editable="SI-4:" x="80" y="284"><tspan></tspan></text>
<text freecad:editable="Size" x="150" y="248"><tspan>A0</tspan></text>
<text freecad:editable="Sheet" x="170" y="248"><tspan>X / Y</tspan></text>
<text freecad:editable="Scale" x="190" y="248"><tspan>SCALE</tspan></text>
<text freecad:editable="PN" x="170" y="260"><tspan>PART NUMBER</tspan></text>
<text freecad:editable="DN" x="170" y="272"><tspan>DRAWING NUMBER</tspan></text>
<text freecad:editable="Date" x="160" y="284"><tspan>YYYY-MM-DD</tspan></text>
<text freecad:editable="Revision" x="190" y="284"><tspan>A</tspan></text>
</g>
</g>
</g>
<!-- DrawingContent -->
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:freecad="http://www.freecadweb.org/wiki/index.php?title=Svg_Namespace"
width="841mm"
height="594mm"
viewBox="0 0 841 594">
<!-- Working space 20 10 831 584 -->
<!-- Title block 651 524 831 584 -->
<g>
<rect
id="drawing-border"
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:miter;stroke-miterlimit:4"
width="811"
height="574"
x="20"
y="10" />
<!-- width-30, height-20 -->
<g
transform="translate(631,297)">
<!-- A4 Portrait based for other formats width-210, height-297 -->
<!-- page rect translation
w h rw rh tx ty
A4-P 210 297 180 277 0 0
A3-L 420 297 390 277 210 0
A2-L 594 420 564 400 384 123
A1-L 841 594 811 574 631 297
A0-L 1189 841 1159 821 979 544
-->
<g
id="titleblock-structure"
style="fill:none;stroke:#000000;stroke-width:0.35;stroke-linecap:miter;stroke-miterlimit:4">
<rect width="180" height="60" x="20" y="227" />
<path d="m 20,239 h 180" />
<path d="m 80,227 v 12" />
<path d="m 140,239 v 48" />
<path d="m 160,239 v 12" />
<path d="m 180,239 v 12" />
<path d="m 140,251 h 60" />
<path d="m 140,275 h 60" />
<path d="m 180,275 v 12" />
</g>
<g
id="titleblock-text-non-editable"
style="font-size:3px;text-anchor:start;fill:#000000;font-family:osifont"
xml:space="preserve">
<text x="21" y="230">Created by:</text>
<text x="81" y="230">Title:</text>
<text x="21" y="242">Supplementary information:</text>
<text x="141" y="242">Size:</text>
<text x="161" y="242">Sheet:</text>
<text x="181" y="242">Scale:</text>
<text x="141" y="254">Part number:</text>
<text x="141" y="266">Drawing number:</text>
<text x="141" y="278">Date:</text>
<text x="181" y="278">Revision:</text>
</g>
<g
id="titleblock-text-editable"
style="font-size:5px;text-anchor:middle;fill:#000000;font-family:osifont"
xml:space="preserve">
<text freecad:editable="Author" x="50" y="236"><tspan>AUTHOR NAME</tspan></text>
<text freecad:editable="Title" x="140" y="236"><tspan>DRAWING TITLE</tspan></text>
<text freecad:editable="SI-1:" x="80" y="248"><tspan></tspan></text>
<text freecad:editable="SI-2:" x="80" y="260"><tspan>FreeCAD DRAWING</tspan></text>
<text freecad:editable="SI-3:" x="80" y="272"><tspan></tspan></text>
<text freecad:editable="SI-4:" x="80" y="284"><tspan></tspan></text>
<text freecad:editable="Size" x="150" y="248"><tspan>A1</tspan></text>
<text freecad:editable="Sheet" x="170" y="248"><tspan>X / Y</tspan></text>
<text freecad:editable="Scale" x="190" y="248"><tspan>SCALE</tspan></text>
<text freecad:editable="PN" x="170" y="260"><tspan>PART NUMBER</tspan></text>
<text freecad:editable="DN" x="170" y="272"><tspan>DRAWING NUMBER</tspan></text>
<text freecad:editable="Date" x="160" y="284"><tspan>YYYY-MM-DD</tspan></text>
<text freecad:editable="Revision" x="190" y="284"><tspan>A</tspan></text>
</g>
</g>
</g>
<!-- DrawingContent -->
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:freecad="http://www.freecadweb.org/wiki/index.php?title=Svg_Namespace"
width="594mm"
height="420mm"
viewBox="0 0 594 420">
<!-- Working space 20 10 584 410 -->
<!-- Title block 404 350 584 410 -->
<g>
<rect
id="drawing-border"
style="fill:none;stroke:#000000;stroke-width:0.35;stroke-linecap:miter;stroke-miterlimit:4"
width="564"
height="400"
x="20"
y="10" />
<!-- width-30, height-20 -->
<g
transform="translate(384,123)">
<!-- A4 Portrait based for other formats width-210, height-297 -->
<!-- page rect translation
w h rw rh tx ty
A4-P 210 297 180 277 0 0
A3-L 420 297 390 277 210 0
A2-L 594 420 564 400 384 123
A1-L 841 594 811 574 631 297
A0-L 1189 841 1159 821 979 544
-->
<g
id="titleblock-structure"
style="fill:none;stroke:#000000;stroke-width:0.35;stroke-linecap:miter;stroke-miterlimit:4">
<rect width="180" height="60" x="20" y="227" />
<path d="m 20,239 h 180" />
<path d="m 80,227 v 12" />
<path d="m 140,239 v 48" />
<path d="m 160,239 v 12" />
<path d="m 180,239 v 12" />
<path d="m 140,251 h 60" />
<path d="m 140,275 h 60" />
<path d="m 180,275 v 12" />
</g>
<g
id="titleblock-text-non-editable"
style="font-size:3px;text-anchor:start;fill:#000000;font-family:osifont"
xml:space="preserve">
<text x="21" y="230">Created by:</text>
<text x="81" y="230">Title:</text>
<text x="21" y="242">Supplementary information:</text>
<text x="141" y="242">Size:</text>
<text x="161" y="242">Sheet:</text>
<text x="181" y="242">Scale:</text>
<text x="141" y="254">Part number:</text>
<text x="141" y="266">Drawing number:</text>
<text x="141" y="278">Date:</text>
<text x="181" y="278">Revision:</text>
</g>
<g
id="titleblock-text-editable"
style="font-size:5px;text-anchor:middle;fill:#000000;font-family:osifont"
xml:space="preserve">
<text freecad:editable="Author" x="50" y="236"><tspan>AUTHOR NAME</tspan></text>
<text freecad:editable="Title" x="140" y="236"><tspan>DRAWING TITLE</tspan></text>
<text freecad:editable="SI-1:" x="80" y="248"><tspan></tspan></text>
<text freecad:editable="SI-2:" x="80" y="260"><tspan>FreeCAD DRAWING</tspan></text>
<text freecad:editable="SI-3:" x="80" y="272"><tspan></tspan></text>
<text freecad:editable="SI-4:" x="80" y="284"><tspan></tspan></text>
<text freecad:editable="Size" x="150" y="248"><tspan>A2</tspan></text>
<text freecad:editable="Sheet" x="170" y="248"><tspan>X / Y</tspan></text>
<text freecad:editable="Scale" x="190" y="248"><tspan>SCALE</tspan></text>
<text freecad:editable="PN" x="170" y="260"><tspan>PART NUMBER</tspan></text>
<text freecad:editable="DN" x="170" y="272"><tspan>DRAWING NUMBER</tspan></text>
<text freecad:editable="Date" x="160" y="284"><tspan>YYYY-MM-DD</tspan></text>
<text freecad:editable="Revision" x="190" y="284"><tspan>A</tspan></text>
</g>
</g>
</g>
<!-- DrawingContent -->
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -121,7 +121,6 @@ static PyObject * importer(PyObject *self, PyObject *args)
try {
IGESControl_Controller::Init();
Interface_Static::SetIVal("read.surfacecurve.mode",3);
IGESCAFControl_Reader aReader;
// http://www.opencascade.org/org/forum/thread_20603/?forum=3
aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true)

View File

@ -162,7 +162,6 @@ static PyObject * importer(PyObject *self, PyObject *args)
try {
IGESControl_Controller::Init();
Interface_Static::SetIVal("read.surfacecurve.mode",3);
IGESCAFControl_Reader aReader;
// http://www.opencascade.org/org/forum/thread_20603/?forum=3
aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true)
@ -518,7 +517,6 @@ static PyObject * ocaf(PyObject *self, PyObject *args)
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("IGES");
IGESControl_Controller::Init();
Interface_Static::SetIVal("read.surfacecurve.mode",3);
IGESCAFControl_Reader aReader;
// http://www.opencascade.org/org/forum/thread_20603/?forum=3
aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true)

View File

@ -297,6 +297,32 @@ void PartExport initPart()
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part");
// General
Base::Reference<ParameterGrp> hGenGrp = hGrp->GetGroup("General");
// http://www.opencascade.org/org/forum/thread_20801/
// read.surfacecurve.mode:
// A preference for the computation of curves in an entity which has both 2D and 3D representation.
// Each TopoDS_Edge in TopoDS_Face must have a 3D and 2D curve that references the surface.
// If both 2D and 3D representation of the entity are present, the computation of these curves depends on
// the following values of parameter:
// 0: "Default" - no preference, both curves are taken
// 3: "3DUse_Preferred" - 3D curves are used to rebuild 2D ones
// Additional modes for IGES
// 2: "2DUse_Preferred" - the 2D is used to rebuild the 3D in case of their inconsistency
// -2: "2DUse_Forced" - the 2D is always used to rebuild the 3D (even if 2D is present in the file)
// -3: "3DUse_Forced" - the 3D is always used to rebuild the 2D (even if 2D is present in the file)
int readsurfacecurve = hGenGrp->GetInt("ReadSurfaceCurveMode", 0);
Interface_Static::SetIVal("read.surfacecurve.mode", readsurfacecurve);
// write.surfacecurve.mode (STEP-only):
// This parameter indicates whether parametric curves (curves in parametric space of surface) should be
// written into the STEP file. This parameter can be set to Off in order to minimize the size of the resulting
// STEP file.
// Off (0) : writes STEP files without pcurves. This mode decreases the size of the resulting file.
// On (1) : (default) writes pcurves to STEP file
int writesurfacecurve = hGenGrp->GetInt("WriteSurfaceCurveMode", 1);
Interface_Static::SetIVal("write.surfacecurve.mode", writesurfacecurve);
//IGES handling
Base::Reference<ParameterGrp> hIgesGrp = hGrp->GetGroup("IGES");
int value = Interface_Static::IVal("write.iges.brep.mode");

View File

@ -69,9 +69,7 @@ int Part::ImportIgesParts(App::Document *pcDoc, const char* FileName)
try {
Base::FileInfo fi(FileName);
// read iges file
// http://www.opencascade.org/org/forum/thread_20801/
IGESControl_Controller::Init();
Interface_Static::SetIVal("read.surfacecurve.mode",3);
// load data exchange message files
Message_MsgFile::LoadFromEnv("CSF_XSMessage","IGES");

View File

@ -569,9 +569,7 @@ void TopoShape::importIges(const char *FileName)
{
try {
// read iges file
// http://www.opencascade.org/org/forum/thread_20801/
IGESControl_Controller::Init();
Interface_Static::SetIVal("read.surfacecurve.mode",3);
IGESControl_Reader aReader;
// Ignore construction elements
// http://www.opencascade.org/org/forum/thread_20603/?forum=3

View File

@ -1376,18 +1376,29 @@ int Sketch::addAngleConstraint(int geoId, double value)
{
geoId = checkGeoId(geoId);
if (Geoms[geoId].type != Line)
return -1;
if (Geoms[geoId].type == Line) {
GCS::Line &l = Lines[Geoms[geoId].index];
GCS::Line &l = Lines[Geoms[geoId].index];
// add the parameter for the angle
FixParameters.push_back(new double(value));
double *angle = FixParameters[FixParameters.size()-1];
// add the parameter for the angle
FixParameters.push_back(new double(value));
double *angle = FixParameters[FixParameters.size()-1];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintP2PAngle(l.p1, l.p2, angle, tag);
return ConstraintsCounter;
}
else if (Geoms[geoId].type == Arc) {
GCS::Arc &a = Arcs[Geoms[geoId].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintP2PAngle(l.p1, l.p2, angle, tag);
return ConstraintsCounter;
// add the parameter for the angle
FixParameters.push_back(new double(value));
double *angle = FixParameters[FixParameters.size()-1];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintL2LAngle(a.center, a.start, a.center, a.end, angle, tag);
return ConstraintsCounter;
}
return -1;
}
// line to line angle constraint

View File

@ -2070,7 +2070,7 @@ void CmdSketcherConstrainAngle::activated(int iMsg)
if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2) && isVertex(GeoId3, PosId3)) {
double ActAngle = 0.0;
openCommand("add angle constraint");
openCommand("Add angle constraint");
//add missing point-on-object constraints
if(! IsPointAlreadyOnCurve(GeoId1, GeoId3, PosId3, Obj)){
@ -2163,7 +2163,7 @@ void CmdSketcherConstrainAngle::activated(int iMsg)
std::swap(PosId1,PosId2);
}
openCommand("add angle constraint");
openCommand("Add angle constraint");
Gui::Command::doCommand(
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Angle',%d,%d,%d,%d,%f)) ",
selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,ActAngle);
@ -2187,12 +2187,28 @@ void CmdSketcherConstrainAngle::activated(int iMsg)
Base::Vector3d dir = lineSeg->getEndPoint()-lineSeg->getStartPoint();
double ActAngle = atan2(dir.y,dir.x);
openCommand("add angle constraint");
openCommand("Add angle constraint");
Gui::Command::doCommand(
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Angle',%d,%f)) ",
selection[0].getFeatName(),GeoId1,ActAngle);
commitCommand();
finishDistanceConstraint(this, Obj);
return;
}
else if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle *arc;
arc = dynamic_cast<const Part::GeomArcOfCircle*>(geom);
double startangle, endangle;
arc->getRange(startangle, endangle);
double angle = endangle - startangle;
openCommand("Add angle constraint");
Gui::Command::doCommand(
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Angle',%d,%f)) ",
selection[0].getFeatName(),GeoId1,angle);
commitCommand();
finishDistanceConstraint(this, Obj);
return;
}

View File

@ -1265,12 +1265,19 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2D &toPo
dir2.RotateZ(-M_PI/2);
}
} else if (Constr->First != Constraint::GeoUndef) { // line angle
} else if (Constr->First != Constraint::GeoUndef) { // line/arc angle
const Part::Geometry *geo = GeoById(geomlist, Constr->First);
if (geo->getTypeId() != Part::GeomLineSegment::getClassTypeId())
if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
p0 = (lineSeg->getEndPoint()+lineSeg->getStartPoint())/2;
}
else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geo);
p0 = arc->getCenter();
}
else {
return;
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
p0 = (lineSeg->getEndPoint()+lineSeg->getStartPoint())/2;
}
} else
return;
@ -3721,16 +3728,26 @@ Restart:
} else if (Constr->First != Constraint::GeoUndef) {
const Part::Geometry *geo = GeoById(*geomlist, Constr->First);
if (geo->getTypeId() != Part::GeomLineSegment::getClassTypeId())
if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
p0 = Base::convertTo<SbVec3f>((lineSeg->getEndPoint()+lineSeg->getStartPoint())/2);
Base::Vector3d dir = lineSeg->getEndPoint()-lineSeg->getStartPoint();
startangle = 0.;
range = atan2(dir.y,dir.x);
endangle = startangle + range;
}
else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geo);
p0 = Base::convertTo<SbVec3f>(arc->getCenter());
Base::Vector3d dir = arc->getEndPoint()-arc->getStartPoint();
arc->getRange(startangle, endangle);
range = endangle - startangle;
}
else {
break;
const Part::GeomLineSegment *lineSeg = dynamic_cast<const Part::GeomLineSegment *>(geo);
p0 = Base::convertTo<SbVec3f>((lineSeg->getEndPoint()+lineSeg->getStartPoint())/2);
Base::Vector3d dir = lineSeg->getEndPoint()-lineSeg->getStartPoint();
startangle = 0.;
range = atan2(dir.y,dir.x);
endangle = startangle + range;
}
} else
break;