Skip to content

Commit

Permalink
Added support for voronoi edges.
Browse files Browse the repository at this point in the history
  • Loading branch information
mlampert authored and sliptonic committed Sep 28, 2020
1 parent 27238c3 commit 6fc2af2
Show file tree
Hide file tree
Showing 14 changed files with 619 additions and 28 deletions.
18 changes: 11 additions & 7 deletions src/Mod/Path/App/AppPath.cpp
Expand Up @@ -47,6 +47,8 @@
#include "AreaPy.h"
#include "FeatureArea.h"
#include "Voronoi.h"
#include "VoronoiEdge.h"
#include "VoronoiEdgePy.h"
#include "VoronoiPy.h"
#include "VoronoiVertex.h"
#include "VoronoiVertexPy.h"
Expand All @@ -71,13 +73,14 @@ PyMOD_INIT_FUNC(Path)
Base::Console().Log("Loading Path module... done\n");

// Add Types to module
Base::Interpreter().addType(&Path::CommandPy ::Type, pathModule, "Command");
Base::Interpreter().addType(&Path::PathPy ::Type, pathModule, "Path");
Base::Interpreter().addType(&Path::ToolPy ::Type, pathModule, "Tool");
Base::Interpreter().addType(&Path::TooltablePy ::Type, pathModule, "Tooltable");
Base::Interpreter().addType(&Path::AreaPy ::Type, pathModule, "Area");
Base::Interpreter().addType(&Path::VoronoiPy ::Type, pathModule, "Voronoi");
Base::Interpreter().addType(&Path::VoronoiVertexPy ::Type, pathModule, "VoronoiVertex");
Base::Interpreter().addType(&Path::CommandPy ::Type, pathModule, "Command");
Base::Interpreter().addType(&Path::PathPy ::Type, pathModule, "Path");
Base::Interpreter().addType(&Path::ToolPy ::Type, pathModule, "Tool");
Base::Interpreter().addType(&Path::TooltablePy ::Type, pathModule, "Tooltable");
Base::Interpreter().addType(&Path::AreaPy ::Type, pathModule, "Area");
Base::Interpreter().addType(&Path::VoronoiPy ::Type, pathModule, "Voronoi");
Base::Interpreter().addType(&Path::VoronoiEdgePy ::Type, pathModule, "VoronoiEdge");
Base::Interpreter().addType(&Path::VoronoiVertexPy ::Type, pathModule, "VoronoiVertex");

// NOTE: To finish the initialization of our own type objects we must
// call PyType_Ready, otherwise we run into a segmentation fault, later on.
Expand All @@ -101,6 +104,7 @@ PyMOD_INIT_FUNC(Path)
Path::FeatureAreaView ::init();
Path::FeatureAreaViewPython ::init();
Path::Voronoi ::init();
Path::VoronoiEdge ::init();
Path::VoronoiVertex ::init();

PyMOD_Return(pathModule);
Expand Down
5 changes: 5 additions & 0 deletions src/Mod/Path/App/CMakeLists.txt
Expand Up @@ -37,6 +37,7 @@ generate_from_xml(FeaturePathCompoundPy)
generate_from_xml(AreaPy)
generate_from_xml(FeatureAreaPy)
generate_from_xml(VoronoiPy)
generate_from_xml(VoronoiEdgePy)
generate_from_xml(VoronoiVertexPy)

SET(Python_SRCS
Expand All @@ -56,6 +57,8 @@ SET(Python_SRCS
FeatureAreaPyImp.cpp
VoronoiPy.xml
VoronoiPyImp.cpp
VoronoiEdgePy.xml
VoronoiEdgePyImp.cpp
VoronoiVertexPy.xml
VoronoiVertexPyImp.cpp
)
Expand Down Expand Up @@ -98,6 +101,8 @@ SET(Path_SRCS
PathSegmentWalker.cpp
Voronoi.cpp
Voronoi.h
VoronoiEdge.cpp
VoronoiEdge.h
VoronoiVertex.cpp
VoronoiVertex.h
${Mod_SRCS}
Expand Down
43 changes: 43 additions & 0 deletions src/Mod/Path/App/Voronoi.cpp
Expand Up @@ -68,6 +68,48 @@ static void color_exterior(const Voronoi::diagram_type::edge_type *edge) {

// Constructors & destructors

int Voronoi::diagram_type::index(const Voronoi::diagram_type::cell_type *cell) const {
auto it = cell_index.find(intptr_t(cell));
if (it == cell_index.end()) {
return Voronoi::InvalidIndex;
}
return it->second;
}
int Voronoi::diagram_type::index(const Voronoi::diagram_type::edge_type *edge) const {
auto it = edge_index.find(intptr_t(edge));
if (it == edge_index.end()) {
return Voronoi::InvalidIndex;
}
return it->second;
}
int Voronoi::diagram_type::index(const Voronoi::diagram_type::vertex_type *vertex) const {
auto it = vertex_index.find(intptr_t(vertex));
if (it == vertex_index.end()) {
return Voronoi::InvalidIndex;
}
return it->second;
}

void Voronoi::diagram_type::reIndex() {
int idx = 0;
cell_index.clear();
edge_index.clear();
vertex_index.clear();

idx = 0;
for (auto it = cells().begin(); it != cells().end(); ++it, ++idx) {
cell_index[intptr_t(&(*it))] = idx;
}
idx = 0;
for (auto it = edges().begin(); it != edges().end(); ++it, ++idx) {
edge_index[intptr_t(&(*it))] = idx;
}
idx = 0;
for (auto it = vertices().begin(); it != vertices().end(); ++it, ++idx) {
vertex_index[intptr_t(&(*it))] = idx;
}
}

Voronoi::Voronoi()
:vd(new diagram_type)
{
Expand Down Expand Up @@ -103,4 +145,5 @@ void Voronoi::construct()
{
vd->clear();
construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), (voronoi_diagram_type*)vd);
vd->reIndex();
}
20 changes: 19 additions & 1 deletion src/Mod/Path/App/Voronoi.h
Expand Up @@ -46,6 +46,7 @@ namespace Path
Voronoi();
~Voronoi();

static const int InvalidIndex = INT_MAX;
// types
typedef double coordinate_type;
typedef boost::polygon::point_data<coordinate_type> point_type;
Expand All @@ -54,7 +55,24 @@ namespace Path
class diagram_type
: public voronoi_diagram_type
, public Base::Handled
{ };
{
public:

typedef std::map<intptr_t, int> cell_map_type;
typedef std::map<intptr_t, int> edge_map_type;
typedef std::map<intptr_t, int> vertex_map_type;

int index(const cell_type *cell) const;
int index(const edge_type *edge) const;
int index(const vertex_type *vertex) const;

void reIndex();

private:
cell_map_type cell_index;
edge_map_type edge_index;
vertex_map_type vertex_index;
};

// specific methods
void addPoint(const point_type &p);
Expand Down
76 changes: 76 additions & 0 deletions src/Mod/Path/App/VoronoiEdge.cpp
@@ -0,0 +1,76 @@
/***************************************************************************
* Copyright (c) sliptonic (shopinthewoods@gmail.com) 2020 *
* *
* 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 <cinttypes>
# include <iomanip>
# include <boost/algorithm/string.hpp>
# include <boost/lexical_cast.hpp>
#endif

#include <Base/Vector3D.h>
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Exception.h>
#include "Voronoi.h"
#include "VoronoiEdge.h"

using namespace Base;
using namespace Path;

TYPESYSTEM_SOURCE(Path::VoronoiEdge , Base::Persistence)

VoronoiEdge::VoronoiEdge(Voronoi::diagram_type *d, long index)
: dia(d)
, index(index)
, ptr(0)
{
if (dia && long(dia->num_edges()) > index) {
ptr = &(dia->edges()[index]);
}
}

VoronoiEdge::VoronoiEdge(Voronoi::diagram_type *d, const Voronoi::diagram_type::edge_type *e)
: dia(d)
, index(Voronoi::InvalidIndex)
, ptr(e)
{
if (d && e) {
index = dia->index(e);
}
}

VoronoiEdge::~VoronoiEdge() {
}

bool VoronoiEdge::isBound(void) const {
if (ptr != 0 && dia.isValid() && index != Voronoi::InvalidIndex) {
if (&(dia->edges()[index]) == ptr) {
return true;
}
}
ptr = 0;
return false;
}
54 changes: 54 additions & 0 deletions src/Mod/Path/App/VoronoiEdge.h
@@ -0,0 +1,54 @@
/***************************************************************************
* Copyright (c) sliptonic (shopinthewoods@gmail.com) 2020 *
* *
* 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 *
* *
***************************************************************************/
#ifndef PATH_VORONOIEDGE_H
#define PATH_VORONOIEDGE_H

#include <Base/Handle.h>
#include <Base/BaseClass.h>
#include <Base/Vector3D.h>
#include <Base/VectorPy.h>
#include "Voronoi.h"

namespace Path
{

class Voronoi;

class PathExport VoronoiEdge
: public Base::BaseClass
{
TYPESYSTEM_HEADER();
public:

VoronoiEdge(Voronoi::diagram_type *dia = 0, long index = Voronoi::InvalidIndex);
VoronoiEdge(Voronoi::diagram_type *dia, const Voronoi::diagram_type::edge_type *edge);
~VoronoiEdge();

bool isBound(void) const;

Base::Reference<Voronoi::diagram_type> dia;
long index;
mutable const Voronoi::diagram_type::edge_type *ptr;
};

}
#endif
101 changes: 101 additions & 0 deletions src/Mod/Path/App/VoronoiEdgePy.xml
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="BaseClassPy"
Name="VoronoiEdgePy"
Twin="VoronoiEdge"
TwinPointer="VoronoiEdge"
Include="Mod/Path/App/Voronoi.h"
FatherInclude="Base/BaseClassPy.h"
Namespace="Path"
FatherNamespace="Base"
Constructor="true"
RichCompare="true"
Delete="true">
<Documentation>
<Author Licence="LGPL" Name="sliptonic" EMail="shopinthewoods@gmail.com" />
<UserDocu>Edge of a Voronoi diagram</UserDocu>
</Documentation>
<Attribute Name="Color" ReadOnly="false">
<Documentation>
<UserDocu>Assigned color of the receiver.</UserDocu>
</Documentation>
<Parameter Name="Color" Type="Int"/>
</Attribute>
<!--
<Attribute Name="Cell" ReadOnly="true">
<Documentation>
<UserDocu>cell the edge belongs to</UserDocu>
</Documentation>
<Parameter Name="Cell" Type="Object"/>
</Attribute>
-->
<Attribute Name="Vertices" ReadOnly="true">
<Documentation>
<UserDocu>Begin and End voronoi vertex</UserDocu>
</Documentation>
<Parameter Name="Vertices" Type="List"/>
</Attribute>
<Attribute Name="Next" ReadOnly="true">
<Documentation>
<UserDocu>CCW next edge whithin voronoi cell</UserDocu>
</Documentation>
<Parameter Name="Next" Type="Object"/>
</Attribute>
<Attribute Name="Prev" ReadOnly="true">
<Documentation>
<UserDocu>CCW previous edge whithin voronoi cell</UserDocu>
</Documentation>
<Parameter Name="Prev" Type="Object"/>
</Attribute>
<Attribute Name="RotatedNext" ReadOnly="true">
<Documentation>
<UserDocu>Rotated CCW next edge whithin voronoi cell</UserDocu>
</Documentation>
<Parameter Name="RotatedNext" Type="Object"/>
</Attribute>
<Attribute Name="RotatedPrev" ReadOnly="true">
<Documentation>
<UserDocu>Rotated CCW previous edge whithin voronoi cell</UserDocu>
</Documentation>
<Parameter Name="RotatedPrev" Type="Object"/>
</Attribute>
<Attribute Name="Twin" ReadOnly="true">
<Documentation>
<UserDocu>Twin edge</UserDocu>
</Documentation>
<Parameter Name="Twin" Type="Object"/>
</Attribute>
<Methode Name="isFinite" Const="true">
<Documentation>
<UserDocu>Returns true if both vertices are finite</UserDocu>
</Documentation>
</Methode>
<Methode Name="isInfinite" Const="true">
<Documentation>
<UserDocu>Returns true if the end vertex is infinite</UserDocu>
</Documentation>
</Methode>
<Methode Name="isLinear" Const="true">
<Documentation>
<UserDocu>Returns true if edge is straight</UserDocu>
</Documentation>
</Methode>
<Methode Name="isCurved" Const="true">
<Documentation>
<UserDocu>Returns true if edge is curved</UserDocu>
</Documentation>
</Methode>
<Methode Name="isPrimary" Const="true">
<Documentation>
<UserDocu>Returns false if edge goes through endpoint of the segment site</UserDocu>
</Documentation>
</Methode>
<Methode Name="isSecondary" Const="true">
<Documentation>
<UserDocu>Returns true if edge goes through endpoint of the segment site</UserDocu>
</Documentation>
</Methode>
-->
</PythonExport>
</GenerateModel>

0 comments on commit 6fc2af2

Please sign in to comment.