Открыть боковую панель
nikitronn
sverchok
Коммиты
3a6adea5
Коммит
3a6adea5
создал
Дек 11, 2020
по автору
Ilya Portnov
Просмотр файлов
"voronoi on mesh" API.
владелец
9e7169e5
Изменения
1
Скрыть пробелы
Построчно
Рядом
utils/voronoi3d.py
Просмотр файла @
3a6adea5
...
...
@@ -26,7 +26,7 @@ from mathutils.bvhtree import BVHTree
from
sverchok.utils.sv_mesh_utils
import
mask_vertices
,
polygons_to_edges
from
sverchok.utils.sv_bmesh_utils
import
bmesh_from_pydata
,
pydata_from_bmesh
,
bmesh_clip
from
sverchok.utils.geom
import
calc_bounds
,
bounding_sphere
from
sverchok.utils.geom
import
calc_bounds
,
bounding_sphere
,
PlaneEquation
from
sverchok.utils.math
import
project_to_sphere
,
weighted_center
from
sverchok.dependencies
import
scipy
,
FreeCAD
...
...
@@ -159,32 +159,97 @@ def calc_bvh_projections(bvh, sites):
projections
.
append
(
loc
)
return
np
.
array
(
projections
)
def
voronoi_on_mesh_impl
(
bvh
,
sites
,
thickness
,
clip_inner
=
True
,
clip_outer
=
True
,
do_clip
=
True
,
clipping
=
1.0
,
make_regions
=
True
):
npoints
=
len
(
sites
)
if
clip_inner
or
clip_outer
:
normals
=
calc_bvh_normals
(
bvh
,
sites
)
k
=
0.5
*
thickness
sites
=
np
.
array
(
sites
)
all_points
=
sites
.
tolist
()
if
clip_outer
:
plus_points
=
sites
+
k
*
normals
all_points
.
extend
(
plus_points
.
tolist
())
if
clip_inner
:
minus_points
=
sites
-
k
*
normals
all_points
.
extend
(
minus_points
.
tolist
())
return
voronoi3d_layer
(
npoints
,
all_points
,
make_regions
=
make_regions
,
do_clip
=
do_clip
,
clipping
=
clipping
)
def
voronoi_on_mesh_bmesh
(
verts
,
faces
,
sites
,
spacing
=
0.0
,
fill
=
True
):
def
get_ridges_per_site
(
voronoi
):
result
=
defaultdict
(
list
)
for
ridge_idx
in
range
(
len
(
voronoi
.
ridge_points
)):
site1_idx
,
site2_idx
=
tuple
(
voronoi
.
ridge_points
[
ridge_idx
])
site1
=
voronoi
.
points
[
site1_idx
]
site2
=
voronoi
.
points
[
site2_idx
]
middle
=
(
site1
+
site2
)
*
0.5
normal
=
site2
-
site1
plane
=
PlaneEquation
.
from_normal_and_point
(
normal
,
middle
)
result
[
site1_idx
].
append
(
plane
)
result
[
site2_idx
].
append
(
plane
)
return
result
def
voronoi_on_mesh
(
verts
,
faces
,
sites
,
thickness
,
clip_inner
=
True
,
clip_outer
=
True
,
do_clip
=
True
,
clipping
=
1.0
,
make_regions
=
True
):
def
cut_cell
(
verts
,
faces
,
planes
,
site
):
src_mesh
=
bmesh_from_pydata
(
verts
,
[],
faces
,
normal_update
=
True
)
for
plane
in
planes
:
geom_in
=
src_mesh
.
verts
[:]
+
src_mesh
.
edges
[:]
+
src_mesh
.
faces
[:]
plane_co
=
plane
.
projection_of_point
(
site
)
plane_no
=
plane
.
normal
if
plane
.
side_of_point
(
site
)
>
0
:
plane_no
=
-
plane_no
plane_co
=
plane_co
-
0.5
*
spacing
*
plane_no
.
normalized
()
#print(f"Plane co {plane_co}, no {plane_no}")
res
=
bmesh
.
ops
.
bisect_plane
(
src_mesh
,
geom
=
geom_in
,
dist
=
0.00001
,
plane_co
=
plane_co
,
plane_no
=
plane_no
,
use_snap_center
=
False
,
clear_outer
=
True
,
clear_inner
=
False
)
if
fill
:
surround
=
[
e
for
e
in
res
[
'geom_cut'
]
if
isinstance
(
e
,
bmesh
.
types
.
BMEdge
)]
fres
=
bmesh
.
ops
.
edgenet_prepare
(
src_mesh
,
edges
=
surround
)
bmesh
.
ops
.
edgeloop_fill
(
src_mesh
,
edges
=
fres
[
'edges'
])
return
pydata_from_bmesh
(
src_mesh
)
verts_out
=
[]
edges_out
=
[]
faces_out
=
[]
voronoi
=
Voronoi
(
np
.
array
(
sites
))
ridges_per_site
=
get_ridges_per_site
(
voronoi
)
for
site_idx
in
range
(
len
(
sites
)):
new_verts
,
new_edges
,
new_faces
=
cut_cell
(
verts
,
faces
,
ridges_per_site
[
site_idx
],
sites
[
site_idx
])
if
new_verts
:
verts_out
.
append
(
new_verts
)
edges_out
.
append
(
new_edges
)
faces_out
.
append
(
new_faces
)
return
verts_out
,
edges_out
,
faces_out
def
voronoi_on_mesh
(
verts
,
faces
,
sites
,
thickness
,
spacing
=
0.0
,
clip_inner
=
True
,
clip_outer
=
True
,
do_clip
=
True
,
clipping
=
1.0
,
mode
=
'REGIONS'
):
bvh
=
BVHTree
.
FromPolygons
(
verts
,
faces
)
return
voronoi_on_mesh_impl
(
bvh
,
sites
,
thickness
,
clip_inner
=
clip_inner
,
clip_outer
=
clip_outer
,
do_clip
=
do_clip
,
clipping
=
clipping
,
make_regions
=
make_regions
)
npoints
=
len
(
sites
)
if
mode
in
{
'REGIONS'
,
'RIDGES'
}:
if
clip_inner
or
clip_outer
:
normals
=
calc_bvh_normals
(
bvh
,
sites
)
k
=
0.5
*
thickness
sites
=
np
.
array
(
sites
)
all_points
=
sites
.
tolist
()
if
clip_outer
:
plus_points
=
sites
+
k
*
normals
all_points
.
extend
(
plus_points
.
tolist
())
if
clip_inner
:
minus_points
=
sites
-
k
*
normals
all_points
.
extend
(
minus_points
.
tolist
())
return
voronoi3d_layer
(
npoints
,
all_points
,
make_regions
=
(
mode
==
'REGIONS'
),
do_clip
=
do_clip
,
clipping
=
clipping
)
else
:
# VOLUME, SURFACE
all_points
=
sites
if
do_clip
:
normals
=
calc_bvh_normals
(
bvh
,
sites
)
plus_points
=
sites
+
clipping
*
normals
all_points
.
extend
(
plus_points
.
tolist
())
return
voronoi_on_mesh_bmesh
(
verts
,
faces
,
all_points
,
spacing
=
spacing
,
fill
=
(
mode
==
'VOLUME'
))
def
project_solid_normals
(
shell
,
pts
,
thickness
,
add_plus
=
True
,
add_minus
=
True
,
predicate_plus
=
None
,
predicate_minus
=
None
):
k
=
0.5
*
thickness
...
...
Редактирование
Предварительный просмотр
Поддерживает Markdown
0%
Попробовать снова
или
прикрепить новый файл
.
Отмена
You are about to add
0
people
to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Отмена
Пожалуйста,
зарегистрируйтесь
или
войдите
чтобы прокомментировать