Example implementation
This commit is contained in:
@@ -462,14 +462,14 @@ bool GeomCurve::normalAt(double u, Base::Vector3d& dir) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GeomCurve::intersect( GeomCurve * c,
|
||||
std::vector<std::pair<Base::Vector3d, Base::Vector3d>>& points,
|
||||
bool GeomCurve::intersect( GeomCurve * c,
|
||||
std::vector<std::pair<Base::Vector3d, Base::Vector3d>>& points,
|
||||
double tol) const
|
||||
{
|
||||
Handle(Geom_Curve) curve1 = Handle(Geom_Curve)::DownCast(handle());
|
||||
Handle(Geom_Curve) curve2 = Handle(Geom_Curve)::DownCast(c->handle());
|
||||
|
||||
if(!curve1.IsNull() && !curve2.IsNull()) {
|
||||
if(!curve1.IsNull() && !curve2.IsNull()) {
|
||||
return intersect(curve1,curve2,points, tol);
|
||||
}
|
||||
else
|
||||
@@ -477,38 +477,38 @@ bool GeomCurve::intersect( GeomCurve * c,
|
||||
|
||||
}
|
||||
|
||||
bool GeomCurve::intersect(const Handle(Geom_Curve) curve1, const Handle(Geom_Curve) curve2,
|
||||
std::vector<std::pair<Base::Vector3d, Base::Vector3d>>& points,
|
||||
bool GeomCurve::intersect(const Handle(Geom_Curve) curve1, const Handle(Geom_Curve) curve2,
|
||||
std::vector<std::pair<Base::Vector3d, Base::Vector3d>>& points,
|
||||
double tol) const
|
||||
{
|
||||
// https://forum.freecadweb.org/viewtopic.php?f=10&t=31700
|
||||
if (curve1->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) &&
|
||||
curve2->IsKind(STANDARD_TYPE(Geom_BoundedCurve))){
|
||||
|
||||
|
||||
Handle(Geom_BoundedCurve) bcurve1 = Handle(Geom_BoundedCurve)::DownCast(curve1);
|
||||
Handle(Geom_BoundedCurve) bcurve2 = Handle(Geom_BoundedCurve)::DownCast(curve2);
|
||||
|
||||
|
||||
gp_Pnt c1s = bcurve1->StartPoint();
|
||||
gp_Pnt c2s = bcurve2->StartPoint();
|
||||
gp_Pnt c1e = bcurve1->EndPoint();
|
||||
gp_Pnt c2e = bcurve2->EndPoint();
|
||||
|
||||
|
||||
auto checkendpoints = [&points,tol]( gp_Pnt p1, gp_Pnt p2) {
|
||||
if(p1.Distance(p2) < tol)
|
||||
points.emplace_back(Base::Vector3d(p1.X(),p1.Y(),p1.Z()),Base::Vector3d(p2.X(),p2.Y(),p2.Z()));
|
||||
};
|
||||
|
||||
|
||||
checkendpoints(c1s,c2s);
|
||||
checkendpoints(c1s,c2e);
|
||||
checkendpoints(c1e,c2s);
|
||||
checkendpoints(c1e,c2e);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
|
||||
|
||||
GeomAPI_ExtremaCurveCurve intersector(curve1, curve2);
|
||||
|
||||
|
||||
if (intersector.NbExtrema() == 0 || intersector.LowerDistance() > tol) {
|
||||
// No intersection
|
||||
return false;
|
||||
@@ -517,7 +517,7 @@ bool GeomCurve::intersect(const Handle(Geom_Curve) curve1, const Handle(Geom_Cur
|
||||
for (int i = 1; i <= intersector.NbExtrema(); i++) {
|
||||
if (intersector.Distance(i) > tol)
|
||||
continue;
|
||||
|
||||
|
||||
gp_Pnt p1, p2;
|
||||
intersector.Points(i, p1, p2);
|
||||
points.emplace_back(Base::Vector3d(p1.X(),p1.Y(),p1.Z()),Base::Vector3d(p2.X(),p2.Y(),p2.Z()));
|
||||
@@ -530,7 +530,7 @@ bool GeomCurve::intersect(const Handle(Geom_Curve) curve1, const Handle(Geom_Cur
|
||||
else
|
||||
THROWM(Base::CADKernelError,e.GetMessageString())
|
||||
}
|
||||
|
||||
|
||||
|
||||
return points.size()>0?true:false;
|
||||
}
|
||||
@@ -547,7 +547,7 @@ bool GeomCurve::closestParameter(const Base::Vector3d& point, double &u) const
|
||||
}
|
||||
}
|
||||
catch (StdFail_NotDone& e) {
|
||||
|
||||
|
||||
if (c->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))){
|
||||
Base::Vector3d firstpoint = this->pointAtParameter(c->FirstParameter());
|
||||
Base::Vector3d lastpoint = this->pointAtParameter(c->LastParameter());
|
||||
@@ -620,7 +620,7 @@ double GeomCurve::getLastParameter() const
|
||||
catch (Standard_Failure& e) {
|
||||
|
||||
THROWM(Base::CADKernelError,e.GetMessageString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double GeomCurve::curvatureAt(double u) const
|
||||
@@ -849,7 +849,7 @@ void GeomBezierCurve::Restore(Base::XMLReader& reader)
|
||||
THROWM(Base::CADKernelError,"BezierCurve restore failed")
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
|
||||
|
||||
THROWM(Base::CADKernelError,e.GetMessageString())
|
||||
}
|
||||
}
|
||||
@@ -1530,24 +1530,24 @@ PyObject *GeomTrimmedCurve::getPyObject(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool GeomTrimmedCurve::intersectBasisCurves( const GeomTrimmedCurve * c,
|
||||
std::vector<std::pair<Base::Vector3d, Base::Vector3d>>& points,
|
||||
bool GeomTrimmedCurve::intersectBasisCurves( const GeomTrimmedCurve * c,
|
||||
std::vector<std::pair<Base::Vector3d, Base::Vector3d>>& points,
|
||||
double tol) const
|
||||
{
|
||||
Handle(Geom_TrimmedCurve) curve1 = Handle(Geom_TrimmedCurve)::DownCast(handle());
|
||||
Handle(Geom_TrimmedCurve) curve2 = Handle(Geom_TrimmedCurve)::DownCast(c->handle());
|
||||
|
||||
|
||||
Handle(Geom_Curve) bcurve1 = curve1->BasisCurve();
|
||||
Handle(Geom_Curve) bcurve2 = curve2->BasisCurve();
|
||||
|
||||
|
||||
if(!bcurve1.IsNull() && !bcurve2.IsNull()) {
|
||||
|
||||
|
||||
return intersect(bcurve1, bcurve2, points, tol);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
@@ -3661,7 +3661,7 @@ void GeomLineSegment::setPoints(const Base::Vector3d& Start, const Base::Vector3
|
||||
// Create line out of two points
|
||||
if (p1.Distance(p2) < gp::Resolution())
|
||||
THROWM(Base::ValueError,"Both points are equal");
|
||||
|
||||
|
||||
GC_MakeSegment ms(p1, p2);
|
||||
if (!ms.IsDone()) {
|
||||
THROWM(Base::CADKernelError,gce_ErrorStatusText(ms.Status()))
|
||||
@@ -3723,21 +3723,20 @@ void GeomLineSegment::Restore (Base::XMLReader &reader)
|
||||
EndY = reader.getAttributeAsFloat("EndY");
|
||||
EndZ = reader.getAttributeAsFloat("EndZ");
|
||||
|
||||
Base::Vector3d start(StartX,StartY,StartZ);
|
||||
Base::Vector3d start(StartX,StartY,StartZ);
|
||||
Base::Vector3d end(EndX,EndY,EndZ);
|
||||
// set the read geometry
|
||||
try {
|
||||
setPoints(start, end);
|
||||
}
|
||||
catch(Base::ValueError &e) {
|
||||
// for a line segment construction, the only possibility of a value error is that
|
||||
// for a line segment construction, the only possibility of a value error is that
|
||||
// the points are too close. The best try to restore is incrementing the distance.
|
||||
// for other objects, the best effort may be just to leave default values.
|
||||
reader.setPartialRestore(true);
|
||||
end = start + Base::Vector3d(start.x*DBL_EPSILON,0,0);
|
||||
|
||||
|
||||
setPoints(start, end);
|
||||
|
||||
THROWM(Base::RestoreError, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Console.h>
|
||||
|
||||
#include "Geometry.h"
|
||||
#include "GeometryPy.h"
|
||||
@@ -39,6 +40,7 @@
|
||||
#include "PropertyGeometryList.h"
|
||||
#include "Part2DObject.h"
|
||||
|
||||
|
||||
using namespace App;
|
||||
using namespace Base;
|
||||
using namespace std;
|
||||
@@ -168,29 +170,21 @@ void PropertyGeometryList::Save(Writer &writer) const
|
||||
|
||||
void PropertyGeometryList::Restore(Base::XMLReader &reader)
|
||||
{
|
||||
bool partialrestore = false;
|
||||
|
||||
// read my element
|
||||
reader.clearPartialRestoreObject();
|
||||
reader.readElement("GeometryList");
|
||||
// get the value of my attribute
|
||||
int count = reader.getAttributeAsInteger("count");
|
||||
|
||||
std::vector<Geometry*> values;
|
||||
values.reserve(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
reader.readElement("Geometry");
|
||||
const char* TypeName = reader.getAttribute("type");
|
||||
Geometry *newG = (Geometry *)Base::Type::fromName(TypeName).createInstance();
|
||||
newG->Restore(reader);
|
||||
|
||||
try {
|
||||
newG->Restore(reader);
|
||||
values.push_back(newG);
|
||||
reader.readEndElement("Geometry");
|
||||
}
|
||||
catch(Base::RestoreError &e) {
|
||||
|
||||
e.ReportException();
|
||||
|
||||
if(reader.testStatus(Base::XMLReader::ReaderStatus::PartialRestoreInObject)) {
|
||||
Base::Console().Error("Geometry \"%s\" within a PropertyGeometryList was subject to a partial restore.\n",reader.localName());
|
||||
if(isOrderRelevant()) {
|
||||
// Pushes the best try by the Geometry class
|
||||
values.push_back(newG);
|
||||
@@ -198,24 +192,19 @@ void PropertyGeometryList::Restore(Base::XMLReader &reader)
|
||||
else {
|
||||
delete newG;
|
||||
}
|
||||
|
||||
reader.readEndElement("Geometry");
|
||||
|
||||
partialrestore = true;
|
||||
|
||||
continue;
|
||||
reader.clearPartialRestoreObject();
|
||||
}
|
||||
else {
|
||||
values.push_back(newG);
|
||||
}
|
||||
|
||||
|
||||
reader.readEndElement("Geometry");
|
||||
}
|
||||
|
||||
reader.readEndElement("GeometryList");
|
||||
|
||||
// assignment
|
||||
setValues(values);
|
||||
|
||||
if(partialrestore)
|
||||
THROW(Base::RestoreError);
|
||||
}
|
||||
|
||||
App::Property *PropertyGeometryList::Copy(void) const
|
||||
|
||||
@@ -133,7 +133,7 @@ Py::Object BrowserViewPy::setHtml(const Py::Tuple& args)
|
||||
|
||||
/**
|
||||
* Constructs a WebView widget which can be zoomed with Ctrl+Mousewheel
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
WebView::WebView(QWidget *parent)
|
||||
@@ -232,11 +232,11 @@ BrowserView::BrowserView(QWidget* parent)
|
||||
|
||||
view->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
|
||||
view->page()->setForwardUnsupportedContent(true);
|
||||
|
||||
|
||||
// set our custom cookie manager
|
||||
FcCookieJar* cookiejar = new FcCookieJar(this);
|
||||
view->page()->networkAccessManager()->setCookieJar(cookiejar);
|
||||
|
||||
|
||||
// enable local storage so we can store stuff across sessions (startpage)
|
||||
QWebSettings* settings = view->settings();
|
||||
settings->setAttribute(QWebSettings::LocalStorageEnabled, true);
|
||||
@@ -272,18 +272,18 @@ BrowserView::~BrowserView()
|
||||
delete view;
|
||||
}
|
||||
|
||||
void BrowserView::onLinkClicked (const QUrl & url)
|
||||
void BrowserView::onLinkClicked (const QUrl & url)
|
||||
{
|
||||
QString scheme = url.scheme();
|
||||
QString host = url.host();
|
||||
//QString username = url.userName();
|
||||
|
||||
// path handling
|
||||
// path handling
|
||||
QString path = url.path();
|
||||
QFileInfo fi(path);
|
||||
QString ext = fi.completeSuffix();
|
||||
QUrl exturl(url);
|
||||
|
||||
|
||||
// query
|
||||
QString q;
|
||||
if (url.hasQuery())
|
||||
@@ -320,21 +320,17 @@ void BrowserView::onLinkClicked (const QUrl & url)
|
||||
q = q.replace(QString::fromLatin1("="),QString::fromLatin1("=\""))+QString::fromLatin1("\"");
|
||||
q = q.replace(QString::fromLatin1("%"),QString::fromLatin1("%%"));
|
||||
// url queries in the form of somescript.py?key=value, the first key=value will be printed in the py console as key="value"
|
||||
Gui::Command::doCommand(Gui::Command::Gui,q.toStdString().c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Gui,q.toStdString().c_str());
|
||||
}
|
||||
// Gui::Command::doCommand(Gui::Command::Gui,"execfile('%s')",(const char*) fi.absoluteFilePath(). toLocal8Bit());
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"exec(open('%s').read())",(const char*) fi.absoluteFilePath() .toLocal8Bit());
|
||||
}
|
||||
catch (const Base::RestoreError& e) {
|
||||
e.ReportException();
|
||||
if(e.getTranslatable()) {
|
||||
QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Error loading file"),
|
||||
QObject::tr(e.getMessage().c_str()));
|
||||
}
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"exec(open('%s').read())",(const char*) fi.absoluteFilePath() .toLocal8Bit());
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
QMessageBox::critical(this, tr("Error"), QString::fromUtf8(e.what()));
|
||||
}
|
||||
|
||||
if(this->getAppDocument()->testStatus(App::Document::PartialRestore))
|
||||
QMessageBox::critical(this, tr("Error"), tr("There were errors while loading the file. Some data might have been modified or not recovered at all. Look in the report view for more specific information about the objects involved."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -346,7 +342,7 @@ void BrowserView::onLinkClicked (const QUrl & url)
|
||||
|
||||
bool BrowserView::chckHostAllowed(const QString& host)
|
||||
{
|
||||
// only check if a local file, later we can do here a dialog to ask the user if
|
||||
// only check if a local file, later we can do here a dialog to ask the user if
|
||||
return host.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user