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

This commit is contained in:
Yorik van Havre
2012-01-20 18:19:03 -02:00
14 changed files with 291 additions and 141 deletions

View File

@@ -308,9 +308,6 @@ bool Application::closeDocument(const char* name)
if (pos == DocMap.end()) // no such document
return false;
if (!pos->second->isClosable())
return false;
// Trigger observers before removing the document from the internal map.
// Some observers might rely on that this document is still there.
signalDeleteDocument(*pos->second);

View File

@@ -86,6 +86,26 @@ void Std_TestQM::activated(int iMsg)
}
}
//===========================================================================
// Std_TestReloadQM
//===========================================================================
DEF_STD_CMD(Std_TestReloadQM);
Std_TestReloadQM::Std_TestReloadQM()
: Command("Std_TestReloadQM")
{
sGroup = "Standard-Test";
sMenuText = "Reload translation files";
sToolTipText = "Test function to check .qm translation files";
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
}
void Std_TestReloadQM::activated(int iMsg)
{
Translator::instance()->activateLanguage(Translator::instance()->activeLanguage().c_str());
}
//===========================================================================
// Std_Test1
//===========================================================================
@@ -626,6 +646,7 @@ void CreateTestCommands(void)
CommandManager &rcCmdMgr = Application::Instance->commandManager();
rcCmdMgr.addCommand(new Std_TestQM());
rcCmdMgr.addCommand(new Std_TestReloadQM());
rcCmdMgr.addCommand(new FCCmdTest1());
rcCmdMgr.addCommand(new FCCmdTest2());
rcCmdMgr.addCommand(new FCCmdTest3());

View File

@@ -1,5 +1,5 @@
#***************************************************************************
#* (c) Milos Koutny (milos.koutny@gmail.com) 2010 *
#* (c) Milos Koutny (milos.koutny@gmail.com) 2012 *
#* *
#* This file is part of the FreeCAD CAx development system. *
#* *
@@ -22,36 +22,38 @@
#* Milos Koutny 2010 *
#***************************************************************************/
import FreeCAD, Part, os, FreeCADGui, draftGui
import FreeCAD, Part, os, FreeCADGui, __builtin__
from FreeCAD import Base
from math import *
##########################################################
# Script version dated 17-May-2010 #
# Script version dated 19-Jan-2012 #
##########################################################
#Configuration parameters below - use standard slashes / #
##########################################################
#model_tab_filename="c:/libraries/3d_libraries/brno_cis/brno_footprints_models.csv"
## path to table file (simple comma separated values)
model_tab_filename = FreeCAD.getResourceDir()+ "Mod/Idf/lib/footprints_models.csv"
#step_path="c:/libraries/3d_libraries/brno_cis/step/"
## path to directory containing step models
step_path=FreeCAD.getResourceDir()+ "Mod/Idf/lib/"
#model_tab_filename="c:/Libraries/3d_libraries/tandberg/footprints_models.csv"
#step_path="c:/Libraries/3d_libraries/tandberg/step/"
ignore_hole_size=1 # size in MM to prevent huge number of drilled holes
EmpDisplayMode=2 # 0='Flat Lines', 1='Shaded', 2='Wireframe', 3='Points'; recommended 2 or 0
IDF_sort=0 # 0-sort per refdes [1 - part number (not preffered)/refdes] 2-sort per footprint/refdes
IDF_diag=1 # 0/1=disabled/enabled output (footprint.lst/missing_models.lst)
IDF_diag_path="C:/temp" # path for output of footprint.lst and missing_models.lst
IDF_diag_path="/tmp" # path for output of footprint.lst and missing_models.lst
########################################################################################
# End config section do not touch code below #
########################################################################################
pythonopen = open # to distinguish python built-in open function from the one declared here
pythonopen = __builtin__.open # to distinguish python built-in open function from the one declared here
def open(filename):
"""called when freecad opens an Emn file"""
@@ -176,11 +178,11 @@ def Process_board_outline(doc,board_outline,drills,board_thickness):
outline=outline.cut(Part.Face(out_shape))
doc_outline=doc.addObject("Part::Feature","Board_outline")
doc_outline.Shape=outline
FreeCADGui.Selection.addSelection(doc_outline)
FreeCADGui.runCommand("Draft_Upgrade")
outline=FreeCAD.ActiveDocument.getObject("Union").Shape
FreeCAD.ActiveDocument.removeObject("Union")
doc_outline=doc.addObject("Part::Feature","Board_outline")
#FreeCADGui.Selection.addSelection(doc_outline)
#FreeCADGui.runCommand("Draft_Upgrade")
#outline=FreeCAD.ActiveDocument.getObject("Union").Shape
#FreeCAD.ActiveDocument.removeObject("Union")
#doc_outline=doc.addObject("Part::Feature","Board_outline")
doc_outline.Shape=outline.extrude(Base.Vector(0,0,-board_thickness))
grp=doc.addObject("App::DocumentObjectGroup", "Board_Geoms")
grp.addObject(doc_outline)
@@ -342,7 +344,7 @@ def place_steps(doc,placement,board_thickness):
FreeCAD.Console.PrintMessage("Step models to be loaded for footprints: "+str(validkeys)+"\n")
grp=doc.addObject("App::DocumentObjectGroup", "Step Models")
for validkey in validkeys:
step_dict.append((validkey,Part.read(step_path+"/"+model_dict[validkey])))
step_dict.append((validkey,Part.read(step_path+model_dict[validkey])))
FreeCAD.Console.PrintMessage("Reading step file "+str(model_dict[validkey])+" for footprint "+str(validkey)+"\n")
step_dict=dict(step_dict)
for place_item in placement:

View File

@@ -31,6 +31,6 @@
# two options for IDF added by Milos Koutny (12-Feb-2010)
# an option for IDF added by Milos Koutny (12-Feb-2010)
FreeCAD.addImportType("IDF emn file File Type (*.emn)","Idf")
#FreeCAD.addImportType("IDF emp File Type (*.emp)","Import_Emp")

View File

@@ -1,28 +1,28 @@
"FOOTPRINT" "STEP FILE"
"SOT23-R" "SOT23.STP"
"SMD_C_0805-R" "0805_SMD.STP"
"SMD_C_1210-R" "1210_SMD.STP"
"SMD_R_1206-R" "1206_SMD.STP"
"SMD_C_0603-R" "0603_SMD.STP"
"SMD_R_0603-R" "0603_SMD.STP"
"MINISMDC-1812-R" "1812_SMD.STP"
"SMD_C_2225-R" "2225_SMD.STP"
"SMD_R_2512-R" "2512_SMD.STP"
"1812PS" "1812_SMD.STP"
"TSSOP8_065M-R" "TSS0P_8.STP"
"MSOP10E_LT" "MSOP_10.STP"
"TCMT11XX" "TCMT1107_4.STP"
"SMB-TB" "SMB_DO_214AA.STP"
"SOT404-GDS-R" "SOT404.STP"
"SOT428-A1-A2C-R" "SOT428_DPAK.STP"
"SOT96-1-R" "SOT_96.STP"
"SOT323-BEC-R" "SOT_323_3.STP"
"SOD523-R" "SOD_523.STP"
"SMC" "SMC_DO_214AB.STP"
"SOD523-R" "SOD_523.STP"
"TSM-104-01-L-DV" "TSM_104_01_L_DV_A.STP"
"TSM-103-01-L-DV-A" "TSM_103_01_L_DV_A.STP"
"SOD323-R" "SOD_323.STP"
"SOT23-R" "SOT23.stp"
"SMD_C_0805-R" "0805_SMD.stp"
"SMD_C_1210-R" "1210_SMD.stp"
"SMD_R_1206-R" "1206_SMD.stp"
"SMD_C_0603-R" "0603_SMD.stp"
"SMD_R_0603-R" "0603_SMD.stp"
"MINISMDC-1812-R" "1812_SMD.stp"
"SMD_C_2225-R" "2225_SMD.stp"
"SMD_R_2512-R" "2512_SMD.stp"
"1812PS" "1812_SMD.stp"
"TSSOP8_065M-R" "TSS0P_8.stp"
"MSOP10E_LT" "MSOP_10.stp"
"TCMT11XX" "TCMT1107_4.stp"
"SMB-TB" "SMB_DO_214AA.stp"
"SOT404-GDS-R" "SOT404.stp"
"SOT428-A1-A2C-R" "SOT428_DPAK.stp"
"SOT96-1-R" "SOT_96.stp"
"SOT323-BEC-R" "SOT_323_3.stp"
"SOD523-R" "SOD_523.stp"
"SMC" "SMC_DO_214AB.stp"
"SOD523-R" "SOD_523.stp"
"TSM-104-01-L-DV" "TSM_104_01_L_DV_A.stp"
"TSM-103-01-L-DV-A" "TSM_103_01_L_DV_A.stp"
"SOD323-R" "SOD_323.stp"
"VC0603-R" "VC0603_SMD.stp"
"RLF12545" "RLF_12545.stp"
"CAPAE830X1050" "CAP_50SGV_8_10.stp"
Can't render this file because it contains an unexpected character in line 1 and column 11.

View File

@@ -68,6 +68,7 @@
#include <App/Document.h>
#include <App/DocumentObjectPy.h>
#include <Gui/Application.h>
#include <Gui/MainWindow.h>
#include <Mod/Part/Gui/ViewProvider.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/ProgressIndicator.h>
@@ -176,9 +177,9 @@ void ImportOCAF::loadShapes(const TDF_Label& label, const TopLoc_Location& loc,
if (aShapeTool->IsSimpleShape(label) && (isRef || aShapeTool->IsFree(label))) {
if (isRef)
createShape( label, loc, defaultname );
createShape(label, loc, part_name);
else
createShape( label, part_loc, part_name );
createShape(label, part_loc, part_name);
}
else {
for (TDF_ChildIterator it(label); it.More(); it.Next()) {
@@ -691,10 +692,15 @@ static PyObject * exporter(PyObject *self, PyObject *args)
#include <XCAFDoc_LayerTool.hxx>
#include <XCAFDoc_ShapeMapTool.hxx>
#include <QApplication>
#include <QDialog>
#include <QDialogButtonBox>
#include <QPointer>
#include <QStyle>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QTextStream>
#include <QHBoxLayout>
#include <QVBoxLayout>
class OCAFBrowser
{
@@ -703,8 +709,6 @@ public:
: pDoc(h)
{
myGroupIcon = QApplication::style()->standardIcon(QStyle::SP_DirIcon);
myTree = new QTreeWidget();
myTree->setHeaderLabel(QString::fromAscii("OCAF Browser"));
TDataStd::IDList(myList);
myList.Append(TDataStd_TreeNode::GetDefaultTreeID());
@@ -720,7 +724,7 @@ public:
myList.Append(XCAFDoc_Location::GetID());
}
void load();
void load(QTreeWidget*);
private:
void load(const TDF_Label& label, QTreeWidgetItem* item, const QString&);
@@ -735,22 +739,20 @@ private:
private:
QIcon myGroupIcon;
QTreeWidget* myTree;
TDF_IDList myList;
Handle_TDocStd_Document pDoc;
};
void OCAFBrowser::load()
void OCAFBrowser::load(QTreeWidget* theTree)
{
myTree->clear();
theTree->clear();
QTreeWidgetItem* root = new QTreeWidgetItem();
root->setText(0, QLatin1String("0"));
root->setIcon(0, myGroupIcon);
myTree->addTopLevelItem(root);
theTree->addTopLevelItem(root);
load(pDoc->GetData()->Root(), root, QString::fromAscii("0"));
myTree->show();
}
void OCAFBrowser::load(const TDF_Label& label, QTreeWidgetItem* item, const QString& s)
@@ -907,8 +909,30 @@ static PyObject * ocaf(PyObject *self, PyObject *args)
return 0;
}
static QPointer<QDialog> dlg = 0;
if (!dlg) {
dlg = new QDialog(Gui::getMainWindow());
QTreeWidget* tree = new QTreeWidget();
tree->setHeaderLabel(QString::fromAscii("OCAF Browser"));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(tree);
dlg->setLayout(layout);
QDialogButtonBox* btn = new QDialogButtonBox(dlg);
btn->setStandardButtons(QDialogButtonBox::Close);
QObject::connect(btn, SIGNAL(rejected()), dlg, SLOT(reject()));
QHBoxLayout *boxlayout = new QHBoxLayout;
boxlayout->addWidget(btn);
layout->addLayout(boxlayout);
}
dlg->setWindowTitle(QString::fromUtf8(file.fileName().c_str()));
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
OCAFBrowser browse(hDoc);
browse.load();
browse.load(dlg->findChild<QTreeWidget*>());
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();

View File

@@ -626,23 +626,23 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
unsigned long refPoint0 = *(boundary.begin());
unsigned long refPoint1 = *(boundary.begin()+1);
if (pP2FStructure) {
const std::set<unsigned long>& ring = (*pP2FStructure)[refPoint0];
bool found = false;
for (std::set<unsigned long>::const_iterator it = ring.begin(); it != ring.end() && !found; ++it) {
for (int i=0; i<3; i++) {
if (pP2FStructure->getFacet(*it)->_aulPoints[i] == refPoint1) {
rFace = *pP2FStructure->getFacet(*it);
rTriangle = _rclMesh.GetFacet(rFace);
found = true;
break;
}
}
}
} else {
const std::set<unsigned long>& ring1 = (*pP2FStructure)[refPoint0];
const std::set<unsigned long>& ring2 = (*pP2FStructure)[refPoint1];
std::vector<unsigned long> f_int;
std::set_intersection(ring1.begin(), ring1.end(), ring2.begin(), ring2.end(),
std::back_insert_iterator<std::vector<unsigned long> >(f_int));
if (f_int.size() != 1)
return false; // error, this must be an open edge!
rFace = _rclMesh._aclFacetArray[f_int.front()];
rTriangle = _rclMesh.GetFacet(rFace);
}
else {
bool ready = false;
for (MeshFacetArray::_TConstIterator it = _rclMesh._aclFacetArray.begin(); it != _rclMesh._aclFacetArray.end(); ++it) {
for (int i=0; i<3; i++) {
if ((it->_aulPoints[i] == refPoint0) && (it->_aulPoints[(i+1)%3] == refPoint1)) {
if ((it->_aulPoints[i] == refPoint0) && (it->_aulPoints[(i+1)%3] == refPoint1) ||
(it->_aulPoints[i] == refPoint1) && (it->_aulPoints[(i+1)%3] == refPoint0)) {
rFace = *it;
rTriangle = _rclMesh.GetFacet(*it);
ready = true;
@@ -663,7 +663,9 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
}
// remove the last added point if it is duplicated
std::vector<unsigned long> bounds = boundary;
if (boundary.front() == boundary.back()) {
bounds.pop_back();
polygon.pop_back();
rPoints.pop_back();
}
@@ -672,6 +674,7 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
// Afterwards we can compare the normals of the created triangles with the z-direction of our local coordinate system.
// If the scalar product is positive it was a hole, otherwise not.
cTria.SetPolygon(polygon);
cTria.SetIndices(bounds);
std::vector<Base::Vector3f> surf_pts = cTria.GetPolygon();
if (pP2FStructure && level > 0) {
@@ -685,7 +688,7 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
if (cTria.TriangulatePolygon()) {
// if we have enough points then we fit a surface through the points and project
// the added points onto this surface
cTria.ProjectOntoSurface(surf_pts);
cTria.PostProcessing(surf_pts);
// get the facets and add the additional points to the array
rFaces.insert(rFaces.end(), cTria.GetFacets().begin(), cTria.GetFacets().end());
std::vector<Base::Vector3f> newVertices = cTria.AddedPoints();
@@ -693,7 +696,7 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
rPoints.push_back((*pt));
}
// Unfortunately, the CDT algorithm does not care about the orientation of the polygon so we cannot rely on the normal
// Unfortunately, some algorithms do not care about the orientation of the polygon so we cannot rely on the normal
// criterion to decide whether it's a hole or not.
//
std::vector<MeshFacet> faces = cTria.GetFacets();
@@ -701,11 +704,13 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
// Special case handling for a hole with three edges: the resulting facet might be coincident with the
// reference facet
if (faces.size()==1){
MeshFacet first;
first._aulPoints[0] = boundary[faces.front()._aulPoints[0]];
first._aulPoints[1] = boundary[faces.front()._aulPoints[1]];
first._aulPoints[2] = boundary[faces.front()._aulPoints[2]];
if ( first.IsEqual(rFace) ) {
MeshFacet first = faces.front();
if (cTria.NeedsReindexing()) {
first._aulPoints[0] = boundary[first._aulPoints[0]];
first._aulPoints[1] = boundary[first._aulPoints[1]];
first._aulPoints[2] = boundary[first._aulPoints[2]];
}
if (first.IsEqual(rFace)) {
rFaces.clear();
rPoints.clear();
cTria.Discard();
@@ -717,9 +722,14 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
MeshFacet facet;
unsigned short ref_side = rFace.Side(refPoint0, refPoint1);
unsigned short tri_side = USHRT_MAX;
if (cTria.NeedsReindexing()) {
// the referenced indices of the polyline
refPoint0 = 0;
refPoint1 = 1;
}
if (ref_side < USHRT_MAX) {
for (std::vector<MeshFacet>::iterator it = faces.begin(); it != faces.end(); ++it) {
tri_side = it->Side(0, 1);
tri_side = it->Side(refPoint0, refPoint1);
if (tri_side < USHRT_MAX) {
facet = *it;
break;
@@ -737,10 +747,9 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
return false;
}
#if 1
MeshGeomFacet triangle;
triangle._aclPoints[0] = rPoints[facet._aulPoints[0]];
triangle._aclPoints[1] = rPoints[facet._aulPoints[1]];
triangle._aclPoints[2] = rPoints[facet._aulPoints[2]];
triangle = cTria.GetTriangle(rPoints, facet);
// Now we have two adjacent triangles which we check for overlaps.
// Therefore we build a separation plane that must separate the two diametrically opposed points.
@@ -763,6 +772,7 @@ bool MeshAlgorithm::FillupHole(const std::vector<unsigned long>& boundary,
for (MeshFacetArray::_TIterator it = rFaces.begin(); it != rFaces.end(); ++it)
it->FlipNormal();
}
#endif
return true;
}
@@ -1764,6 +1774,7 @@ void MeshRefPointToFacets::SearchNeighbours(MeshFacetArray::_TConstIterator f_it
rclNb.push_back(f_it);
f_it->SetFlag(MeshFacet::VISIT);
MeshPointArray::_TConstIterator p_beg = _rclMesh.GetPoints().begin();
MeshFacetArray::_TConstIterator f_beg = _rclMesh.GetFacets().begin();
for (int i = 0; i < 3; i++) {

View File

@@ -1237,55 +1237,20 @@ void MeshTopoAlgorithm::FillupHoles(unsigned long length, int level,
std::list<std::vector<unsigned long> >& aFailed)
{
// get the mesh boundaries as an array of point indices
std::list<std::vector<unsigned long> > aBorders;
std::list<std::vector<unsigned long> > aBorders, aFillBorders;
MeshAlgorithm cAlgo(_rclMesh);
cAlgo.GetMeshBorders(aBorders);
// split boundary loops if needed
cAlgo.SplitBoundaryLoops(aBorders);
// get the facets to a point
MeshRefPointToFacets cPt2Fac(_rclMesh);
MeshFacetArray newFacets;
MeshPointArray newPoints;
unsigned long numberOfOldPoints = _rclMesh._aclPointArray.size();
for ( std::list<std::vector<unsigned long> >::iterator it = aBorders.begin(); it != aBorders.end(); ++it ) {
if ( it->size()-1 > length )
continue; // boundary with too many edges
MeshFacetArray cFacets;
MeshPointArray cPoints;
if (cAlgo.FillupHole(*it, cTria, cFacets, cPoints, level, &cPt2Fac)) {
if (it->front() == it->back())
it->pop_back();
// the triangulation may produce additional points which we must take into account when appending to the mesh
unsigned long countBoundaryPoints = it->size();
unsigned long countDifference = cPoints.size() - countBoundaryPoints;
if (countDifference > 0) {
MeshPointArray::_TIterator pt = cPoints.begin() + countBoundaryPoints;
for (unsigned long i=0; i<countDifference; i++, pt++) {
it->push_back(numberOfOldPoints++);
newPoints.push_back(*pt);
}
}
for (MeshFacetArray::_TIterator kt = cFacets.begin(); kt != cFacets.end(); ++kt ) {
kt->_aulPoints[0] = (*it)[kt->_aulPoints[0]];
kt->_aulPoints[1] = (*it)[kt->_aulPoints[1]];
kt->_aulPoints[2] = (*it)[kt->_aulPoints[2]];
newFacets.push_back(*kt);
}
}
else {
aFailed.push_back(*it);
}
for (std::list<std::vector<unsigned long> >::iterator it = aBorders.begin(); it != aBorders.end(); ++it) {
if (it->size()-1 <= length) // ignore boundary with too many edges
aFillBorders.push_back(*it);
}
// insert new points and faces into the mesh structure
_rclMesh._aclPointArray.insert(_rclMesh._aclPointArray.end(), newPoints.begin(), newPoints.end());
for (MeshPointArray::_TIterator it = newPoints.begin(); it != newPoints.end(); ++it)
_rclMesh._clBoundBox &= *it;
if (!newFacets.empty())
_rclMesh.AddFacets(newFacets);
if (!aFillBorders.empty())
FillupHoles(level, cTria, aFillBorders, aFailed);
}
void MeshTopoAlgorithm::FillupHoles(int level, AbstractPolygonTriangulator& cTria,
@@ -1307,20 +1272,27 @@ void MeshTopoAlgorithm::FillupHoles(int level, AbstractPolygonTriangulator& cTri
if (bound.front() == bound.back())
bound.pop_back();
// the triangulation may produce additional points which we must take into account when appending to the mesh
unsigned long countBoundaryPoints = bound.size();
unsigned long countDifference = cPoints.size() - countBoundaryPoints;
if (countDifference > 0) {
if (cPoints.size() > bound.size()) {
unsigned long countBoundaryPoints = bound.size();
unsigned long countDifference = cPoints.size() - countBoundaryPoints;
MeshPointArray::_TIterator pt = cPoints.begin() + countBoundaryPoints;
for (unsigned long i=0; i<countDifference; i++, pt++) {
bound.push_back(numberOfOldPoints++);
newPoints.push_back(*pt);
}
}
for (MeshFacetArray::_TIterator kt = cFacets.begin(); kt != cFacets.end(); ++kt ) {
kt->_aulPoints[0] = bound[kt->_aulPoints[0]];
kt->_aulPoints[1] = bound[kt->_aulPoints[1]];
kt->_aulPoints[2] = bound[kt->_aulPoints[2]];
newFacets.push_back(*kt);
if (cTria.NeedsReindexing()) {
for (MeshFacetArray::_TIterator kt = cFacets.begin(); kt != cFacets.end(); ++kt ) {
kt->_aulPoints[0] = bound[kt->_aulPoints[0]];
kt->_aulPoints[1] = bound[kt->_aulPoints[1]];
kt->_aulPoints[2] = bound[kt->_aulPoints[2]];
newFacets.push_back(*kt);
}
}
else {
for (MeshFacetArray::_TIterator kt = cFacets.begin(); kt != cFacets.end(); ++kt ) {
newFacets.push_back(*kt);
}
}
}
else {
@@ -1332,8 +1304,24 @@ void MeshTopoAlgorithm::FillupHoles(int level, AbstractPolygonTriangulator& cTri
_rclMesh._aclPointArray.insert(_rclMesh._aclPointArray.end(), newPoints.begin(), newPoints.end());
for (MeshPointArray::_TIterator it = newPoints.begin(); it != newPoints.end(); ++it)
_rclMesh._clBoundBox &= *it;
if (!newFacets.empty())
_rclMesh.AddFacets(newFacets);
if (!newFacets.empty()) {
// Do some checks for invalid point indices
MeshFacetArray addFacets;
addFacets.reserve(newFacets.size());
unsigned long ctPoints = _rclMesh.CountPoints();
for (MeshFacetArray::_TIterator it = newFacets.begin(); it != newFacets.end(); ++it) {
if (it->_aulPoints[0] >= ctPoints ||
it->_aulPoints[1] >= ctPoints ||
it->_aulPoints[2] >= ctPoints) {
Base::Console().Log("Ignore invalid face <%d, %d, %d> (%d vertices)\n",
it->_aulPoints[0], it->_aulPoints[1], it->_aulPoints[2], ctPoints);
}
else {
addFacets.push_back(*it);
}
}
_rclMesh.AddFacets(addFacets);
}
}
void MeshTopoAlgorithm::FindHoles(unsigned long length,

View File

@@ -30,6 +30,7 @@
#include <Base/Exception.h>
#include "Triangulation.h"
#include "Approximation.h"
#include "Algorithm.h"
#include "MeshKernel.h"
#include <Mod/Mesh/App/WildMagic4/Wm4Delaunay2.h>
@@ -121,7 +122,7 @@ std::vector<Base::Vector3f> AbstractPolygonTriangulator::ProjectToFitPlane()
return proj;
}
void AbstractPolygonTriangulator::ProjectOntoSurface(const std::vector<Base::Vector3f>& points)
void AbstractPolygonTriangulator::PostProcessing(const std::vector<Base::Vector3f>& points)
{
// For a good approximation we should have enough points, i.e. for 9 parameters
// for the fit function we should have at least 50 points.
@@ -144,9 +145,23 @@ void AbstractPolygonTriangulator::ProjectOntoSurface(const std::vector<Base::Vec
}
}
MeshGeomFacet AbstractPolygonTriangulator::GetTriangle(const MeshPointArray& points,
const MeshFacet& facet) const
{
MeshGeomFacet triangle;
triangle._aclPoints[0] = points[facet._aulPoints[0]];
triangle._aclPoints[1] = points[facet._aulPoints[1]];
triangle._aclPoints[2] = points[facet._aulPoints[2]];
return triangle;
}
bool AbstractPolygonTriangulator::TriangulatePolygon()
{
try {
if (this->_points.size() != this->_indices.size()) {
Base::Console().Log("Triangulation: %d points <> %d indices\n", _points.size(), _indices.size());
return false;
}
bool ok = Triangulate();
if (ok) Done();
return ok;
@@ -177,6 +192,10 @@ void AbstractPolygonTriangulator::Discard()
}
}
void AbstractPolygonTriangulator::Reset()
{
}
void AbstractPolygonTriangulator::Done()
{
_info.push_back(_points.size());
@@ -625,7 +644,7 @@ bool FlatTriangulator::Triangulate()
return succeeded;
}
void FlatTriangulator::ProjectOntoSurface(const std::vector<Base::Vector3f>&)
void FlatTriangulator::PostProcessing(const std::vector<Base::Vector3f>&)
{
}
@@ -669,7 +688,8 @@ bool ConstraintDelaunayTriangulator::Triangulate()
// -------------------------------------------------------------
Triangulator::Triangulator(const MeshKernel& k) : _kernel(k)
#if 0
Triangulator::Triangulator(const MeshKernel& k, bool flat) : _kernel(k)
{
}
@@ -681,3 +701,23 @@ bool Triangulator::Triangulate()
{
return false;
}
MeshGeomFacet Triangulator::GetTriangle(const MeshPointArray&,
const MeshFacet& facet) const
{
return MeshGeomFacet();
}
void Triangulator::PostProcessing(const std::vector<Base::Vector3f>&)
{
}
void Triangulator::Discard()
{
AbstractPolygonTriangulator::Discard();
}
void Triangulator::Reset()
{
}
#endif

View File

@@ -39,6 +39,15 @@ public:
/** Sets the polygon to be triangulated. */
void SetPolygon(const std::vector<Base::Vector3f>& raclPoints);
void SetIndices(const std::vector<unsigned long>& d) {_indices = d;}
/** Usually the created faces use the indices of the polygon points
* from [0, n]. If the faces should be appended to an existing mesh
* they may need to be reindexed from the calling instance.
* However, there may other algorithms that directly use the indices
* of the mesh and thus do not need to be touched afterwards. In this
* case the method should be reimplemented to return false.
*/
virtual bool NeedsReindexing() const { return true; }
/** Get the polygon points to be triangulated. The points may be
* projected onto its average plane.
*/
@@ -46,7 +55,7 @@ public:
/** The triangulation algorithm may create new points when
* calling Triangulate(). This method returns these added
* points.
* @note: Make sure to have called ProjectOntoSurface() before using
* @note: Make sure to have called PostProcessing() before using
* this method if you want the surface points the new points are lying on.
*/
std::vector<Base::Vector3f> AddedPoints() const;
@@ -65,11 +74,13 @@ public:
/** If points were added then we get the 3D points by projecting the added
* 2D points onto a surface which fits into the given points.
*/
virtual void ProjectOntoSurface(const std::vector<Base::Vector3f>&);
virtual void PostProcessing(const std::vector<Base::Vector3f>&);
/** Returns the geometric triangles of the polygon. */
const std::vector<MeshGeomFacet>& GetTriangles() const { return _triangles;}
/** Returns the topologic facets of the polygon. */
const std::vector<MeshFacet>& GetFacets() const { return _facets;}
/** Returns the the triangle to a given topologic facet. */
virtual MeshGeomFacet GetTriangle(const MeshPointArray&, const MeshFacet&) const;
/** Returns the length of the polygon */
float GetLength() const;
/** Get information about the pol<gons that were processed.
@@ -77,7 +88,9 @@ public:
* polygon.
*/
std::vector<unsigned long> GetInfo() const;
void Discard();
virtual void Discard();
/** Resets some internals. The default implementation does nothing.*/
virtual void Reset();
protected:
/** Computes the triangulation of a polygon. The resulting facets can
@@ -89,6 +102,7 @@ protected:
protected:
bool _discard;
Base::Matrix4D _inverse;
std::vector<unsigned long> _indices;
std::vector<Base::Vector3f> _points;
std::vector<Base::Vector3f> _newpoints;
std::vector<MeshGeomFacet> _triangles;
@@ -168,7 +182,7 @@ public:
FlatTriangulator();
~FlatTriangulator();
void ProjectOntoSurface(const std::vector<Base::Vector3f>&);
void PostProcessing(const std::vector<Base::Vector3f>&);
protected:
bool Triangulate();
@@ -187,17 +201,25 @@ private:
float fMaxArea;
};
#if 0
class MeshExport Triangulator : public AbstractPolygonTriangulator
{
public:
Triangulator(const MeshKernel&);
Triangulator(const MeshKernel&, bool flat);
~Triangulator();
void Discard();
void Reset();
bool NeedsReindexing() const { return false; }
MeshGeomFacet GetTriangle(const MeshPointArray&, const MeshFacet&) const;
void PostProcessing(const std::vector<Base::Vector3f>&);
protected:
bool Triangulate();
const MeshKernel& _kernel;
};
#endif
} // namespace MeshCore

View File

@@ -41,6 +41,11 @@
<UserDocu>Make a ruled surface of this and the given curves</UserDocu>
</Documentation>
</Methode>
<Methode Name="intersect2d">
<Documentation>
<UserDocu>Get intersection points with another curve lying on a plane.</UserDocu>
</Documentation>
</Methode>
<Methode Name="parameter">
<Documentation>
<UserDocu>Returns the parameter on the curve

View File

@@ -26,9 +26,13 @@
# include <BRepBuilderAPI_MakeEdge.hxx>
# include <gp_Dir.hxx>
# include <gp_Vec.hxx>
# include <gp_Pln.hxx>
# include <GCPnts_UniformAbscissa.hxx>
# include <Geom2dAPI_InterCurveCurve.hxx>
# include <GeomAPI.hxx>
# include <Geom_Geometry.hxx>
# include <Geom_Curve.hxx>
# include <Geom_Plane.hxx>
# include <Geom_Surface.hxx>
# include <GeomAdaptor_Curve.hxx>
# include <GeomFill.hxx>
@@ -48,6 +52,7 @@
#include "GeometryCurvePy.cpp"
#include "RectangularTrimmedSurfacePy.h"
#include "BSplineSurfacePy.h"
#include "PlanePy.h"
#include "TopoShape.h"
#include "TopoShapePy.h"
@@ -261,6 +266,41 @@ PyObject* GeometryCurvePy::makeRuledSurface(PyObject *args)
return 0;
}
PyObject* GeometryCurvePy::intersect2d(PyObject *args)
{
PyObject *c,*p;
if (!PyArg_ParseTuple(args, "O!O!", &(Part::GeometryCurvePy::Type), &c,
&(Part::PlanePy::Type), &p))
return 0;
try {
Handle_Geom_Curve self = Handle_Geom_Curve::DownCast(getGeometryPtr()->handle());
Handle_Geom_Curve curv = Handle_Geom_Curve::DownCast(static_cast<GeometryPy*>(c)->
getGeometryPtr()->handle());
Handle_Geom_Plane plane = Handle_Geom_Plane::DownCast(static_cast<GeometryPy*>(p)->
getGeometryPtr()->handle());
Handle_Geom2d_Curve curv1 = GeomAPI::To2d(self, plane->Pln());
Handle_Geom2d_Curve curv2 = GeomAPI::To2d(curv, plane->Pln());
Geom2dAPI_InterCurveCurve intCC(curv1, curv2);
int nbPoints = intCC.NbPoints();
Py::List list;
for (int i=1; i<= nbPoints; i++) {
gp_Pnt2d pt = intCC.Point(i);
Py::Tuple tuple(2);
tuple.setItem(0, Py::Float(pt.X()));
tuple.setItem(1, Py::Float(pt.Y()));
list.append(tuple);
}
return Py::new_reference_to(list);
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
PyErr_SetString(PyExc_Exception, e->GetMessageString());
return 0;
}
}
Py::Float GeometryCurvePy::getFirstParameter(void) const
{
return Py::Float(Handle_Geom_Curve::DownCast

View File

@@ -147,7 +147,7 @@ App::DocumentObjectExecReturn *Loft::execute(void)
return new App::DocumentObjectExecReturn("Linked shape is invalid.");
if (shape.ShapeType() == TopAbs_WIRE)
profiles.Append(shape);
else if (shape.ShapeType() == TopAbs_EDGE)
else if (shape.ShapeType() == TopAbs_VERTEX)
profiles.Append(shape);
else
return new App::DocumentObjectExecReturn("Linked shape is neither a vertex nor a wire.");

View File

@@ -63,7 +63,7 @@ class TestWorkbench ( Workbench ):
self.appendToolbar("TestTools",list)
menu = ["Test &Commands","TestToolsGui"]
list = ["Std_TestQM","Test_Test","Test_TestAll","Test_TestDoc","Test_TestBase"]
list = ["Std_TestQM","Std_TestReloadQM","Test_Test","Test_TestAll","Test_TestDoc","Test_TestBase"]
self.appendCommandbar("TestToolsGui",list)
self.appendMenu(menu,list)