Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Leger <stephen@3dservices.ch>2017-08-03 16:59:40 +0300
committerStephen Leger <stephen@3dservices.ch>2017-08-14 02:16:24 +0300
commitfde9aa0a3fe223e7f2eb03010faf626bac925780 (patch)
tree3cf8c0355c6892187527844d93669d0428e1f7da
parent6e469175870222d724be17c9f14590a07e1e7e45 (diff)
archipack: Fix issue with curved segments in walls/slab/floor
-rw-r--r--archipack/archipack_2d.py39
-rw-r--r--archipack/archipack_cutter.py30
-rw-r--r--archipack/archipack_fence.py16
-rw-r--r--archipack/archipack_floor.py25
-rw-r--r--archipack/archipack_slab.py53
-rw-r--r--archipack/archipack_wall2.py47
-rw-r--r--archipack/panel.py4
7 files changed, 165 insertions, 49 deletions
diff --git a/archipack/archipack_2d.py b/archipack/archipack_2d.py
index fcd578da..4bf0d1f1 100644
--- a/archipack/archipack_2d.py
+++ b/archipack/archipack_2d.py
@@ -116,6 +116,7 @@ class Line(Projection):
else:
self.p = Vector((0, 0))
self.v = Vector((0, 0))
+ self.line = None
@property
def copy(self):
@@ -162,6 +163,10 @@ class Line(Projection):
return atan2(self.v.y, self.v.x)
@property
+ def a0(self):
+ return self.angle
+
+ @property
def angle_normal(self):
"""
2d angle of perpendicular
@@ -365,7 +370,7 @@ class Line(Projection):
if hasattr(last, "r"):
res, d, t = line.point_sur_segment(last.c)
c = (last.r * last.r) - (d * d)
- print("t:%s" % t)
+ # print("t:%s" % t)
if c <= 0:
# no intersection !
p0 = line.lerp(t)
@@ -455,8 +460,6 @@ class Arc(Circle):
"""
Represent a 2d Arc
TODO:
- Add some sugar here
- like being able to set p0 and p1 of line
make it possible to define an arc by start point end point and center
"""
def __init__(self, c, radius, a0, da):
@@ -473,6 +476,7 @@ class Arc(Circle):
stored internally as radians
"""
Circle.__init__(self, Vector(c).to_2d(), radius)
+ self.line = None
self.a0 = a0
self.da = da
@@ -575,6 +579,15 @@ class Arc(Circle):
"""
return self.r * abs(self.da)
+ @property
+ def oposite(self):
+ a0 = self.a0 + self.da
+ if a0 > pi:
+ a0 -= 2 * pi
+ if a0 < -pi:
+ a0 += 2 * pi
+ return Arc(self.c, self.r, a0, -self.da)
+
def normal(self, t=0):
"""
Perpendicular line starting at t
@@ -628,6 +641,26 @@ class Arc(Circle):
steps = max(1, round(abs(self.da) / step_angle, 0))
return 1.0 / steps, int(steps)
+ def as_lines(self, steps):
+ """
+ convert Arc to lines
+ """
+ res = []
+ p0 = self.lerp(0)
+ for step in range(steps):
+ p1 = self.lerp((step + 1) / steps)
+ s = Line(p0=p0, p1=p1)
+ res.append(s)
+ p0 = p1
+
+ if self.line is not None:
+ p0 = self.line.lerp(0)
+ for step in range(steps):
+ p1 = self.line.lerp((step + 1) / steps)
+ res[step].line = Line(p0=p0, p1=p1)
+ p0 = p1
+ return res
+
def offset(self, offset):
"""
Offset circle
diff --git a/archipack/archipack_cutter.py b/archipack/archipack_cutter.py
index 69bd16c2..b5a64776 100644
--- a/archipack/archipack_cutter.py
+++ b/archipack/archipack_cutter.py
@@ -62,7 +62,7 @@ class CutterSegment(Line):
def offset(self, offset):
s = self.copy
- s.p += offset * self.cross_z.normalized()
+ s.p += self.sized_normal(0, offset).v
return s
@property
@@ -206,6 +206,18 @@ class CutAblePolygon():
- holes
- convex
"""
+ def as_lines(self, step_angle=0.104):
+ """
+ Convert curved segments to straight lines
+ """
+ segs = []
+ for s in self.segs:
+ if "Curved" in type(s).__name__:
+ dt, steps = s.steps_by_angle(step_angle)
+ segs.extend(s.as_lines(steps))
+ else:
+ segs.append(s)
+ self.segs = segs
def inside(self, pt, segs=None):
"""
@@ -471,8 +483,9 @@ class CutAbleGenerator():
of = offset[s.type]
else:
of = offset['DEFAULT']
- p0 = s.p0 + s.cross_z.normalized() * of
- self.bissect(bm, p0.to_3d(), s.cross_z.to_3d(), clear_outer=False)
+ n = s.sized_normal(0, 1).v
+ p0 = s.p0 + n * of
+ self.bissect(bm, p0.to_3d(), n.to_3d(), clear_outer=False)
# compute boundary with offset
new_s = None
@@ -495,7 +508,8 @@ class CutAbleGenerator():
else:
for s in hole.segs:
if s.length > 0:
- self.bissect(bm, s.p0.to_3d(), s.cross_z.to_3d(), clear_outer=False)
+ n = s.sized_normal(0, 1).v
+ self.bissect(bm, s.p0.to_3d(), n.to_3d(), clear_outer=False)
# use hole boundary
segs = hole.segs
if len(segs) > 0:
@@ -518,12 +532,14 @@ class CutAbleGenerator():
of = offset[s.type]
else:
of = offset['DEFAULT']
- p0 = s.p0 + s.cross_z.normalized() * of
- self.bissect(bm, p0.to_3d(), s.cross_z.to_3d(), clear_outer=cutable.convex)
+ n = s.sized_normal(0, 1).v
+ p0 = s.p0 + n * of
+ self.bissect(bm, p0.to_3d(), n.to_3d(), clear_outer=cutable.convex)
else:
for s in cutable.segs:
if s.length > 0:
- self.bissect(bm, s.p0.to_3d(), s.cross_z.to_3d(), clear_outer=cutable.convex)
+ n = s.sized_normal(0, 1).v
+ self.bissect(bm, s.p0.to_3d(), n.to_3d(), clear_outer=cutable.convex)
if not cutable.convex:
f_geom = [f for f in bm.faces
diff --git a/archipack/archipack_fence.py b/archipack/archipack_fence.py
index 7006b3b1..0f5f3b37 100644
--- a/archipack/archipack_fence.py
+++ b/archipack/archipack_fence.py
@@ -52,7 +52,6 @@ class Fence():
self.t_end = 0
self.dz = 0
self.z0 = 0
- self.a0 = 0
def set_offset(self, offset, last=None):
"""
@@ -622,12 +621,19 @@ def update_type(self, context):
else:
w = w0.curved_fence(part.a0, part.da, part.radius)
else:
- g = FenceGenerator(None)
- g.add_part(self)
- w = g.segs[0]
+ if "C_" in self.type:
+ p = Vector((0, 0))
+ v = self.length * Vector((cos(self.a0), sin(self.a0)))
+ w = StraightFence(p, v)
+ a0 = pi / 2
+ else:
+ c = -self.radius * Vector((cos(self.a0), sin(self.a0)))
+ w = CurvedFence(c, self.radius, self.a0, pi)
- # w0 - w - w1
+ # not closed, see wall
+ # for closed ability
dp = w.p1 - w.p0
+
if "C_" in self.type:
part.radius = 0.5 * dp.length
part.da = pi
diff --git a/archipack/archipack_floor.py b/archipack/archipack_floor.py
index 634c2130..8664b637 100644
--- a/archipack/archipack_floor.py
+++ b/archipack/archipack_floor.py
@@ -246,6 +246,13 @@ class FloorGenerator(CutAblePolygon, CutAbleGenerator):
def limits(self):
x_size = [s.p0.x for s in self.segs]
y_size = [s.p0.y for s in self.segs]
+ for s in self.segs:
+ if "Curved" in type(s).__name__:
+ x_size.append(s.c.x + s.r)
+ x_size.append(s.c.x - s.r)
+ y_size.append(s.c.y + s.r)
+ y_size.append(s.c.y - s.r)
+
self.xmin = min(x_size)
self.xmax = max(x_size)
self.xsize = self.xmax - self.xmin
@@ -258,6 +265,7 @@ class FloorGenerator(CutAblePolygon, CutAbleGenerator):
either external or holes cuts
"""
self.limits()
+ self.as_lines()
self.is_convex()
for b in o.children:
d = archipack_floor_cutter.datablock(b)
@@ -857,12 +865,21 @@ def update_type(self, context):
else:
w = w0.curved_floor(part.a0, part.da, part.radius)
else:
- g = FloorGenerator(None)
- g.add_part(self)
- w = g.segs[0]
+ if "C_" in self.type:
+ p = Vector((0, 0))
+ v = self.length * Vector((cos(self.a0), sin(self.a0)))
+ w = StraightFloor(p, v)
+ a0 = pi / 2
+ else:
+ c = -self.radius * Vector((cos(self.a0), sin(self.a0)))
+ w = CurvedFloor(c, self.radius, self.a0, pi)
# w0 - w - w1
- dp = w.p1 - w.p0
+ if idx + 1 == d.n_parts:
+ dp = - w.p0
+ else:
+ dp = w.p1 - w.p0
+
if "C_" in self.type:
part.radius = 0.5 * dp.length
part.da = pi
diff --git a/archipack/archipack_slab.py b/archipack/archipack_slab.py
index 9f8a2947..9059f269 100644
--- a/archipack/archipack_slab.py
+++ b/archipack/archipack_slab.py
@@ -247,6 +247,10 @@ class SlabGenerator(CutAblePolygon, CutAbleGenerator):
either external or holes cuts
"""
self.limits()
+
+ self.as_lines(step_angle=0.0502)
+ # self.segs = [s.line for s in self.segs]
+
for b in o.children:
d = archipack_slab_cutter.datablock(b)
if d is not None:
@@ -382,12 +386,21 @@ def update_type(self, context):
else:
w = w0.curved_slab(part.a0, part.da, part.radius)
else:
- g = SlabGenerator(None)
- g.add_part(self)
- w = g.segs[0]
+ if "C_" in self.type:
+ p = Vector((0, 0))
+ v = self.length * Vector((cos(self.a0), sin(self.a0)))
+ w = StraightSlab(p, v)
+ a0 = pi / 2
+ else:
+ c = -self.radius * Vector((cos(self.a0), sin(self.a0)))
+ w = CurvedSlab(c, self.radius, self.a0, pi)
# w0 - w - w1
- dp = w.p1 - w.p0
+ if idx + 1 == d.n_parts:
+ dp = - w.p0
+ else:
+ dp = w.p1 - w.p0
+
if "C_" in self.type:
part.radius = 0.5 * dp.length
part.da = pi
@@ -494,22 +507,15 @@ class ArchipackSegment():
def draw(self, context, layout, index):
box = layout.box()
- row = box.row()
- row.prop(self, "type", text=str(index + 1))
+ box.prop(self, "type", text=str(index + 1))
self.draw_insert(context, box, index)
if self.type in ['C_SEG']:
- row = box.row()
- row.prop(self, "radius")
- row = box.row()
- row.prop(self, "da")
+ box.prop(self, "radius")
+ box.prop(self, "da")
else:
- row = box.row()
- row.prop(self, "length")
- row = box.row()
- row.prop(self, "a0")
- row = box.row()
- row.prop(self, "offset")
- # row.prop(self, "linked_idx")
+ box.prop(self, "length")
+ box.prop(self, "a0")
+ # box.prop(self, "offset")
class archipack_slab_part(ArchipackSegment, PropertyGroup):
@@ -823,6 +829,7 @@ class archipack_slab(ArchipackObject, Manipulable, PropertyGroup):
# start and shared: update rotation
a = seg.angle - w.segs[idx].angle
+
if abs(a) > 0.00001:
w.rotate(idx, a)
@@ -831,7 +838,7 @@ class archipack_slab(ArchipackObject, Manipulable, PropertyGroup):
if next_idx > -1:
- if idx + 1 == next_idx:
+ if (idx + 1 == next_idx) or (next_idx == 0 and i + 1 == self.n_parts):
# shared: should move last point
# and apply to next segments
# this is overriden for common segs
@@ -854,11 +861,13 @@ class archipack_slab(ArchipackObject, Manipulable, PropertyGroup):
last_idx = next_idx - 1
# update d from og
+ last_seg = None
for i, seg in enumerate(w.segs):
- if i > 0:
- d.parts[i].a0 = seg.delta_angle(w.segs[i - 1])
- else:
- d.parts[i].a0 = seg.angle
+
+ d.parts[i].a0 = seg.delta_angle(last_seg)
+
+ last_seg = seg
+
if "C_" in d.parts[i].type:
d.parts[i].radius = seg.r
d.parts[i].da = seg.da
diff --git a/archipack/archipack_wall2.py b/archipack/archipack_wall2.py
index f52233a5..92172eb1 100644
--- a/archipack/archipack_wall2.py
+++ b/archipack/archipack_wall2.py
@@ -577,11 +577,21 @@ def update_type(self, context):
else:
w = w0.curved_wall(self.a0, self.da, self.radius, d.z, self.z, self.t)
else:
- g = WallGenerator(None)
- g.add_part(self, d.z, d.flip)
- w = g.segs[0]
+ if "C_" in self.type:
+ p = Vector((0, 0))
+ v = self.length * Vector((cos(self.a0), sin(self.a0)))
+ w = StraightWall(p, v, d.z, self.z, self.t, d.flip)
+ a0 = pi / 2
+ else:
+ c = -self.radius * Vector((cos(self.a0), sin(self.a0)))
+ w = CurvedWall(c, self.radius, self.a0, pi, d.z, self.z, self.t, d.flip)
+
# w0 - w - w1
- dp = w.p1 - w.p0
+ if d.closed and idx == d.n_parts:
+ dp = - w.p0
+ else:
+ dp = w.p1 - w.p0
+
if "C_" in self.type:
self.radius = 0.5 * dp.length
self.da = pi
@@ -1088,13 +1098,37 @@ class archipack_wall2(ArchipackObject, Manipulable, PropertyGroup):
def reverse(self, context, o):
g = self.get_generator()
+
+ self.auto_update = False
+
pts = [seg.p0.to_3d() for seg in g.segs]
+ if not self.closed:
+ g.segs.pop()
+
+ g_segs = list(reversed(g.segs))
+
+ last_seg = None
+
+ for i, seg in enumerate(g_segs):
+
+ s = seg.oposite
+ if "Curved" in type(seg).__name__:
+ self.parts[i].type = "C_WALL"
+ self.parts[i].radius = s.r
+ self.parts[i].da = s.da
+ else:
+ self.parts[i].type = "S_WALL"
+ self.parts[i].length = s.length
+
+ self.parts[i].a0 = s.delta_angle(last_seg)
+
+ last_seg = s
+
if self.closed:
pts.append(pts[0])
pts = list(reversed(pts))
- self.auto_update = False
# location wont change for closed walls
if not self.closed:
@@ -1107,7 +1141,8 @@ class archipack_wall2(ArchipackObject, Manipulable, PropertyGroup):
[0, 0, 0, 1],
])
- self.from_points(pts, self.closed)
+ # self.from_points(pts, self.closed)
+
g = self.get_generator()
self.setup_childs(o, g)
diff --git a/archipack/panel.py b/archipack/panel.py
index c8898fe5..4a472362 100644
--- a/archipack/panel.py
+++ b/archipack/panel.py
@@ -703,8 +703,8 @@ class Panel():
n_profil_faces = self.profil_faces
idmat = []
for i in range(n_path_faces):
- for mat in range(n_profil_faces):
- idmat.append(self.idmat[mat])
+ for f in range(n_profil_faces):
+ idmat.append(self.idmat[f])
if self.side_cap_front > -1:
idmat.append(cap_front_id)
if self.side_cap_back > -1: