Merge branch 'master' of ssh://free-cad.git.sourceforge.net/gitroot/free-cad/free-cad

This commit is contained in:
Yorik van Havre 2012-02-25 18:38:15 -02:00
commit ee1509afa0
11 changed files with 320 additions and 126 deletions

View File

@ -426,6 +426,17 @@ void InventorBuilder::endPoints(void)
result << Base::blanks(indent) << "]" << std::endl;
indent -= 2;
result << Base::blanks(indent) << "}" << std::endl;
}
/**
* Adds an SoPointSet node after creating an SoCordinate3 node with
* beginPoints() and endPoints().
* @see startPoints()
* @see beginPoints()
* @see endPoints()
*/
void InventorBuilder::addPointSet(void)
{
result << Base::blanks(indent) << "PointSet { } " << std::endl;
}

View File

@ -164,6 +164,8 @@ public:
void addPoint(const Vector3f &vec);
/// ends the points set operation
void endPoints(void);
/// add an SoPointSet node
void addPointSet(void);
//@}
/** @name Line/Direction handling */

View File

@ -194,7 +194,7 @@ Vector3<_Precision>& Vector3<_Precision>::ProjToPlane (const Vector3<_Precision>
const Vector3<_Precision> &rclNorm)
{
Vector3<_Precision> clTemp(rclNorm);
*this = *this - (clTemp *= ((*this - rclBase) * clTemp));
*this = *this - (clTemp *= ((*this - rclBase) * clTemp) / clTemp.Sqr());
return *this;
}
@ -202,7 +202,7 @@ template <class _Precision>
_Precision Vector3<_Precision>::DistanceToPlane (const Vector3<_Precision> &rclBase,
const Vector3<_Precision> &rclNorm) const
{
return (*this - rclBase) * rclNorm;
return ((*this - rclBase) * rclNorm) / rclNorm.Length();
}
template <class _Precision>
@ -361,7 +361,7 @@ template <class _Precision>
Vector3<_Precision> & Vector3<_Precision>::Normalize (void)
{
_Precision fLen = Length ();
if (fLen != 0.0f) {
if (fLen != (_Precision)0.0 && fLen != (_Precision)1.0) {
x /= fLen;
y /= fLen;
z /= fLen;

View File

@ -73,6 +73,11 @@
<UserDocu>Deliver the distance of the point to a given line</UserDocu>
</Documentation>
</Methode>
<Methode Name="distanceToLineSegment" Const="true">
<Documentation>
<UserDocu>Deliver the distance of the point to a given line segment</UserDocu>
</Documentation>
</Methode>
<Methode Name="distanceToPlane" Const="true">
<Documentation>
<UserDocu>Deliver the distance of the point to a given plane</UserDocu>

View File

@ -401,6 +401,31 @@ PyObject* VectorPy::distanceToLine(PyObject *args)
return Py::new_reference_to(dist);
}
PyObject* VectorPy::distanceToLineSegment(PyObject *args)
{
PyObject *base, *line;
if (!PyArg_ParseTuple(args, "OO",&base, &line))
return 0;
if (!PyObject_TypeCheck(base, &(VectorPy::Type))) {
PyErr_SetString(PyExc_TypeError, "First arg must be Vector");
return 0;
}
if (!PyObject_TypeCheck(line, &(VectorPy::Type))) {
PyErr_SetString(PyExc_TypeError, "Second arg must be Vector");
return 0;
}
VectorPy* base_vec = static_cast<VectorPy*>(base);
VectorPy* line_vec = static_cast<VectorPy*>(line);
VectorPy::PointerType this_ptr = reinterpret_cast<VectorPy::PointerType>(_pcTwinPointer);
VectorPy::PointerType base_ptr = reinterpret_cast<VectorPy::PointerType>(base_vec->_pcTwinPointer);
VectorPy::PointerType line_ptr = reinterpret_cast<VectorPy::PointerType>(line_vec->_pcTwinPointer);
Vector3d v = this_ptr->DistanceToLineSegment(*base_ptr, *line_ptr);
return new VectorPy(v);
}
PyObject* VectorPy::distanceToPlane(PyObject *args)
{
PyObject *base, *line;

View File

@ -39,18 +39,15 @@
#include <BRepLib_FuseEdges.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
#include <BRepBuilderAPI_MakeSolid.hxx>
#include <ShapeBuild_ReShape.hxx>
#include <ShapeFix_Face.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeShape.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
#include <BRepTools.hxx>
#include <BRep_Builder.hxx>
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
#include <ShapeAnalysis_Edge.hxx>
#include "modelRefine.h"
using namespace ModelRefine;
@ -118,49 +115,6 @@ namespace ModelRefine
};
}
void BoundaryEdgeSplitter::split(const EdgeVectorType &edgesIn)
{
std::list<TopoDS_Edge> edges;
std::copy(edgesIn.begin(), edgesIn.end(), back_inserter(edges));
while(!edges.empty())
{
TopoDS_Vertex destination = TopExp::FirstVertex(edges.front(), Standard_True);
TopoDS_Vertex lastVertex = TopExp::LastVertex(edges.front(), Standard_True);
EdgeVectorType boundary;
boundary.push_back(edges.front());
edges.pop_front();
//single edge closed check.
if (destination.IsSame(lastVertex))
{
groupedEdges.push_back(boundary);
continue;
}
bool closedSignal(false);
std::list<TopoDS_Edge>::iterator it;
for (it = edges.begin(); it != edges.end();)
{
TopoDS_Vertex currentVertex = TopExp::FirstVertex(*it, Standard_True);
if (lastVertex.IsSame(currentVertex))
{
boundary.push_back(*it);
lastVertex = TopExp::LastVertex(*it, Standard_True);
edges.erase(it);
it = edges.begin();
if (lastVertex.IsSame(destination))
{
closedSignal = true;
break;
}
continue;
}
++it;
}
if (closedSignal)
groupedEdges.push_back(boundary);
}
}
////////////////////////////////////////////////////////////////////////////////////////////
void FaceTypeSplitter::addShell(const TopoDS_Shell &shellIn)
@ -319,6 +273,53 @@ GeomAbs_SurfaceType FaceTypedBase::getFaceType(const TopoDS_Face &faceIn)
return surfaceTest.GetType();
}
void FaceTypedBase::boundarySplit(const FaceVectorType &facesIn, std::vector<EdgeVectorType> &boundariesOut) const
{
EdgeVectorType bEdges;
boundaryEdges(facesIn, bEdges);
std::list<TopoDS_Edge> edges;
std::copy(bEdges.begin(), bEdges.end(), back_inserter(edges));
while(!edges.empty())
{
TopoDS_Vertex destination = TopExp::FirstVertex(edges.front(), Standard_True);
TopoDS_Vertex lastVertex = TopExp::LastVertex(edges.front(), Standard_True);
EdgeVectorType boundary;
boundary.push_back(edges.front());
edges.pop_front();
//single edge closed check.
if (destination.IsSame(lastVertex))
{
boundariesOut.push_back(boundary);
continue;
}
bool closedSignal(false);
std::list<TopoDS_Edge>::iterator it;
for (it = edges.begin(); it != edges.end();)
{
TopoDS_Vertex currentVertex = TopExp::FirstVertex(*it, Standard_True);
if (lastVertex.IsSame(currentVertex))
{
boundary.push_back(*it);
lastVertex = TopExp::LastVertex(*it, Standard_True);
edges.erase(it);
it = edges.begin();
if (lastVertex.IsSame(destination))
{
closedSignal = true;
break;
}
continue;
}
++it;
}
if (closedSignal)
boundariesOut.push_back(boundary);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
FaceTypedPlane::FaceTypedPlane() : FaceTypedBase(GeomAbs_Plane)
@ -344,15 +345,10 @@ GeomAbs_SurfaceType FaceTypedPlane::getType() const
TopoDS_Face FaceTypedPlane::buildFace(const FaceVectorType &faces) const
{
EdgeVectorType bEdges;
boundaryEdges(faces, bEdges);
BoundaryEdgeSplitter bSplitter;
bSplitter.split(bEdges);
std::vector<TopoDS_Wire> wires;
std::vector<EdgeVectorType> splitEdges = bSplitter.getGroupedEdges();
std::vector<EdgeVectorType> splitEdges;
this->boundarySplit(faces, splitEdges);
if (splitEdges.empty())
return TopoDS_Face();
std::vector<EdgeVectorType>::iterator splitIt;
@ -424,8 +420,111 @@ GeomAbs_SurfaceType FaceTypedCylinder::getType() const
TopoDS_Face FaceTypedCylinder::buildFace(const FaceVectorType &faces) const
{
//to do.
return TopoDS_Face();
std::vector<EdgeVectorType> boundaries;
boundarySplit(faces, boundaries);
static TopoDS_Face dummy;
if (boundaries.size() < 1)
return dummy;
//take one face and remove all the wires.
TopoDS_Face workFace = faces.at(0);
ShapeBuild_ReShape reshaper;
TopExp_Explorer it;
for (it.Init(workFace, TopAbs_WIRE); it.More(); it.Next())
reshaper.Remove(it.Current());
workFace = TopoDS::Face(reshaper.Apply(workFace));
if (workFace.IsNull())
return TopoDS_Face();
ShapeFix_Face faceFixer(workFace);
//makes wires
std::vector<EdgeVectorType>::iterator boundaryIt;
for (boundaryIt = boundaries.begin(); boundaryIt != boundaries.end(); ++boundaryIt)
{
BRepLib_MakeWire wireMaker;
EdgeVectorType::iterator it;
for (it = (*boundaryIt).begin(); it != (*boundaryIt).end(); ++it)
wireMaker.Add(*it);
if (wireMaker.Error() != BRepLib_WireDone)
continue;
faceFixer.Add(wireMaker.Wire());
}
if (faceFixer.Perform() > ShapeExtend_DONE5)
return TopoDS_Face();
return faceFixer.Face();
}
void FaceTypedCylinder::boundarySplit(const FaceVectorType &facesIn, std::vector<EdgeVectorType> &boundariesOut) const
{
//get all the seam edges
EdgeVectorType seamEdges;
FaceVectorType::const_iterator faceIt;
for (faceIt = facesIn.begin(); faceIt != facesIn.end(); ++faceIt)
{
TopExp_Explorer explorer;
for (explorer.Init(*faceIt, TopAbs_EDGE); explorer.More(); explorer.Next())
{
ShapeAnalysis_Edge edgeCheck;
if(edgeCheck.IsSeam(TopoDS::Edge(explorer.Current()), *faceIt))
seamEdges.push_back(TopoDS::Edge(explorer.Current()));
}
}
//normal edges.
EdgeVectorType normalEdges;
ModelRefine::boundaryEdges(facesIn, normalEdges);
//put seam edges in front.the idea is that we always want to traverse along a seam edge if possible.
std::list<TopoDS_Edge> sortedEdges;
std::copy(normalEdges.begin(), normalEdges.end(), back_inserter(sortedEdges));
std::copy(seamEdges.begin(), seamEdges.end(), front_inserter(sortedEdges));
while (!sortedEdges.empty())
{
//detecting closed boundary works best if we start off of the seam edges.
TopoDS_Vertex destination = TopExp::FirstVertex(sortedEdges.back(), Standard_True);
TopoDS_Vertex lastVertex = TopExp::LastVertex(sortedEdges.back(), Standard_True);
bool closedSignal(false);
std::list<TopoDS_Edge> boundary;
boundary.push_back(sortedEdges.back());
sortedEdges.pop_back();
std::list<TopoDS_Edge>::iterator sortedIt;
for (sortedIt = sortedEdges.begin(); sortedIt != sortedEdges.end();)
{
TopoDS_Vertex currentVertex = TopExp::FirstVertex(*sortedIt, Standard_True);
//Seam edges lie on top of each other. i.e. same. and we remove every match from the list
//so we don't actually ever compare the same edge.
if ((*sortedIt).IsSame(boundary.back()))
{
++sortedIt;
continue;
}
if (lastVertex.IsSame(currentVertex))
{
boundary.push_back(*sortedIt);
lastVertex = TopExp::LastVertex(*sortedIt, Standard_True);
if (lastVertex.IsSame(destination))
{
closedSignal = true;
sortedEdges.erase(sortedIt);
break;
}
sortedEdges.erase(sortedIt);
sortedIt = sortedEdges.begin();
continue;
}
++sortedIt;
}
if (closedSignal)
{
EdgeVectorType temp;
std::copy(boundary.begin(), boundary.end(), std::back_inserter(temp));
boundariesOut.push_back(temp);
}
}
}
FaceTypedCylinder& ModelRefine::getCylinderObject()
@ -446,7 +545,7 @@ bool FaceUniter::process()
if (workShell.IsNull())
return false;
typeObjects.push_back(&getPlaneObject());
// typeObjects.push_back(&getCylinderObject());
typeObjects.push_back(&getCylinderObject());
//add more face types.
ModelRefine::FaceTypeSplitter splitter;

View File

@ -61,6 +61,7 @@ namespace ModelRefine
static GeomAbs_SurfaceType getFaceType(const TopoDS_Face &faceIn);
protected:
virtual void boundarySplit(const FaceVectorType &facesIn, std::vector<EdgeVectorType> &boundariesOut) const;
GeomAbs_SurfaceType surfaceType;
};
@ -85,6 +86,9 @@ namespace ModelRefine
virtual GeomAbs_SurfaceType getType() const;
virtual TopoDS_Face buildFace(const FaceVectorType &faces) const;
friend FaceTypedCylinder& getCylinderObject();
protected:
virtual void boundarySplit(const FaceVectorType &facesIn, std::vector<EdgeVectorType> &boundariesOut) const;
};
FaceTypedCylinder& getCylinderObject();
@ -134,17 +138,6 @@ namespace ModelRefine
std::vector<FaceVectorType> equalityVector;
};
class BoundaryEdgeSplitter
{
public:
BoundaryEdgeSplitter(){}
void split(const EdgeVectorType &edgesIn);
const std::vector<EdgeVectorType>& getGroupedEdges(){return groupedEdges;}
private:
std::vector<EdgeVectorType> groupedEdges;
};
class FaceUniter
{
private:

View File

@ -120,6 +120,7 @@ PyObject* PointsPy::writeInventor(PyObject * args)
for (Points::PointKernel::const_iterator it = kernel->begin(); it != kernel->end(); ++it)
builder.addPoint((float)it->x,(float)it->y,(float)it->z);
builder.endPoints();
builder.addPointSet();
builder.close();
return Py::new_reference_to(Py::String(result.str()));

View File

@ -23,9 +23,11 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QPixmap>
# include <QDialog>
#endif
#include <Gui/BitmapFactory.h>
#include <Gui/MainWindow.h>
#include <Base/Tools.h>
@ -34,9 +36,16 @@
using namespace SketcherGui;
SketchOrientationDialog::SketchOrientationDialog(void)
SketchOrientationDialog::SketchOrientationDialog(void)
: QDialog(Gui::getMainWindow()), ui(new Ui_SketchOrientationDialog)
{
ui->setupUi(this);
onPreview();
connect(ui->Reverse_checkBox, SIGNAL(clicked(bool)), this, SLOT(onPreview()));
connect(ui->XY_radioButton , SIGNAL(clicked(bool)), this, SLOT(onPreview()));
connect(ui->XZ_radioButton , SIGNAL(clicked(bool)), this, SLOT(onPreview()));
connect(ui->YZ_radioButton , SIGNAL(clicked(bool)), this, SLOT(onPreview()));
}
SketchOrientationDialog::~SketchOrientationDialog()
@ -44,51 +53,70 @@ SketchOrientationDialog::~SketchOrientationDialog()
}
int SketchOrientationDialog::exec()
void SketchOrientationDialog::accept()
{
//Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
//Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
QDialog dlg(Gui::getMainWindow());
Ui::SketchOrientationDialog ui_SketchOrientationDialog;
ui_SketchOrientationDialog.setupUi(&dlg);
int res;
if (res=dlg.exec()) {
double offset = ui_SketchOrientationDialog.Offset_doubleSpinBox->value();
bool reverse = ui_SketchOrientationDialog.Reverse_checkBox->isChecked();
if (ui_SketchOrientationDialog.XY_radioButton->isChecked()) {
if (reverse) {
Pos = Base::Placement(Base::Vector3d(0,0,offset),Base::Rotation(-1.0,0.0,0.0,0.0));
DirType = 1;
}
else {
Pos = Base::Placement(Base::Vector3d(0,0,offset),Base::Rotation());
DirType = 0;
}
double offset = ui->Offset_doubleSpinBox->value();
bool reverse = ui->Reverse_checkBox->isChecked();
if (ui->XY_radioButton->isChecked()) {
if (reverse) {
Pos = Base::Placement(Base::Vector3d(0,0,offset),Base::Rotation(-1.0,0.0,0.0,0.0));
DirType = 1;
}
else if (ui_SketchOrientationDialog.XZ_radioButton->isChecked()) {
if (reverse) {
Pos = Base::Placement(Base::Vector3d(0,offset,0),Base::Rotation(Base::Vector3d(0,sqrt(2.0)/2.0,sqrt(2.0)/2.0),M_PI));
DirType = 3;
}
else {
Pos = Base::Placement(Base::Vector3d(0,offset,0),Base::Rotation(Base::Vector3d(-1,0,0),1.5*M_PI));
DirType = 2;
}
else {
Pos = Base::Placement(Base::Vector3d(0,0,offset),Base::Rotation());
DirType = 0;
}
else if (ui_SketchOrientationDialog.YZ_radioButton->isChecked()) {
if (reverse) {
Pos = Base::Placement(Base::Vector3d(offset,0,0),Base::Rotation(-0.5,0.5,0.5,-0.5));
DirType = 5;
}
else {
Pos = Base::Placement(Base::Vector3d(offset,0,0),Base::Rotation(0.5,0.5,0.5,0.5));
DirType = 4;
}
}
else if (ui->XZ_radioButton->isChecked()) {
if (reverse) {
Pos = Base::Placement(Base::Vector3d(0,offset,0),Base::Rotation(Base::Vector3d(0,sqrt(2.0)/2.0,sqrt(2.0)/2.0),M_PI));
DirType = 3;
}
else {
Pos = Base::Placement(Base::Vector3d(0,offset,0),Base::Rotation(Base::Vector3d(-1,0,0),1.5*M_PI));
DirType = 2;
}
}
else if (ui->YZ_radioButton->isChecked()) {
if (reverse) {
Pos = Base::Placement(Base::Vector3d(offset,0,0),Base::Rotation(-0.5,0.5,0.5,-0.5));
DirType = 5;
}
else {
Pos = Base::Placement(Base::Vector3d(offset,0,0),Base::Rotation(0.5,0.5,0.5,0.5));
DirType = 4;
}
}
return res;
QDialog::accept();
}
void SketchOrientationDialog::onPreview()
{
std::string icon;
bool reverse = ui->Reverse_checkBox->isChecked();
if (ui->XY_radioButton->isChecked()) {
if (reverse)
icon = "view-bottom";
else
icon = "view-top";
}
else if (ui->XZ_radioButton->isChecked()) {
if (reverse)
icon = "view-rear";
else
icon = "view-front";
}
else if (ui->YZ_radioButton->isChecked()) {
if (reverse)
icon = "view-left";
else
icon = "view-right";
}
ui->previewLabel->setPixmap(
Gui::BitmapFactory().pixmapFromSvg(icon.c_str(),
ui->previewLabel->size()));
}
#include "moc_SketchOrientationDialog.cpp"

View File

@ -24,20 +24,31 @@
#define SKETCHERGUI_SketchOrientationDialog_H
#include <Base/Placement.h>
#include <QDialog>
namespace SketcherGui {
class SketchOrientationDialog {
class Ui_SketchOrientationDialog;
class SketchOrientationDialog : public QDialog
{
Q_OBJECT
public:
SketchOrientationDialog(void);
~SketchOrientationDialog();
int exec();
Base::Placement Pos;
int DirType;
void accept();
protected Q_SLOTS:
void onPreview();
private:
Ui_SketchOrientationDialog* ui;
};
}
#endif // SKETCHERGUI_SketchOrientationDialog_H

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SketchOrientationDialog</class>
<widget class="QDialog" name="SketchOrientationDialog">
<class>SketcherGui::SketchOrientationDialog</class>
<widget class="QDialog" name="SketcherGui::SketchOrientationDialog">
<property name="geometry">
<rect>
<x>0</x>
@ -13,8 +13,8 @@
<property name="windowTitle">
<string>Choose orientation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Sketch orientation</string>
@ -47,14 +47,33 @@
</layout>
</widget>
</item>
<item>
<item row="0" column="1">
<widget class="QLabel" name="previewLabel">
<property name="minimumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="text">
<string notr="true">Preview</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="Reverse_checkBox">
<property name="text">
<string>Reverse direction</string>
</property>
</widget>
</item>
<item>
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
@ -81,7 +100,7 @@
</item>
</layout>
</item>
<item>
<item row="3" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -98,7 +117,7 @@
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SketchOrientationDialog</receiver>
<receiver>SketcherGui::SketchOrientationDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
@ -114,7 +133,7 @@
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SketchOrientationDialog</receiver>
<receiver>SketcherGui::SketchOrientationDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">