Compare commits

...

5 Commits

  1. 4
      .gitignore
  2. 41
      CMakeLists.txt
  3. 1
      include/Astar.h
  4. 1
      include/BVH.h
  5. 1
      include/BasicChannel.h
  6. 1
      include/BasicEdge.h
  7. 3
      include/BranchPoint.h
  8. 1
      include/BranchTree.h
  9. 1
      include/Bundle.h
  10. 1
      include/Clip.h
  11. 1
      include/Connector.h
  12. 1
      include/Const.h
  13. 88
      include/Geometry.h
  14. 243
      include/Intersection.h
  15. 1
      include/KDtree.h
  16. 10
      include/Path.h
  17. 130
      include/Point.h
  18. 47
      include/ReadXML.h
  19. 28
      include/stdafx.h
  20. 22
      lib/CMakeLists.txt
  21. 37
      lib/Geometry.cpp
  22. 101
      lib/Point.cpp
  23. 181
      src/Intersection.cpp
  24. 8
      src/stdafx.cpp
  25. 24
      src/xmlsql.cpp

4
.gitignore

@ -5,4 +5,6 @@
# MacOS
.DS_Store
# cmake build dir
build/
build/
lib/Debug/
lib/Release/

41
CMakeLists.txt

@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.16)
#------------REQUIRED_2 ------------#
project(
WireRouting # 这里没有添加任何的目标(target)
WireRoutingProject # 这里没有添加任何的目标(target)
VERSION 1.0
DESCRIPTION "A project for wire routing" # CMake 3.9+
# C,CXX,Fortran,ASM,CUDA(CMake 3.8+),CSharp(3.8+),SWIFT(CMake 3.15+ experimental)
@ -16,7 +16,7 @@ project(
#------------REQUIRED_4 C++------------#
# !!!使!!!使set_target_properties/set_property
# C++ 11(STRING) CMakeCache.txt
set(CMAKE_CXX_STANDARD 11 CACHE STRING "The C++ standard to use")
set(CMAKE_CXX_STANDARD 17 CACHE STRING "The C++ standard to use")
# CMake 使
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 使 -std=c++11 -std=g++11
@ -42,7 +42,7 @@ elseif (WIN32)
list(PREPEND CMAKE_PREFIX_PATH D:/SOURCE/Dependencies) # Windows
set(CMAKE_TOOLCHAIN_FILE "D:\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake") # vcpkg
include(${CMAKE_TOOLCHAIN_FILE})
find_package(tinyxml CONFIG REQUIRED)
find_package(tinyxml2 CONFIG REQUIRED)
elseif (UNIX)
list(PREPEND CMAKE_PREFIX_PATH /home/yony/PROJECTS/Dependencies) # Linux
find_package(tinyxml CONFIG REQUIRED)
@ -64,7 +64,7 @@ message(STATUS "Self added CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}")
# igl_include(glfw) # igl_include_optional(glfw) Enable the target igl::glfw
ADD_SUBDIRECTORY(lib)
#------------REQUIRED_3 ------------#
# 使fileGLOB CMakeMake
@ -75,23 +75,30 @@ add_executable(
${SRC_DIR}
)
# warning C4530: 使 C++ /EHsc
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/EHsc")
# add_custom_command(
# TARGET ${PROJECT_NAME} POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy_directory
# ${CMAKE_SOURCE_DIR}/lib/$(IntDir)/WireRouting.dll $(outdir)
# )
# file(COPY ${CMAKE_SOURCE_DIR}/lib/Debug/WireRouting.dll DESTINATION ${PROJECT_BINARY_DIR}/Debug)
#------------REQUIRED_5.2 CMake ------------#
# target_link_libraries(${PROJECT_NAME} PUBLIC {lib_name1} {lib_name1} ...)
# CMakeLists.txt
# target_include_directories <lib_name>/include <LIB_NAME>_INCLUDE_DIRS
if (WIN32)
target_link_libraries(
${PROJECT_NAME} PUBLIC
unofficial-tinyxml::unofficial-tinyxml
)
else()
target_link_libraries(
${PROJECT_NAME} PUBLIC
/opt/homebrew/Cellar/tinyxml/2.6.2/lib/libtinyxml.dylib
)
endif()
target_link_libraries(
${PROJECT_NAME} PUBLIC
tinyxml2::tinyxml2
)
target_link_libraries(
${PROJECT_NAME} PUBLIC
${PROJECT_SOURCE_DIR}/lib/Debug/WireRouting.lib
)
#------------OPTIONAL_1.2 config.h------------#
@ -102,9 +109,7 @@ target_include_directories(
# INTERFACE
${PROJECT_NAME} PUBLIC
${PROJECT_BINARY_DIR} # config.h.in build
include
${TINYXML_INCLUDE_DIR} # tinyxml
${TINYXML_INCLUDE_DIRS} # pkg-config tinyxml dir
${CMAKE_SOURCE_DIR}/include
)
# TODO: MSVC msvc_19.29_cxx11_32_md_debugdll/lib

1
include/Astar.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "BranchTree.h"
#include <cmath>
#include <vector>

1
include/BVH.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "ReadXML.h"
#include <cmath>
#include <vector>

1
include/BasicChannel.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "Bundle.h"
#include <cmath>
#include <vector>

1
include/BasicEdge.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "BasicChannel.h"
#include <cmath>
#include <vector>

3
include/BranchPoint.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "Clip.h"
#include <cmath>
#include <vector>
@ -7,6 +6,8 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <assert.h>
using namespace std;
// 分支点数据类型

1
include/BranchTree.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "BasicEdge.h"
#include <cmath>
#include <vector>

1
include/Bundle.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "Path.h"
#include <cmath>
#include <vector>

1
include/Clip.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "KDtree.h"
#include <cmath>
#include <vector>

1
include/Connector.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "Const.h"
#include <cmath>
#include <vector>

1
include/Const.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "Point.h"
#include "Geometry.h"
#include "Intersection.h"

88
include/Geometry.h

@ -1,5 +1,11 @@
#pragma once
#ifdef _WIN32
#define GEOMETRY_API __declspec(dllexport)
#else
#define GEOMETRY_API
#endif
#include <numeric>
#include <limits>
#include <cmath>
@ -47,37 +53,25 @@ public:
return a;
}
// Vec3 operator+(const Vec3 &other) const {
// return {a + other.a, b + other.b, c + other.c};
// }
Vec3 operator+(const Vec3 &other) const
{
return Vec3(a + other.a, b + other.b, c + other.c);
} // VS2008
}
// Vec3 operator/(const float w) const {
// return {a / w, b / w, c / w};
// }
Vec3 operator/(const float w) const
{
return Vec3(a / w, b / w, c / w);
} // VS2008
}
// Vec3 operator-(const Vec3 &other) const {
// return {a - other.a, b - other.b, c - other.c};
// }
Vec3 operator-(const Vec3 &other) const
{
return Vec3(a - other.a, b - other.b, c - other.c);
} // VS2008
}
// Vec3 operator*(const float &w) const {
// return {a * w, b * w, c * w};
// }
Vec3 operator*(const float &w) const
{
return Vec3(a * w, b * w, c * w);
} // VS2008
}
float length() const
{
@ -89,9 +83,6 @@ public:
return *this / length();
}
// Vec3 cross(const Vec3 &other) const {
// return {b * other.c - c * other.b, c * other.a - a * other.c, a * other.b - b * other.a};
// }
Vec3 cross(const Vec3 &other) const
{
return Vec3(b * other.c - c * other.b, c * other.a - a * other.c, a * other.b - b * other.a);
@ -106,76 +97,43 @@ public:
typedef Vec3<float> Vec3f;
typedef Vec3<unsigned int> Vec3u;
class Mesh
extern "C" class GEOMETRY_API Mesh
{
public:
std::vector<Vec3f> vertices;
std::vector<Vec3u> indices;
};
class AABB
extern "C" class GEOMETRY_API AABB
{
public:
Vec3f min, max;
/*
AABB()
:min(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(),std::numeric_limits<float>::max()),
max(std::numeric_limits<float>::min(), std::numeric_limits<float>::min(),std::numeric_limits<float>::min())
{}
*/
AABB()
{
min = Vec3f(1e5, 1e5, 1e5);
max = Vec3f(0, 0, 0);
}
AABB();
};
class LineSegment
extern "C" class GEOMETRY_API LineSegment
{
public:
Vec3f start;
Vec3f end;
float length;
Vec3f dir;
// LineSegment(const Vec3f &s, const Vec3f &e) : start(s), end(e) {
// length = (end - start).length();
// dir = (end - start).norm();
// }
LineSegment(const Vec3f &s, const Vec3f &e) : start(s), end(e)
{
calculate();
}
LineSegment(const Vec3f &s, const Vec3f &e);
float getLength() const
{
return length;
}
float getLength() const;
Vec3f getDir() const
{
return dir;
}
Vec3f getDir() const;
// private:
float length;
Vec3f dir;
void calculate()
{ // VS2008
Vec3f diff = end - start; // VS2008
length = diff.length(); // VS2008
dir = diff.norm(); // VS2008
} // VS2008
void calculate();
};
struct FaceCenterComparator
extern "C" struct GEOMETRY_API FaceCenterComparator
{
const std::vector<Vec3f> &faceCenters; // Ìæ»» YourVectorType ΪÄãµÄÏòÁ¿ÀàÐÍ
int longAxis;
FaceCenterComparator(const std::vector<Vec3f> &centers, int axis)
: faceCenters(centers), longAxis(axis) {}
FaceCenterComparator(const std::vector<Vec3f> &centers, int axis);
bool operator()(const size_t &a, const size_t &b) const
{
return faceCenters[a][longAxis] < faceCenters[b][longAxis];
}
bool operator()(const size_t &a, const size_t &b) const;
};

243
include/Intersection.h

@ -1,40 +1,30 @@
#pragma once
#ifdef _WIN32
#define INTERSECTION_API __declspec(dllexport)
#else
#define INTERSECTION_API
#endif
#include "Geometry.h"
#include <numeric>
#include <algorithm>
#include <vector>
#include <cstddef>
#include "Geometry.h"
#include <iostream> // std::cerr
#include <stdexcept> // std::length_error
struct TriangleSegmentIntersectRes
extern "C" struct INTERSECTION_API TriangleSegmentIntersectRes
{
bool hit;
float t;
TriangleSegmentIntersectRes(bool h, float tt) : hit(h), t(tt) {} // VS2008
TriangleSegmentIntersectRes(bool h, float tt);
};
TriangleSegmentIntersectRes
triangleSegmentIntersection(const LineSegment &segment, const Vec3f &a, const Vec3f &b, const Vec3f &c)
{
Vec3f e1 = b - a;
Vec3f e2 = c - a;
Vec3f s = segment.start - a;
Vec3f s1 = segment.getDir().cross(e2);
Vec3f s2 = s.cross(e1);
float s1_dot_e1 = s1.dot(e1);
float b1 = s1.dot(s) / s1_dot_e1;
float b2 = s2.dot(segment.getDir()) / s1_dot_e1;
if (b1 >= 0. && b2 >= 0. && b1 + b2 <= 1.)
{
// hit
// return {true, s2.dot(e2) / s1_dot_e1};
return TriangleSegmentIntersectRes(true, s2.dot(e2) / s1_dot_e1); // VS2008
}
// return {false, 0.};
return TriangleSegmentIntersectRes(false, 0.f); // VS2008
}
INTERSECTION_API
TriangleSegmentIntersectRes triangleSegmentIntersection(const LineSegment &segment, const Vec3f &a, const Vec3f &b, const Vec3f &c);
class BVHNode
extern "C" class INTERSECTION_API BVHNode
{
public:
size_t left;
@ -42,210 +32,27 @@ public:
size_t parent;
AABB boundingBox;
BVHNode(size_t l, size_t r, size_t p, const AABB &aabb) : left(l), right(r), parent(p), boundingBox(aabb) {}
BVHNode() : left(0), right(0), parent(0), boundingBox() {}
BVHNode(size_t l, size_t r, size_t p, const AABB &aabb);
BVHNode();
};
class BVH_intersection
extern "C" class INTERSECTION_API BVH_intersection
{
public:
const Mesh &mesh;
std::vector<Vec3f> faceCenters;
std::vector<BVHNode> nodes;
BVH_intersection(const Mesh &mesh_) : mesh(mesh_)
{
// ??????????????????
faceCenters.reserve(mesh.indices.size());
for (std::vector<Vec3u>::const_iterator it = mesh.indices.begin(); it != mesh.indices.end(); ++it)
{
const Vec3u &face = *it;
Vec3f center = (mesh.vertices[face[0]] + mesh.vertices[face[1]] + mesh.vertices[face[2]]) / 3.0f;
faceCenters.push_back(center);
} // VS2008
// indicesList ????0,1,2...?C++11iota??
// std::iota(indicesList.begin(), indicesList.end(), 0);
std::vector<size_t> indicesList(mesh.indices.size());
for (size_t i = 0; i < indicesList.size(); ++i)
{
indicesList[i] = i;
}
// ??BVH????
try
{
nodes.resize(2 * mesh.indices.size() - 1);
}
catch (const std::length_error &e)
{
std::cout << "vector.length:" << nodes.size() << " resize_pa:" << (2 * mesh.indices.size() - 1) << std::endl;
std::cerr << "Caught a length_error: " << e.what() << std::endl;
}
BVH_intersection(const Mesh &mesh_);
size_t
dfsBuild(std::vector<size_t> &indicesList, AABB aabb, size_t &nowIdx);
bool intersectWithLineSegment(const LineSegment &lineSegment) const;
size_t nowIdx = 0;
dfsBuild(indicesList, computeAABB(indicesList), nowIdx);
}
// BVH???
size_t dfsBuild(std::vector<size_t> &indicesList, AABB aabb, size_t &nowIdx)
{
const size_t nodeIdx = nowIdx;
nowIdx++;
if (indicesList.size() == 1)
{
// leaf
nodes[nodeIdx] = BVHNode(0, indicesList[0], 0, aabb); // VS2008
return nodeIdx;
}
// longest axis
int longAxis = -1;
float longAxisLen = -1;
for (int i = 0; i < 3; ++i)
{
const float axisLen = aabb.max[i] - aabb.min[i];
if (axisLen > longAxisLen)
{
longAxisLen = axisLen;
longAxis = i;
}
}
// split indices list
const size_t k = indicesList.size() / 2;
// std::nth_element(indicesList.begin(), indicesList.begin() + k - 1, indicesList.end(),
// [&](const size_t &a, const size_t &b) {
// return faceCenters[a][longAxis] < faceCenters[b][longAxis];
// });
nth(indicesList, k - 1, longAxis);
std::vector<size_t> leftIndices(indicesList.begin(), indicesList.begin() + k);
std::vector<size_t> rightIndices(indicesList.begin() + k, indicesList.end());
const AABB leftAABB = computeAABB(leftIndices);
const AABB rightAABB = computeAABB(rightIndices);
const size_t leftIdx = dfsBuild(leftIndices, leftAABB, nowIdx);
const size_t rightIdx = dfsBuild(rightIndices, rightAABB, nowIdx);
// nodes[nodeIdx] = {leftIdx, rightIdx, 0, aabb};
nodes[nodeIdx] = BVHNode(leftIdx, rightIdx, 0, aabb); // VS2008
nodes[leftIdx].parent = nodeIdx;
nodes[rightIdx].parent = nodeIdx;
return nodeIdx;
}
bool intersectWithLineSegment(const LineSegment &lineSegment) const
{
return recursiveLineSegIntersection(lineSegment, 0);
}
// private:
// AABB computeAABB(const std::vector<size_t> &indices) {
// AABB aabb;
// for (const size_t &idx: indices) {
// const Vec3u &face = mesh.indices[idx];
// for (int i = 0; i < 3; ++i) {
// const Vec3f &vertex = mesh.vertices[face[i]];
// for (int j = 0; j < 3; ++j) {
// aabb.min[j] = std::min(aabb.min[j], vertex[j]);
// aabb.max[j] = std::max(aabb.max[j], vertex[j]);
// }
// }
// }
// return {aabb.min, aabb.max};
// }
private:
// ??????????????AABB??????????AABB
AABB computeAABB(const std::vector<size_t> &indices)
{
AABB aabb;
for (std::vector<size_t>::const_iterator it = indices.begin(); it != indices.end(); ++it)
{
const Vec3u &face = mesh.indices[*it];
for (int i = 0; i < 3; ++i)
{
const Vec3f &vertex = mesh.vertices[face[i]];
for (int j = 0; j < 3; ++j)
{
aabb.min[j] = min(aabb.min[j], vertex[j]);
aabb.max[j] = max(aabb.max[j], vertex[j]);
}
}
}
return aabb;
}
bool recursiveLineSegIntersection(const LineSegment &lineSegment, size_t nodeIdx) const
{
// segment-box intersection test
const AABB &aabb = nodes[nodeIdx].boundingBox;
const Vec3f &dir = lineSegment.getDir();
bool hit = false;
for (int i = 0; !hit && i < 3; ++i)
{
float t_min = (aabb.min[i] - lineSegment.start[i]) / dir[i];
float t_max = (aabb.max[i] - lineSegment.start[i]) / dir[i];
if (t_min > t_max)
{
std::swap(t_min, t_max);
}
if (t_min > lineSegment.getLength() || t_max < 0)
return false;
Vec3f hitPt = lineSegment.start + dir * t_min;
int otherPlane1 = (i + 1) % 3, otherPlane2 = (i + 2) % 3;
if (hitPt[otherPlane1] >= aabb.min[otherPlane1] && hitPt[otherPlane1] <= aabb.max[otherPlane1] &&
hitPt[otherPlane2] >= aabb.min[otherPlane2] && hitPt[otherPlane2] <= aabb.max[otherPlane2])
{
hit = true;
}
}
if (hit)
{
if (nodes[nodeIdx].left == 0)
{
// leaf
Vec3u face = mesh.indices[nodes[nodeIdx].right];
TriangleSegmentIntersectRes res = triangleSegmentIntersection(lineSegment, mesh.vertices[face[0]], mesh.vertices[face[1]],
mesh.vertices[face[2]]);
if (!res.hit || res.t < 0 || res.t > lineSegment.getLength())
return false;
return true;
}
else
{
// check children
return recursiveLineSegIntersection(lineSegment, nodes[nodeIdx].left) ||
recursiveLineSegIntersection(lineSegment, nodes[nodeIdx].right);
}
}
return false;
}
AABB computeAABB(const std::vector<size_t> &indices);
bool recursiveLineSegIntersection(const LineSegment &lineSegment, size_t nodeIdx) const;
// implement nth, without std::nth_element
// kth is 0-based
void nth(std::vector<size_t> &indicesList, size_t kth, int longAxis)
{
recursiveChoose(indicesList, 0, indicesList.size() - 1, kth, longAxis);
}
void recursiveChoose(std::vector<size_t> &indicesList, size_t begin, size_t end, size_t kth, int longAxis)
{
if (begin >= end)
return;
int i = begin, j = end;
while (i < j)
{
while (i < j && faceCenters[indicesList[j]][longAxis] >= faceCenters[indicesList[begin]][longAxis])
j--;
while (i < j && faceCenters[indicesList[i]][longAxis] <= faceCenters[indicesList[begin]][longAxis])
i++;
std::swap(indicesList[i], indicesList[j]);
}
std::swap(indicesList[begin], indicesList[i]);
if (i == kth)
return;
if (i < kth)
recursiveChoose(indicesList, i + 1, end, kth, longAxis);
else
recursiveChoose(indicesList, begin, i - 1, kth, longAxis);
}
void nth(std::vector<size_t> &indicesList, size_t kth, int longAxis);
void recursiveChoose(std::vector<size_t> &indicesList, size_t begin, size_t end, size_t kth, int longAxis);
};

1
include/KDtree.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "BVH.h"
#include <cmath>
#include <vector>

10
include/Path.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "BranchPoint.h"
#include <cmath>
#include <vector>
@ -9,7 +8,14 @@
#include <sstream>
#include <algorithm>
using namespace std;
P dirP(P &A)
{
P B;
B.x = A.dx;
B.y = A.dy;
B.z = A.dz;
return B;
}
// 简单的路径信息,路径规划的直接结果
struct Path
{

130
include/Point.h

@ -1,11 +1,24 @@
#pragma once
#ifdef _WIN32
#define POINT_API __declspec(dllexport)
#else
#define POINT_API
#endif
#include <string>
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
const double eps = 1e-6;
#define Equal(a, b) ((fabs(a - b) < eps) ? true : false)
struct P
extern "C" POINT_API const double eps = 1e-6;
extern "C" POINT_API bool Equal(double a, double b);
extern "C" struct POINT_API P
{
double x, y, z; // 坐标
double dx, dy, dz; // 方向
@ -13,106 +26,23 @@ struct P
int type; // 0卡箍 1未确定分支点 2已确定分支点 3连接器
int ref; // 指向其代表的相应数据类型标号
bool operator<(P B) const
{
if (!Equal(x, B.x))
return x < B.x;
if (!Equal(y, B.y))
return y < B.y;
if (!Equal(z, B.z))
return z < B.z;
return false;
}
bool operator==(P B) const
{
return Equal(x, B.x) && Equal(y, B.y) && Equal(z, B.z);
}
bool operator!=(P B) const
{
return !(Equal(x, B.x) && Equal(y, B.y) && Equal(z, B.z));
}
bool operator<(P B) const;
bool operator==(P B) const;
bool operator!=(P B) const;
void set(int i, double v)
{
if (i == 0)
x = v;
else if (i == 1)
y = v;
else if (i == 2)
z = v;
}
const double get(int i)
{
if (i == 0)
return x;
else if (i == 1)
return y;
else if (i == 2)
return z;
void set(int i, double v);
const double get(int i);
return 0;
}
void reverse();
void reverse()
{
dx = -dx;
dy = -dy;
dz = -dz;
}
P(double x1, double y1, double z1)
{
x = x1;
y = y1;
z = z1;
dx = 0;
dy = dz = 0;
isend = 0;
type = ref = 0;
}
P()
{
x = y = z = 0;
dx = 0;
dy = dz = 0;
isend = 0;
type = ref = 0;
}
P operator-(P B) const
{
return P(x - B.x, y - B.y, z - B.z);
}
P operator+(P B) const
{
return P(x + B.x, y + B.y, z + B.z);
}
P operator*(double p) const
{
return P(x * p, y * p, z * p);
}
P operator/(double p) const
{
return P(x / p, y / p, z / p);
}
void print(string s)
{
cout << s << setprecision(10) << " : " << x << " " << y << " " << z << endl;
return;
}
P(double x1, double y1, double z1);
P();
P operator-(P B) const;
P operator+(P B) const;
P operator*(double p) const;
P operator/(double p) const;
void print(string s);
// 设置方向
void setDir(const P &dir)
{
dx = dir.x;
dy = dir.y;
dz = dir.z;
}
void setDir(const P &dir);
};
P dirP(P &A)
{
P B;
B.x = A.dx;
B.y = A.dy;
B.z = A.dz;
return B;
}

47
include/ReadXML.h

@ -1,4 +1,3 @@
#include "stdafx.h"
#include "Connector.h"
#include <string>
#include <map>
@ -7,7 +6,9 @@
#include <cmath>
#include <fstream>
#include <sstream>
using namespace std;
string ini = "--";
// Őë˝Ĺ
@ -85,11 +86,11 @@ void init_readxml()
cnt = 0;
}
void producePin(TiXmlElement *pin)
void producePin(tinyxml2::XMLElement *pin)
{
pinidmap[pin->Attribute("id")] = pin->Attribute("name");
}
string safegave(TiXmlElement *pEle, const char *t)
string safegave(tinyxml2::XMLElement *pEle, const char *t)
{
if (pEle->Attribute(t) == NULL)
return ini;
@ -103,7 +104,7 @@ string safegave(TiXmlElement *pEle, const char *t)
}
}
TiXmlElement *GetNodePointerByName(TiXmlElement *pRootEle, const char *strNodeName)
tinyxml2::XMLElement *GetNodePointerByName(tinyxml2::XMLElement *pRootEle, const char *strNodeName)
{
// if equal root node then return
if (0 == strcmp(strNodeName, pRootEle->Value()))
@ -111,13 +112,13 @@ TiXmlElement *GetNodePointerByName(TiXmlElement *pRootEle, const char *strNodeNa
return pRootEle;
}
TiXmlElement *pEle = pRootEle;
tinyxml2::XMLElement *pEle = pRootEle;
for (pEle = pRootEle->FirstChildElement(); pEle; pEle = pEle->NextSiblingElement())
{
// recursive find sub node return node pointer
if (0 != strcmp(pEle->Value(), strNodeName))
{
TiXmlElement *res = GetNodePointerByName(pEle, strNodeName);
tinyxml2::XMLElement *res = GetNodePointerByName(pEle, strNodeName);
if (res != NULL)
return res;
}
@ -127,10 +128,10 @@ TiXmlElement *GetNodePointerByName(TiXmlElement *pRootEle, const char *strNodeNa
return NULL;
}
TiXmlElement *GetNextNodePointerByName(TiXmlElement *pRootEle, const char *strNodeName)
tinyxml2::XMLElement *GetNextNodePointerByName(tinyxml2::XMLElement *pRootEle, const char *strNodeName)
{
// if equal root node then return
TiXmlElement *pEle;
tinyxml2::XMLElement *pEle;
for (pEle = pRootEle->NextSiblingElement(); pEle; pEle = pEle->NextSiblingElement())
{
// recursive find sub node return node pointer
@ -139,7 +140,7 @@ TiXmlElement *GetNextNodePointerByName(TiXmlElement *pRootEle, const char *strNo
}
return NULL;
}
void produceConnector(TiXmlElement *pcon)
void produceConnector(tinyxml2::XMLElement *pcon)
{
Connector con;
con.id = pcon->Attribute("id");
@ -154,8 +155,8 @@ void produceConnector(TiXmlElement *pcon)
connectors[connectorNum] = con;
TiXmlElement *pEle;
TiXmlElement *p;
tinyxml2::XMLElement *pEle;
tinyxml2::XMLElement *p;
for (pEle = pcon->FirstChildElement(); pEle; pEle = pEle->NextSiblingElement())
{
if (strcmp(pEle->Value(), "backshell") == 0)
@ -185,14 +186,14 @@ void produceConnector(TiXmlElement *pcon)
}
}
void produceWire(TiXmlElement *pwire)
void produceWire(tinyxml2::XMLElement *pwire)
{
Pin sn, en;
TiXmlElement *pconnection = GetNodePointerByName(pwire, "connection");
tinyxml2::XMLElement *pconnection = GetNodePointerByName(pwire, "connection");
if (pconnection != NULL)
{
sn = pinmap[pconnection->Attribute("pinref")];
TiXmlElement *pconnection2 = GetNextNodePointerByName(pconnection, "connection");
tinyxml2::XMLElement *pconnection2 = GetNextNodePointerByName(pconnection, "connection");
if (pconnection2 != NULL)
en = pinmap[pconnection2->Attribute("pinref")];
else
@ -242,7 +243,7 @@ void produceWire(TiXmlElement *pwire)
wire_node[p] = bd;
}
}
void produce(TiXmlElement *pEle)
void produce(tinyxml2::XMLElement *pEle)
{
if (strcmp(pEle->Value(), "wire") == 0)
produceWire(pEle);
@ -250,7 +251,7 @@ void produce(TiXmlElement *pEle)
produceConnector(pEle);
return;
}
void ProduceNodePointerByName(TiXmlElement *pRootEle, const char *strNodeName)
void ProduceNodePointerByName(tinyxml2::XMLElement *pRootEle, const char *strNodeName)
{
// if equal root node then return
if (0 == strcmp(strNodeName, pRootEle->Value()))
@ -259,7 +260,7 @@ void ProduceNodePointerByName(TiXmlElement *pRootEle, const char *strNodeName)
return;
}
TiXmlElement *pEle = pRootEle;
tinyxml2::XMLElement *pEle = pRootEle;
for (pEle = pRootEle->FirstChildElement(); pEle; pEle = pEle->NextSiblingElement())
{
// recursive find sub node return node pointer
@ -275,7 +276,7 @@ void ProduceNodePointerByName(TiXmlElement *pRootEle, const char *strNodeName)
return;
}
void readxml(const char *xml, const char *connectorFile)
void readxml(const string xml, const string connectorFile)
{
init_readxml();
ifstream infile;
@ -299,15 +300,17 @@ void readxml(const char *xml, const char *connectorFile)
mp[fields[0]] = P(atof(fields[1].c_str()), atof(fields[2].c_str()), atof(fields[3].c_str()));
}
TiXmlDocument *pDoc = new TiXmlDocument(xml);
if (!(pDoc->LoadFile()))
tinyxml2::XMLDocument pDoc;
tinyxml2::XMLError error = pDoc.LoadFile(xml.c_str());
if (error != tinyxml2::XMLError::XML_SUCCESS)
return;
// pDoc->Print();
// ťńľĂ¸ůÔŞËŘŁŹź´PersonsĄŁ
// cout<<"connectivity"<<endl<<endl;
TiXmlElement *RootElement = pDoc->RootElement();
TiXmlElement *connectivity = GetNodePointerByName(RootElement, "connectivity");
tinyxml2::XMLElement *RootElement = pDoc.RootElement();
tinyxml2::XMLElement *connectivity = GetNodePointerByName(RootElement, "connectivity");
// cout<<(connectivity->Value())<<endl;
// cout<<(connectivity->Attribute("id")==NULL)<<endl;
ProduceNodePointerByName(connectivity, "connector");

28
include/stdafx.h

@ -1,28 +0,0 @@
// stdafx.h : ��׼ϵͳ�����ļ��İ����ļ���
// ���Ǿ���ʹ�õ��������ĵ�
// �ض�����Ŀ�İ����ļ�
//
#pragma once
#pragma comment(lib, "tinyxml.lib")
#pragma once
#define Word Microsoft::Office::Interop::Word
#include "targetver.h"
#include <stdio.h>
#ifdef _WIN32
#include <tchar.h>
#include <windows.h>
#include <atlstr.h>
#endif
#include <ctype.h>
#include <iostream>
#include <tinyxml.h>
// #include <tinystr.h>
// TODO: �ڴ˴����ó�����Ҫ������ͷ�ļ�

22
lib/CMakeLists.txt

@ -0,0 +1,22 @@
aux_source_directory(${CMAKE_SOURCE_DIR}/lib SRC_FILES_IN_LIB)
message(STATUS "SRC_FILES_IN_LIB: ${SRC_FILES_IN_LIB}")
add_library(WireRouting SHARED ${SRC_FILES_IN_LIB})
target_compile_definitions(WireRouting PUBLIC -DMY_LIB_SHARED_BUILD)
target_compile_definitions(WireRouting PRIVATE -DMY_LIB_EXPORTS)
INSTALL(TARGETS WireRouting DESTINATION ${CMAKE_SOURCE_DIR}/lib)
SET_TARGET_PROPERTIES(
WireRouting PROPERTIES LINKER_LANGUAGE C
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib
OUTPUT_NAME "WireRouting"
PREFIX ""
)
target_include_directories(
WireRouting PUBLIC
${CMAKE_SOURCE_DIR}/include
)

37
lib/Geometry.cpp

@ -0,0 +1,37 @@
#include "Geometry.h"
AABB::AABB()
{
min = Vec3f(1e5, 1e5, 1e5);
max = Vec3f(0, 0, 0);
}
LineSegment::LineSegment(const Vec3f &s, const Vec3f &e) : start(s), end(e)
{
calculate();
}
float LineSegment::getLength() const
{
return length;
}
Vec3f LineSegment::getDir() const
{
return dir;
}
void LineSegment::calculate()
{
Vec3f diff = end - start;
length = diff.length();
dir = diff.norm();
}
FaceCenterComparator::FaceCenterComparator(const std::vector<Vec3f> &centers, int axis)
: faceCenters(centers), longAxis(axis) {}
bool FaceCenterComparator::operator()(const size_t &a, const size_t &b) const
{
return faceCenters[a][longAxis] < faceCenters[b][longAxis];
}

101
lib/Point.cpp

@ -0,0 +1,101 @@
#include "Point.h"
bool Equal(double a, double b)
{
return ((fabs(a - b) < eps) ? true : false);
}
bool P::operator<(P B) const
{
if (!Equal(x, B.x))
return x < B.x;
if (!Equal(y, B.y))
return y < B.y;
if (!Equal(z, B.z))
return z < B.z;
return false;
}
bool P::operator==(P B) const
{
return Equal(x, B.x) && Equal(y, B.y) && Equal(z, B.z);
}
bool P::operator!=(P B) const
{
return !(Equal(x, B.x) && Equal(y, B.y) && Equal(z, B.z));
}
void P::set(int i, double v)
{
if (i == 0)
x = v;
else if (i == 1)
y = v;
else if (i == 2)
z = v;
}
const double P::get(int i)
{
if (i == 0)
return x;
else if (i == 1)
return y;
else if (i == 2)
return z;
return 0;
}
void P::reverse()
{
dx = -dx;
dy = -dy;
dz = -dz;
}
P::P(double x1, double y1, double z1)
{
x = x1;
y = y1;
z = z1;
dx = 0;
dy = dz = 0;
isend = 0;
type = ref = 0;
}
P::P()
{
x = y = z = 0;
dx = 0;
dy = dz = 0;
isend = 0;
type = ref = 0;
}
P P::operator-(P B) const
{
return P(x - B.x, y - B.y, z - B.z);
}
P P::operator+(P B) const
{
return P(x + B.x, y + B.y, z + B.z);
}
P P::operator*(double p) const
{
return P(x * p, y * p, z * p);
}
P P::operator/(double p) const
{
return P(x / p, y / p, z / p);
}
void P::print(string s)
{
cout << s << setprecision(10) << " : " << x << " " << y << " " << z << endl;
return;
}
// ÉèÖ÷½Ïò
void P::setDir(const P &dir)
{
dx = dir.x;
dy = dir.y;
dz = dir.z;
}

181
src/Intersection.cpp

@ -0,0 +1,181 @@
#include "Intersection.h"
using namespace std;
TriangleSegmentIntersectRes::TriangleSegmentIntersectRes(bool h, float tt) : hit(h), t(tt) {} // VS2008
TriangleSegmentIntersectRes
triangleSegmentIntersection(const LineSegment &segment, const Vec3f &a, const Vec3f &b, const Vec3f &c)
{
Vec3f e1 = b - a;
Vec3f e2 = c - a;
Vec3f s = segment.start - a;
Vec3f s1 = segment.getDir().cross(e2);
Vec3f s2 = s.cross(e1);
float s1_dot_e1 = s1.dot(e1);
float b1 = s1.dot(s) / s1_dot_e1;
float b2 = s2.dot(segment.getDir()) / s1_dot_e1;
if (b1 >= 0. && b2 >= 0. && b1 + b2 <= 1.)
{
return TriangleSegmentIntersectRes(true, s2.dot(e2) / s1_dot_e1);
}
return TriangleSegmentIntersectRes(false, 0.f);
}
BVHNode::BVHNode(size_t l, size_t r, size_t p, const AABB &aabb) : left(l), right(r), parent(p), boundingBox(aabb) {}
BVHNode::BVHNode() : left(0), right(0), parent(0), boundingBox() {}
BVH_intersection::BVH_intersection(const Mesh &mesh_) : mesh(mesh_)
{
faceCenters.reserve(mesh.indices.size());
for (vector<Vec3u>::const_iterator it = mesh.indices.begin(); it != mesh.indices.end(); ++it)
{
const Vec3u &face = *it;
Vec3f center = (mesh.vertices[face[0]] + mesh.vertices[face[1]] + mesh.vertices[face[2]]) / 3.0f;
faceCenters.push_back(center);
}
vector<size_t> indicesList(mesh.indices.size());
for (size_t i = 0; i < indicesList.size(); ++i)
{
indicesList[i] = i;
}
try
{
nodes.resize(2 * mesh.indices.size() - 1);
}
catch (const length_error &e)
{
cout << "vector.length:" << nodes.size() << " resize_pa:" << (2 * mesh.indices.size() - 1) << endl;
cerr << "Caught a length_error: " << e.what() << endl;
}
size_t nowIdx = 0;
dfsBuild(indicesList, computeAABB(indicesList), nowIdx);
}
size_t BVH_intersection::dfsBuild(vector<size_t> &indicesList, AABB aabb, size_t &nowIdx)
{
const size_t nodeIdx = nowIdx;
nowIdx++;
if (indicesList.size() == 1)
{
nodes[nodeIdx] = BVHNode(0, indicesList[0], 0, aabb); // VS2008
return nodeIdx;
}
int longAxis = -1;
float longAxisLen = -1;
for (int i = 0; i < 3; ++i)
{
const float axisLen = aabb.max[i] - aabb.min[i];
if (axisLen > longAxisLen)
{
longAxisLen = axisLen;
longAxis = i;
}
}
const size_t k = indicesList.size() / 2;
nth(indicesList, k - 1, longAxis);
vector<size_t> leftIndices(indicesList.begin(), indicesList.begin() + k);
vector<size_t> rightIndices(indicesList.begin() + k, indicesList.end());
const AABB leftAABB = computeAABB(leftIndices);
const AABB rightAABB = computeAABB(rightIndices);
const size_t leftIdx = dfsBuild(leftIndices, leftAABB, nowIdx);
const size_t rightIdx = dfsBuild(rightIndices, rightAABB, nowIdx);
nodes[nodeIdx] = BVHNode(leftIdx, rightIdx, 0, aabb); // VS2008
nodes[leftIdx].parent = nodeIdx;
nodes[rightIdx].parent = nodeIdx;
return nodeIdx;
}
bool BVH_intersection::intersectWithLineSegment(const LineSegment &lineSegment) const
{
return recursiveLineSegIntersection(lineSegment, 0);
}
AABB BVH_intersection::computeAABB(const vector<size_t> &indices)
{
AABB aabb;
for (vector<size_t>::const_iterator it = indices.begin(); it != indices.end(); ++it)
{
const Vec3u &face = mesh.indices[*it];
for (int i = 0; i < 3; ++i)
{
const Vec3f &vertex = mesh.vertices[face[i]];
for (int j = 0; j < 3; ++j)
{
aabb.min[j] = min(aabb.min[j], vertex[j]);
aabb.max[j] = max(aabb.max[j], vertex[j]);
}
}
}
return aabb;
}
bool BVH_intersection::recursiveLineSegIntersection(const LineSegment &lineSegment, size_t nodeIdx) const
{
const AABB &aabb = nodes[nodeIdx].boundingBox;
const Vec3f &dir = lineSegment.getDir();
bool hit = false;
for (int i = 0; !hit && i < 3; ++i)
{
float t_min = (aabb.min[i] - lineSegment.start[i]) / dir[i];
float t_max = (aabb.max[i] - lineSegment.start[i]) / dir[i];
if (t_min > t_max)
{
swap(t_min, t_max);
}
if (t_min > lineSegment.getLength() || t_max < 0)
return false;
Vec3f hitPt = lineSegment.start + dir * t_min;
int otherPlane1 = (i + 1) % 3, otherPlane2 = (i + 2) % 3;
if (hitPt[otherPlane1] >= aabb.min[otherPlane1] && hitPt[otherPlane1] <= aabb.max[otherPlane1] &&
hitPt[otherPlane2] >= aabb.min[otherPlane2] && hitPt[otherPlane2] <= aabb.max[otherPlane2])
{
hit = true;
}
}
if (hit)
{
if (nodes[nodeIdx].left == 0)
{
Vec3u face = mesh.indices[nodes[nodeIdx].right];
TriangleSegmentIntersectRes res = triangleSegmentIntersection(lineSegment, mesh.vertices[face[0]], mesh.vertices[face[1]],
mesh.vertices[face[2]]);
if (!res.hit || res.t < 0 || res.t > lineSegment.getLength())
return false;
return true;
}
else
{
return recursiveLineSegIntersection(lineSegment, nodes[nodeIdx].left) ||
recursiveLineSegIntersection(lineSegment, nodes[nodeIdx].right);
}
}
return false;
}
void BVH_intersection::nth(vector<size_t> &indicesList, size_t kth, int longAxis)
{
recursiveChoose(indicesList, 0, indicesList.size() - 1, kth, longAxis);
}
void BVH_intersection::recursiveChoose(vector<size_t> &indicesList, size_t begin, size_t end, size_t kth, int longAxis)
{
if (begin >= end)
return;
int i = begin, j = end;
while (i < j)
{
while (i < j && faceCenters[indicesList[j]][longAxis] >= faceCenters[indicesList[begin]][longAxis])
j--;
while (i < j && faceCenters[indicesList[i]][longAxis] <= faceCenters[indicesList[begin]][longAxis])
i++;
swap(indicesList[i], indicesList[j]);
}
swap(indicesList[begin], indicesList[i]);
if (i == kth)
return;
if (i < kth)
recursiveChoose(indicesList, i + 1, end, kth, longAxis);
else
recursiveChoose(indicesList, begin, i - 1, kth, longAxis);
}

8
src/stdafx.cpp

@ -1,8 +0,0 @@
// stdafx.cpp : 只包括标准包含文件的源文件
// xmlsql.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
// 引用任何所需的附加头文件,而不是在此文件中引用

24
src/xmlsql.cpp

@ -1,7 +1,5 @@
// xmlsql.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <tinyxml2.h>
#include "Astar.h"
#include "Geometry.h"
#include "Intersection.h"
@ -26,20 +24,20 @@ map<P, string> pmp, clipName;
struct Readexcel
{
vector<string> slist;
TiXmlElement *GetNodePointerByName(TiXmlElement *pRootEle, const char *strNodeName)
tinyxml2::XMLElement *GetNodePointerByName(tinyxml2::XMLElement *pRootEle, const char *strNodeName)
{
// if equal root node then return
if (0 == strcmp(strNodeName, pRootEle->Value()))
{
return pRootEle;
}
TiXmlElement *pEle = pRootEle;
tinyxml2::XMLElement *pEle = pRootEle;
for (pEle = pRootEle->FirstChildElement(); pEle; pEle = pEle->NextSiblingElement())
{
// recursive find sub node return node pointer
if (0 != strcmp(pEle->Value(), strNodeName))
{
TiXmlElement *res = GetNodePointerByName(pEle, strNodeName);
tinyxml2::XMLElement *res = GetNodePointerByName(pEle, strNodeName);
if (res != NULL)
return res;
}
@ -52,20 +50,20 @@ struct Readexcel
{
slist.clear();
TiXmlDocument *pDoc = new TiXmlDocument();
tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument();
pDoc->LoadFile(xml.c_str());
TiXmlElement *RootElement = pDoc->RootElement();
tinyxml2::XMLElement *RootElement = pDoc->RootElement();
TiXmlElement *row = GetNodePointerByName(RootElement, "Row");
tinyxml2::XMLElement *row = GetNodePointerByName(RootElement, "Row");
TiXmlElement *pEle;
tinyxml2::XMLElement *pEle;
for (pEle = row; pEle; pEle = pEle->NextSiblingElement())
{
// recursive find sub node return node pointer
TiXmlElement *cell;
tinyxml2::XMLElement *cell;
string s[7];
int i = 0;
for (cell = pEle->FirstChildElement(); cell; cell = cell->NextSiblingElement())
@ -201,7 +199,7 @@ bool read_OBJ(const string &filename, vector<Vec3f> &vertices, vector<Vec3u> &in
return true;
}
void produceXML(const char *xml, const char *connectorFile, string resultfile)
void produceXML(const string xml, const string connectorFile, string resultfile)
{
ofstream ofs, oendpoint;
ofs.open("result.txt", ios::out);

Loading…
Cancel
Save