Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
Printrun
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
machinery
Printrun
Commits
5d637a90
Commit
5d637a90
authored
Apr 05, 2014
by
Guillaume Seguin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Double clicking on a facet in plater will rebase object on facet #207
parent
0bba2c17
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
87 additions
and
12 deletions
+87
-12
stlplater.py
printrun/stlplater.py
+41
-4
stltool.py
printrun/stltool.py
+44
-5
stlview.py
printrun/stlview.py
+2
-3
No files found.
printrun/stlplater.py
View file @
5d637a90
...
...
@@ -63,7 +63,7 @@ class showstl(wx.Window):
self
.
initpos
=
None
self
.
prevsel
=
-
1
def
draw
model
(
self
,
m
,
scale
):
def
prepare_
model
(
self
,
m
,
scale
):
m
.
bitmap
=
wx
.
EmptyBitmap
(
800
,
800
,
32
)
dc
=
wx
.
MemoryDC
()
dc
.
SelectObject
(
m
.
bitmap
)
...
...
@@ -226,6 +226,43 @@ class StlPlater(Plater):
self
.
simarrange_path
=
simarrange_path
if
simarrange_path
else
"./simarrange/sa"
self
.
set_viewer
(
viewer
)
def
clickcb
(
self
,
event
):
if
not
isinstance
(
self
.
s
,
stlview
.
StlViewPanel
):
return
x
,
y
=
event
.
GetPosition
()
ray_near
,
ray_far
=
self
.
s
.
mouse_to_ray
(
x
,
y
,
local_transform
=
True
)
best_match
=
None
best_facet
=
None
best_dist
=
float
(
"inf"
)
# TODO: speedup search by first checking if ray is in bounding box
# of the given model
for
key
,
model
in
self
.
models
.
iteritems
():
transformed
=
model
if
any
(
model
.
centeroffset
):
transformed
=
transformed
.
translate
(
model
.
centeroffset
)
if
model
.
rot
:
transformed
=
transformed
.
rotate
([
0
,
0
,
model
.
rot
])
if
any
(
model
.
offsets
):
transformed
=
transformed
.
translate
(
model
.
offsets
)
facet
,
facet_dist
=
transformed
.
intersect
(
ray_near
,
ray_far
)
if
facet
is
not
None
and
facet_dist
<
best_dist
:
best_match
=
key
best_facet
=
facet
best_dist
=
facet_dist
if
best_match
is
not
None
:
model
=
self
.
models
[
best_match
]
newmodel
=
model
.
rebase
(
best_facet
)
newmodel
.
offsets
=
model
.
offsets
newmodel
.
rot
=
0
newmodel
.
scale
=
model
.
scale
newmodel
.
filename
=
model
.
filename
newmodel
.
centeroffset
=
[
-
(
newmodel
.
dims
[
1
]
+
newmodel
.
dims
[
0
])
/
2
,
-
(
newmodel
.
dims
[
3
]
+
newmodel
.
dims
[
2
])
/
2
,
0
]
self
.
s
.
prepare_model
(
newmodel
,
2
)
self
.
models
[
best_match
]
=
newmodel
wx
.
CallAfter
(
self
.
Refresh
)
def
done
(
self
,
event
,
cb
):
try
:
os
.
mkdir
(
"tempstl"
)
...
...
@@ -294,12 +331,12 @@ class StlPlater(Plater):
newmodel
.
rot
=
model
.
rot
newmodel
.
scale
=
list
(
model
.
scale
)
self
.
add_model
(
name
,
newmodel
)
self
.
s
.
draw
model
(
newmodel
,
2
)
self
.
s
.
prepare_
model
(
newmodel
,
2
)
break
else
:
# Filter out the path, just show the STL filename.
self
.
load_stl_into_model
(
name
,
name
)
self
.
Refresh
(
)
wx
.
CallAfter
(
self
.
Refresh
)
def
load_stl_into_model
(
self
,
path
,
name
,
offset
=
[
0
,
0
,
0
],
rotation
=
0
,
scale
=
[
1.0
,
1.0
,
1.0
]):
model
=
stltool
.
stl
(
path
)
...
...
@@ -311,7 +348,7 @@ class StlPlater(Plater):
model
.
centeroffset
=
[
-
(
model
.
dims
[
1
]
+
model
.
dims
[
0
])
/
2
,
-
(
model
.
dims
[
3
]
+
model
.
dims
[
2
])
/
2
,
0
]
self
.
s
.
draw
model
(
model
,
2
)
self
.
s
.
prepare_
model
(
model
,
2
)
def
export_to
(
self
,
name
):
with
open
(
name
.
replace
(
"."
,
"_"
)
+
".scad"
,
"w"
)
as
sf
:
...
...
printrun/stltool.py
View file @
5d637a90
...
...
@@ -20,6 +20,9 @@ import math
import
numpy
import
numpy.linalg
def
normalize
(
v
):
return
v
/
numpy
.
linalg
.
norm
(
v
)
def
genfacet
(
v
):
veca
=
v
[
1
]
-
v
[
0
]
vecb
=
v
[
2
]
-
v
[
1
]
...
...
@@ -154,6 +157,38 @@ class stl(object):
f
.
close
()
return
def
intersect
(
self
,
ray_far
,
ray_near
):
ray_near
=
numpy
.
array
(
ray_near
)
ray_far
=
numpy
.
array
(
ray_far
)
ray_dir
=
normalize
(
ray_far
-
ray_near
)
best_facet
=
None
best_dist
=
float
(
"inf"
)
eps
=
0.000001
for
facet_i
,
(
normal
,
(
v1
,
v2
,
v3
))
in
enumerate
(
self
.
facets
):
edge1
=
v2
-
v1
edge2
=
v3
-
v1
pvec
=
numpy
.
cross
(
ray_dir
,
edge2
)
det
=
edge1
.
dot
(
pvec
)
if
abs
(
det
)
<
eps
:
continue
inv_det
=
1.
/
det
tvec
=
ray_near
-
v1
u
=
tvec
.
dot
(
pvec
)
*
inv_det
if
u
<
0.
or
u
>
1.
:
continue
qvec
=
numpy
.
cross
(
tvec
,
edge1
)
v
=
ray_dir
.
dot
(
qvec
)
*
inv_det
if
v
<
0.
or
u
+
v
>
1.
:
continue
t
=
edge2
.
dot
(
qvec
)
*
inv_det
if
t
<
eps
:
continue
if
t
<
best_dist
:
best_facet
=
facet_i
best_dist
=
t
return
best_facet
,
best_dist
def
rebase
(
self
,
facet_i
):
normal
,
facet
=
self
.
facets
[
facet_i
]
u1
=
facet
[
1
]
-
facet
[
0
]
...
...
@@ -163,17 +198,21 @@ class stl(object):
u2
=
v2
-
u1
*
v2
.
dot
(
u1
)
/
n1
e2
=
u2
/
numpy
.
linalg
.
norm
(
u2
)
e3
=
numpy
.
cross
(
e1
,
e2
)
# Ensure Z direction if opposed to the normal
if
normal
.
dot
(
e3
)
>
0
:
e2
=
-
e2
e3
=
-
e3
matrix
=
[[
e1
[
0
],
e2
[
0
],
e3
[
0
],
0
],
[
e1
[
1
],
e2
[
1
],
e3
[
1
],
0
],
[
e1
[
2
],
e2
[
2
],
e3
[
2
],
0
],
[
0
,
0
,
0
,
1
]]
matrix
=
numpy
.
array
(
matrix
)
# Inverse change of basis matrix
matrix
=
numpy
.
linalg
.
inv
(
matrix
)
# Set first vertex of facet as origin
neworig
=
matrix
.
dot
(
homogeneous
(
facet
[
0
]))
matrix
[:
3
,
3
]
=
-
neworig
[:
3
]
newmodel
=
self
.
transform
(
matrix
)
# If object ends up being mostly below ground plane,
# rotate it around Y axis
avgz
=
(
newmodel
.
dims
[
4
]
+
newmodel
.
dims
[
5
])
/
2
if
avgz
<
0
:
newmodel
=
newmodel
.
rotate
([
0
,
180
,
0
])
return
newmodel
def
translate
(
self
,
v
=
[
0
,
0
,
0
]):
...
...
printrun/stlview.py
View file @
5d637a90
...
...
@@ -253,12 +253,11 @@ class StlViewPanel(wxGLPanel):
self
.
initialized
=
1
wx
.
CallAfter
(
self
.
Refresh
)
def
drawmodel
(
self
,
m
,
n
):
def
prepare_model
(
self
,
m
,
scale
):
batch
=
pyglet
.
graphics
.
Batch
()
stlview
(
m
.
facets
,
batch
=
batch
)
m
.
batch
=
batch
m
.
animoffset
=
300
# print m
# m.animoffset = 300
# threading.Thread(target = self.anim, args = (m, )).start()
wx
.
CallAfter
(
self
.
Refresh
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment