Have just done a short test why cdt module will crash with arc. Bellow is the stripped down code.
Problem seems to be that initVector() creates a Vector3 while initDelaunayTriangulation() expects a Vector2.
I always admitted that cdt is untested, that is the reason that it is not in nimble. But I think it is funny that default gc seems to work, but arc not. Maybe arc is correct, and default just more forgiving? That was easy -- next milestone is learning what the cursor warning means excactly for cdt and how to fix it.
import tables
type
VertexID* = distinct int
QuadEdgeID* = distinct int
type
Vector2* = object of RootObj
x*, y*: float
Vector3* = object of Vector2
z*: float
type
Vector* = Vector2
type
Vertex* = ref object
point*: Vector
id*: VertexID
seqPos*: int
mark*: int
type
Subdivision* = object of RootObj
vertices*: Table[int, Vertex]
vertIDs*: seq[VertexID]
vertexID: VertexID
quadEdgeID: QuadEdgeID
type
DelaunayTriangulation* = object
subdivision*: Subdivision
constraints*: Table[int, Vertex]
epsilon*: float
xmin, ymin, xmax, ymax: float
mark: int
straightEdges*: bool
interpolateZ*: bool
proc nextVertexID(s: var Subdivision): VertexID {.inline.} =
result = s.vertexID
inc(int(s.vertexID))
func initVector3*(x: float = 0, y: float = 0, z: float = 0): Vector3 =
Vector3(x: x, y: y, z: z)
const
initVector = initVector3
proc newVertex*(p: Vector; id: VertexID): Vertex =
return Vertex(point: p, id: id)
proc createVertex*(s: var Subdivision; p: Vector): Vertex =
echo s.nextVertexID.int
result = newVertex(p, s.nextVertexID)
s.vertices[result.id.int] = result
result.seqPos = s.vertIDs.len
s.vertIDs.add(result.id)
proc initDelaunayTriangulation*(a, b: Vector; precision = 1e-8): DelaunayTriangulation =
assert(a.x != b.x and a.y != b.y)
assert(precision <= 1e-6 and precision >= 1e-14)
(result.xmin, result.xmax) = (a.x, b.x)
if result.xmin > result.xmax:
swap(result.xmin, result.xmax)
(result.ymin, result.ymax) = (a.y, b.y)
if result.ymin > result.ymax:
swap(result.ymin, result.ymax)
let boundary =
[Vector(x: result.xmin, y: result.ymin), Vector(x: result.xmax, y: result.ymin),
Vector(x: result.xmax, y: result.ymax), Vector(x: result.xmin, y: result.ymax)]
result.epsilon = max(result.xmax - result.xmin, result.ymax - result.ymin) * precision
var verts: seq[Vertex]
for p in boundary:
verts.add(result.subdivision.createVertex(p))
var dt: DelaunayTriangulation = initDelaunayTriangulation(initVector(0, 10), initVector(10, 100))
/tmp/cdt/src/cdt/t.nim(53) newVertex
SIGSEGV: Illegal storage access. (Attempt to read from nil?)