1
1

Compare commits

...

2681 Commits

Author SHA1 Message Date
d0527bfd48 fix for inner uv and fractal / bmesh 2019-04-04 21:30:41 +02:00
f0bf1f57f6 attempt to fix inner uv for fractal boolean 2019-04-04 15:08:19 +02:00
9dbc8cc201 small refresh operator fix 2019-03-17 14:48:12 +01:00
bda7f7d61f attempt to stabilize dynamic fracture 2019-03-17 14:12:48 +01:00
6bcb6b128d can now finally save and load fracture data (and motion data) 2019-03-12 00:39:42 +01:00
a6815cd398 fix typo (where only the unmodified mesh was taken into account as operand) 2019-03-10 12:35:54 +01:00
2c056a1e2e why interrupt and reset the particle sim, if a modifier after it changes ? Makes not much sense.
in this case, changing the parameters of metaball remesh after particlesystem during animation caused strange resets.
2019-03-10 10:51:03 +01:00
fcb6514aba null pointer crash fix 2019-03-09 23:29:48 +01:00
db14be423c actually take the FM solver change into account, was defaulting to carve now. 2019-03-09 22:48:28 +01:00
f236797eee fix incorrectly flipped carve result 2019-03-09 21:09:52 +01:00
3832a09ea8 bring back carve as boolean alternative for FM 2.8 (and boolean modifier too)
Users should keep the solver as choice, since Bmesh boolean is not finished yet.
2019-03-09 20:40:29 +01:00
0b20de3608 attempt to fix crash with dynamic + constraints (but the problems are multiple depsgraph threads here) 2019-03-02 19:14:34 +01:00
bb1ca80bc1 metaball remesh crash fix 2019-03-02 11:05:39 +01:00
c9d59c9d9e update submodule pointers 2019-03-02 10:48:23 +01:00
7faf3f4736 Merge remote-tracking branch 'origin/master' into fracture_modifier-2.8
# Conflicts:
#	intern/cycles/blender/blender_mesh.cpp
#	intern/rigidbody/RBI_api.h
#	intern/rigidbody/rb_bullet_api.cpp
#	source/blender/blenkernel/BKE_rigidbody.h
#	source/blender/blenkernel/intern/rigidbody.c
#	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
#	source/blender/draw/intern/draw_manager.c
#	source/blender/editors/physics/rigidbody_object.c
#	source/blender/makesdna/DNA_modifier_types.h
#	source/blender/makesdna/DNA_rigidbody_types.h
#	source/blender/makesrna/intern/rna_modifier.c
#	source/blender/makesrna/intern/rna_rigidbody.c
#	source/blender/modifiers/intern/MOD_boolean.c
#	source/blender/modifiers/intern/MOD_multires.c
#	source/blender/modifiers/intern/MOD_remesh.c
2019-03-02 10:43:27 +01:00
0c0de344aa make usage of opensubdiv in subsurf and multires optional, allow switching to legacy mode 2019-02-22 12:15:52 +01:00
4b614d9e94 anim bind rotation fix (again) 2019-01-12 14:46:39 +01:00
58161e738d animated mesh rotation fix 2019-01-09 18:45:31 +01:00
5203b4e6b1 expose shard neighbors via RNA 2018-12-29 23:31:26 +01:00
4d72c167b4 Merge remote-tracking branch 'origin/master' into fracture_modifier-2.8
# Conflicts:
#	release/scripts/addons
#	release/scripts/addons_contrib
#	source/blender/blenkernel/BKE_rigidbody.h
#	source/blender/blenkernel/intern/rigidbody.c
#	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
#	source/blender/editors/physics/rigidbody_constraint.c
#	source/blender/makesrna/intern/rna_rigidbody.c
2018-12-21 16:33:28 +01:00
c03a1606a6 probably it is not necessary to clear the cache on every rna property change
like changing autohide / automerge parameters which are considered live postprocess steps caused the mesh to disappear when not on cache startframe.
2018-12-12 23:50:06 +01:00
3c9d369821 temporarily bringing back the legacy subsurf code for performance reasons
opensubdivs subdivision code has currently an abysmal performance and is thus not yet
really usable, especially with many ngons and variable topology in animations.
After opensubdivs performance issues have been fixed, this legacy code can go again.
Not before.
2018-12-12 22:16:44 +01:00
0f093de7f3 re-added metaball remesher and deform motionblur in cycles for it and FM 2018-12-12 21:38:23 +01:00
5f25071d1b added testwise threaded fracture via openmp
after more testing this might be converted to task, but works ok already, and added only
trivial changes to the code
2018-12-12 15:40:06 +01:00
39d8449f7e submodule pointers.. yawn 2018-12-12 15:38:59 +01:00
3ffbac0de8 fixed some memory leaks, removed unused "reset" parameter in fracture operator
also for now disabled "Geometry limitation tree", intent was to accelerate voronoi + bisect
by only processing "necessary" new geometry (and omitting unchanged), but doesnt work correctly
2018-12-12 15:36:24 +01:00
31e8634dac Merge remote-tracking branch 'origin/blender2.8' into fracture_modifier-2.8
# Conflicts:
#	source/blender/modifiers/intern/MOD_boolean.c
2018-12-10 17:28:25 +01:00
6d2edc97a1 forgot to display rigidbody settings subpanel with opengl render engine 2018-12-09 23:19:54 +01:00
60bce45b8a crash fix attempt when adding / removing rigidbody worlds
still issues when appending FM objects, need to re-add rigidbodies and refracture
2018-12-09 22:15:05 +01:00
e8e4ba9b5d added shape-based clusters
clustergroup object with meshes will now cut out clusters according to their mesh,
make sure mesh is subdivided enough for better results
2018-12-09 16:37:30 +01:00
a9e575ce65 fix attempt for having proper constraints with dynamic fracture again
"mixed" and "all" settings were basically not properly taken into account before
2018-12-09 00:55:25 +01:00
e90424544a added new cluster trigger propagation feature and a couple of fixes
fixes for example for split to island crashs
2018-12-08 20:13:10 +01:00
44ea1f75a0 forgot to free duplilist after usage, and re-added previously removed depsgraph relation
relation is necessary to smoothly looking continued motion after dynamic fracture
2018-12-03 22:10:30 +01:00
e52c7c4676 attempt to add more detail for dynamic fracturing 2018-12-03 20:14:37 +01:00
40794110d4 fix for external constraints (centroid) 2018-12-02 13:38:27 +01:00
d6e2e2572a crash fix attempts for split to island function 2018-12-01 22:21:57 +01:00
3d0a325148 try to avoid crashes due to excessive usage of immediate draw buffer
since the buffersize is limited to 4 MB (but it effectively crashed above usage of 3 MB,
probably due to 4 bit padding), there is a hard limit of usage ratio to be taken into account. The debug drawer counts the bytes used and increases an epsilon value as softlimit
first. This filters out short lines / very close verts and reduces the buffer usage. If that is not enough, there is a hard limit at 95% buffer usage. Then line drawing is skipped.
2018-11-30 19:42:45 +01:00
7723dc5485 got physics visualization operational again
kudos to hypersomniac for pointing me to the debug draw api
2018-11-30 17:40:53 +01:00
a7306bd50f attempt to fix pack group and export to objects 2018-11-30 16:06:45 +01:00
1eba694945 attempt for fixing fake cloth + dynamic fracture 2018-11-30 01:48:05 +01:00
96161c80ed added duplis as fracture "source"
this basically converts e.g. particle duplis to individual rigidbodies
2018-11-29 18:54:50 +01:00
d6100f8d48 dynamic fracture: fix for depsgraph thread jamming / crashes
the modifier eval thread made calls (validate shard) which changed the rigidbody thread's data from outside, before control is passed to rigidbody thread again (both tasks / threads follow each other alternatingly, first rigidbody, then modifier, then again rigidbody and so on after frames do change. Solution was to delay validation and let the rigidbody thread do it, instead of forcing it from the modifier thread.
2018-11-27 20:48:13 +01:00
e3bcc2d0d5 dynamic fracture: when using constraints, keep those of unaffected shards in place
internally all constraints are removed just after bullet step, and rebuilt in modifier
eval call following it, so it will be there on next bullet step. else you mess up the sim
if you stop and restart it.
2018-11-27 15:35:01 +01:00
908c6c4946 removed separate pack operator, execute fracture handles this now 2018-11-25 20:52:18 +01:00
028df92b64 removed accidental code merge failures 2018-11-25 13:59:28 +01:00
96140b706e updated submodule pointers to match latest 2.8 2018-11-25 12:38:53 +01:00
77d43236c3 Merge remote-tracking branch 'origin/blender2.8' into fracture_modifier-2.8
# Conflicts:
#	release/scripts/addons
#	source/blender/blenkernel/intern/armature_update.c
#	source/blender/editors/interface/interface_templates.c
#	source/blender/python/intern/bpy_app_handlers.c
2018-11-25 12:36:44 +01:00
e50f8cfdde cleanup, removed (non-working) compound stuff again 2018-11-25 11:57:30 +01:00
b1721771a2 cleanup, sensible rename and code documentation, first part 2018-11-25 00:49:01 +01:00
c5f52f87d0 added dynamic shard count setting, to decouple from prefractured 2018-11-24 14:00:36 +01:00
9b9963b9df fix for odd behavior with constraints and dynamic
was necessary to delete all constraints in each modifier evaluation when using dynamic
2018-11-24 13:18:20 +01:00
681279ba60 mainly fixing some warnings, further fix attempts for misbehavior with constraints/dynamic 2018-11-24 01:42:46 +01:00
b56af321a3 some more dynamic fracture stability fixes 2018-11-23 18:39:35 +01:00
d3da8f964c partial fix for bullet related crashes or lockups
especially when 2 or more dynamic objects fracture each other, there are still crashes / lockups
2018-11-23 14:21:08 +01:00
7a19768059 seems dynamic cache behavior is fixed, tests looked good . 2018-11-22 22:03:24 +01:00
2c97140258 execute fracture in dynamic should return the intact object 2018-11-22 14:39:12 +01:00
8a2ee5573c added constraint search size, made mixed/none constraint setting in dynamic work
plus fix attempts for dynamic cache logic
2018-11-22 14:20:51 +01:00
475132e0ce added separate activation shard size for dynamic fracture 2018-11-21 23:37:35 +01:00
9d74833412 exposed apply_force and apply_torque for rigidbody to python 2018-11-21 19:13:06 +01:00
b10611f957 using proper random number generator now + fixed dynamic trigger 2018-11-21 15:31:19 +01:00
50a9322eeb fix attempt for dynamic fracture 2018-11-19 13:44:11 +01:00
baabe028a4 brought compound back + some recent fixes from 2.7 branch 2018-11-18 17:39:19 +01:00
4729279fd5 Merge remote-tracking branch 'origin/blender2.8' into fracture_modifier-2.8
# Conflicts:
#	release/scripts/startup/bl_operators/presets.py
#	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
2018-11-16 10:32:29 +01:00
a035b9f609 some more fix attempts for dynamic fracture cache behavior 2018-11-15 21:21:39 +01:00
f2f9829933 fixes for preset property names 2018-11-13 16:39:31 +01:00
ed348890c1 Merge remote-tracking branch 'origin/blender2.8' into fracture_modifier-2.8
# Conflicts:
#	release/scripts/addons
#	release/scripts/addons_contrib
#	source/blender/blenkernel/BKE_customdata.h
#	source/blender/blenkernel/intern/bvhutils.c
#	source/blender/depsgraph/intern/depsgraph_query_filter.cc
#	source/blender/editors/interface/interface.c
#	source/blender/editors/object/object_modifier.c
#	source/blender/editors/object/object_relations.c
#	source/blender/makesrna/RNA_access.h
#	source/blender/modifiers/intern/MOD_boolean.c
2018-11-13 15:08:38 +01:00
3618df78a8 fix for python ui 2018-11-06 10:10:46 +01:00
63bf87364c Merge remote-tracking branch 'origin/blender2.8' into fracture_modifier-2.8
# Conflicts:
#	release/scripts/addons
2018-08-31 23:08:00 +02:00
433fac8f1e keep ob->flag and ob->base_flag in sync, else there were problems 2018-08-28 12:44:27 +02:00
600c4e86d1 compile fixes for windows 2018-08-26 00:04:55 +02:00
ac06f77d25 proper collection iteration in updateDepsgraph etc + couple of fixes 2018-08-25 18:46:40 +02:00
bd1e6e00a6 small fix for extra particle/ extra vert group, submodule pointer correction 2018-08-24 23:19:19 +02:00
8287a46f84 Merge remote-tracking branch 'refs/remotes/origin/blender2.8' into fracture_modifier-2.8
Conflicts:
	build_files/cmake/macros.cmake
	release/scripts/addons
	release/scripts/addons_contrib
	release/scripts/startup/bl_ui/properties_physics_common.py
	release/scripts/startup/bl_ui/properties_physics_fluid.py
	release/scripts/startup/bl_ui/properties_physics_rigidbody.py
	source/blender/blenloader/intern/readfile.c
	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
	source/tools
2018-08-24 14:00:34 +02:00
c2231bc4c9 fixes and polishing recently implemented features 2018-08-23 12:42:45 +02:00
4ac1aeebc7 most stuff re-implemented, but still rather buggy, needs polish. 2018-08-23 03:18:22 +02:00
fdb5188e60 attempt for proper reset of new cache together with pointcache 2018-08-22 12:06:51 +02:00
ab326d2920 improvement for dynamic fracture 2018-08-21 22:31:02 +02:00
9e6db7f70b first attempt of getting dynamic fracture back working 2018-08-21 18:04:35 +02:00
cf9221f4ee fixed some crashes regarding automatic cache reallocation 2018-08-21 02:31:02 +02:00
2f7c0c94c9 decouple FM motion data cache from pointcache
the FM stores validity and motiondata in its meshislands, the point cache only holds the objects.
2018-08-20 23:26:23 +02:00
bf64551fc3 split to islands and autoexecute work again
re-using meshisland works too, but oddly initially the mesh is not drawn, needs to have a "pointsource"
selected, but re-using meshislands works with empty pointsource atm
2018-08-19 13:26:30 +02:00
aac1b9ab77 crash fix with voronoi + fractal boolean 2018-08-18 13:37:22 +02:00
070d6c167f couple of smaller fixes
fixes like resetting to start position after cancelling animation or using the input scene for the current
frame (not the evaluated one)
2018-08-18 11:40:48 +02:00
5951f1e5e1 fix for another memory / crash issue 2018-08-18 01:05:20 +02:00
9703c6f481 fixes for fractal boolean, autohide and convert to objects
works all partially only still, because other blender things dont work as expected any more...
2018-08-17 22:31:25 +02:00
5c3b85a4c9 removed all known memleaks happening in FM so far 2018-08-16 22:14:24 +02:00
f592c365ef memory leak hunting with partial success 2018-08-16 18:35:57 +02:00
97dad8496c fix for fastbisect with orthogonal cuts, also fix for crash in FM free function 2018-08-15 23:31:57 +02:00
f19fb8e1f4 only sort meshes for fastbisect/fill and fractal now
also removed commented old shard / fracmesh structs, they appeared in makesdna too still
2018-08-15 23:11:03 +02:00
868280331e further rewrite to make more readable / maintainable code 2018-08-15 14:36:06 +02:00
289a8a59c8 complete rewrite of ugly code pieces, work in progress 2018-08-14 23:21:44 +02:00
744c07b263 made FM more CoW compliant and added some sanity checks 2018-08-14 17:29:33 +02:00
4681e66f15 removing shards from fracture modifer (work in progress)
only dealing with mesh_islands now, they have been partially rewritten as well
2018-08-14 15:00:28 +02:00
aa644d7b31 some more rigidbody refactor and crash fix for fracturing in debug mode 2018-08-12 01:22:23 +02:00
a4412f2b72 crash fix for deform mblur velocity precalculation (port from 2.7x FM) 2018-08-11 00:49:44 +02:00
fdc3da9646 do not init copy any more (was incorrect behavior) 2018-08-10 11:41:19 +02:00
e3e29cad3e cheap "storage" solution for now, just recreate on load 2018-08-10 00:44:54 +02:00
026ba72bff Merge branch 'blender2.8' into fracture_modifier-2.8
Conflicts:
	source/blender/makesdna/DNA_modifier_types.h
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/modifiers/MOD_modifiertypes.h
	source/blender/modifiers/intern/MOD_util.c
	source/tools
2018-08-09 23:58:58 +02:00
327e1d335e added "shared" pointer prop in RNA
this way access to mesh_islands / mesh_constraints is possible again
2018-08-09 23:34:13 +02:00
7a9197ea38 FM is more stable / usable now in 2.8 2018-08-09 21:15:43 +02:00
797b15e684 simulation jumps and interrupts itself still, regular rigidbodies crash... 2018-08-09 17:47:35 +02:00
1f88c9c667 yay first fracture sim in 2.8 :) (but not very stable yet) 2018-08-09 14:11:32 +02:00
c697d298f6 cleanup, removed flag at freeData again 2018-08-09 13:29:45 +02:00
c70d802a23 still trying to get simulation to work 2018-08-09 13:18:13 +02:00
8ebe58dc1d put FM storage contents into cow-shared struct 2018-08-09 01:13:37 +02:00
a3d433acb8 split rigidbody.c to regular and fractured part 2018-08-08 19:54:54 +02:00
3f703f2acf intial fracturing ok, CoW makes trouble 2018-08-08 16:08:43 +02:00
a8cc5180d8 Merge remote-tracking branch 'refs/remotes/origin/blender2.8' into fracture_modifier-2.8 2018-08-08 09:42:04 +02:00
173bb6314a further compile fixes 2018-08-08 01:15:09 +02:00
f70caf38d7 hmm nothing happens so far when fracturing... 2018-08-08 00:18:28 +02:00
83b386220c trying to get it working again, temporarily 2018-08-07 23:47:47 +02:00
8c54c02564 yay, blender starts again :) 2018-08-07 23:00:32 +02:00
bdb663df0c yay, finally it compiled. but py is broken still 2018-08-07 20:56:04 +02:00
5549751774 more compile fixes 2018-08-07 20:22:10 +02:00
d415458465 some compile fixes 2018-08-07 13:53:39 +02:00
fe6e5123c0 Merge branch 'fracture_modifier' into fracture_modifier-2.8 2018-08-06 21:37:11 +02:00
16b07fb08d allow grid spacing > 1 2018-08-03 11:22:08 +02:00
3436ed8df7 use voro particle order now correctly, fixes brick fracture problems. 2018-08-02 13:42:32 +02:00
63ec1f4f9d fix for ghost trigger (again) 2018-07-29 21:27:04 +02:00
ea4be4d1b1 execute operator warns now if current frame is not on cache startframe 2018-07-28 23:45:07 +02:00
f811c08407 restore ghost stop trigger functionality 2018-07-28 13:05:28 +02:00
0f15570266 attempt to fix incorrect (bbox) triggering behavior 2018-07-27 17:04:42 +02:00
b82de8463b do not set edges of selected faces to sharp in external mode
because in most cases only existing objects are packed into the FM mesh, and no fracturing happens,
where you want to set fracture edges to sharp.
2018-06-25 16:50:42 +02:00
1d880e8e0b enable angular limit/stiffness/damping settings for plastic constraints
in fact, only forgot to uncomment
2018-06-23 16:21:43 +02:00
9a21afd18d fix for cmake failing to detect VS 2017 properly 2018-05-24 23:55:19 +02:00
d3b52a6cbc added ghost stop triggers
stopped shards also will get their constraints disabled and still attached partners will be stopped too
2018-05-24 14:45:27 +02:00
da4854a8b8 missed in last commit: rise BM_OMPLIMIT to avoid overheads with small datasets 2018-05-02 20:45:37 +02:00
f3ce2881c3 fix a clang warning, fix an improper initialisation for gcc, remove nonfunctional omp, rise BM_OMPLIMIT to avoid overheads with small datasets 2018-05-02 20:41:56 +02:00
dac9244425 crash fix for changing shardcount and refracture when doing automerge
forgot to refresh the merge data before merging, after refracturing
2018-04-25 22:09:25 +02:00
192ae864f4 added isIntact() query to regular rigidbody constraints, too 2018-04-25 14:17:26 +02:00
18ba072f17 immediately take constraint limit changes into account during rigidbody simulation 2018-04-17 14:55:27 +02:00
d451c4e831 fix for setting lower x linear limit 2018-04-15 12:57:56 +02:00
16ccab4748 Merge remote-tracking branch 'refs/remotes/origin/blender-v2.79b-release' into fracture_modifier 2018-04-14 20:53:09 +02:00
f4dc9f9d68 Fix T54360: FFMPEG bitrate not editable for all codecs
The bitrate selection was hidden when a CRF mode was chosen and then
switched to a codec that doesn't support CRF.
2018-03-22 15:10:42 +01:00
6f07673ce4 Fix compilation error
Recent fix was assuming some cleanup is done.
2018-03-22 09:56:06 +01:00
150dee260e Update addons submodule hash 2018-03-22 09:51:05 +01:00
55872de560 Fix T54234, add BLENDER_VERSION_CHAR to .plist 2018-03-22 09:48:31 +01:00
6bf458dfff Fixed: cache clearing when using multiple Alembic files. 2018-03-22 09:44:12 +01:00
61c3317688 Cleanup: Use more python way of checking boolean 2018-03-22 09:41:22 +01:00
0253b16180 Tracking: Make object created form tracks active and selected 2018-03-22 09:41:18 +01:00
3ed28ccb93 Tracking: Warn when no tracks are selected when creating mesh
Makes it more clear why mesh was not created this way.

Fixes T54368: 3D markers to mesh In MovieClipEditor Not working.
2018-03-22 09:41:10 +01:00
d791f3522e Fix T54348: Bone dissolve gives invalid hierarchy
Disconnected bones weren't handled correctly.
2018-03-22 09:39:11 +01:00
557e1b02de Fix bone dissolve using wrong envelope radius
Also correctly copy bone tip selection when dissolving.
2018-03-22 09:38:47 +01:00
5da3aecefd Fix T53478, T53430: Sequencer cut edge case fails
Previous fix for T53430 caused T54200.

The edge case for soft & hard cuts weren't working,
where the strip used start/end-still & the frame was placed exactly on
the start/end of of the sequence content.

T54200 fixed the end-still case but broke hard-cuts for all other cases.

This fixes the case for soft/hard cuts with/without start/end-still.
2018-03-19 11:36:25 +01:00
241c142248 Revert "Fix T53430: Cut at the strip end fails w/ endstill"
This reverts commit 855799ecc1.

Caused T54200
2018-03-19 11:36:18 +01:00
c5db594b92 Error passing context arg to marker menu
own mistake in 6981861fcf
2018-03-19 11:36:11 +01:00
e57a1bb86b API generating script: give better version for releases builds.
Was giving '2.62.1 <sha1>' even for releases, now rather giving nicer
'2.62a <sha1>' in that case.
2018-03-19 11:36:02 +01:00
4697e491b4 Fix T54206: bevel and inset operations repeat did not remember offset.
Now repeating the operator will use the previously chosen offset, either with
the modal operator or typed in. The modal operator will still start at zero.
2018-03-19 11:35:55 +01:00
852d63b835 Fix T54204: Wrong selection on Clean Tracks (Motion Tracking)
A mistake in a fix for T53612.

Regression in 2.79a, candidate for 2.79b :S
2018-03-19 11:35:46 +01:00
8ec398d401 Fix T54003: Particles - Size and random size not present in "physics" tab in Advanced mode
The check to see if `use_advanced_hair` was enabled was actually in two places
(render panel `draw` function and physics panel `poll` function). As these
properties are only in one place now the check in `draw` isn't needed anymore.

Related: T53513, a6c69ca57f
2018-03-19 11:35:20 +01:00
9accd8852b Bl;ender 2.79b: Begin 2.79b release cycle 2018-03-19 11:33:15 +01:00
c381b3fadc added vertexgroup to influence metaball radii
note, the weight (0...1) is normed to a size factor -0.5 ... 0.5 to also allow negative mball elements.
2018-02-28 17:54:10 +01:00
3cc1faf118 when sorting objects, keep mi->object_index aligned 2018-02-25 19:48:05 +01:00
d39fb8ffbb activate by constraint impulse and regular ghost triggers 2018-02-25 15:46:40 +01:00
930b6a0540 rna build fix (error when building debug) 2018-02-25 00:02:38 +01:00
882cf08e5e only calc FM mblur velocity layer at render time
this costs some performance
2018-02-24 17:32:50 +01:00
fb8acd8b33 optionally restore old activation behavior with broken constraints
this allows easier breaking / collapsing of objects
2018-02-24 11:20:44 +01:00
e88359152a compile fixes after merge 2018-02-22 13:03:08 +01:00
fb4fcd6e01 Merge remote-tracking branch 'refs/remotes/origin/blender-v2.79a-release' into fracture_modifier
Conflicts:
	source/blender/modifiers/intern/MOD_boolean.c
2018-02-22 13:02:34 +01:00
8928d99270 VSE: skip non image/movie w/ proxy dir storage
This would use uninitialized filename variable,
looked into supporting this however generating proxies currently only
works for movies.
2018-02-21 21:41:31 +11:00
9e707802c2 Depsgraph: Fix crash using --debug-depsgraph and --debug-depsgraph-no-threads
Was accessing past the array boundaries.

Should be safe for 2.79a.
2018-02-21 10:53:05 +01:00
ae358f92e6 fix, anim bind rotation was calculated incorrectly 2018-02-20 13:45:53 +01:00
db0f53ae3c fix for bind ngon problems (jumping rotations) 2018-02-19 18:46:30 +01:00
09aaee5640 Fix T53032: Image sequence works bad with Displace modifier
We shouldn't mix image pool acuisition with and without user provided,
the fact that internally image.c uses last frame from Image datablock
confuses the logic.
2018-02-19 14:38:25 +01:00
dc5aaac3a2 Blender 2.79a: Update submodules hash for addons 2018-02-19 11:33:45 +01:00
a4dbff33c9 Blender 2.79a: Prepare for release
Enter release state and make spacing to "a" more sane.

There is still at least one fix we want to get in, before declaring we are
ready for release.
2018-02-19 10:49:46 +01:00
750798a777 crash fix for deleting connected objects before its connectors 2018-02-18 11:20:39 +01:00
76dfe5f0b4 crash fix for FM objects being copied after connect 2018-02-18 02:31:37 +01:00
446ed1c516 rigidbody sort fix for external constraints 2018-02-18 00:51:05 +01:00
4e1c31ca7b crash fix for external constraints
ensure refresh of "parent" FM object on every refresh of connected objects, also ensure evaluation order in rigidbody.c / bullet (parent always after children)
2018-02-17 13:42:26 +01:00
59cc0bfef5 Fix T54075: Align Objects fails w/ empty mesh 2018-02-15 15:49:03 +11:00
9268ff4b21 Cleanup: Python context access
Avoid access from bpy when it's already declared.
2018-02-15 15:49:03 +11:00
7ae9b96ac6 Fix T54072: Crash splitting edges 2018-02-15 15:49:03 +11:00
bc891ad124 Fix T53958: Sequencer zoom 1:1 fails 2018-02-15 15:49:03 +11:00
3982a36c10 Minor change to last commit
Keep mode checks simple, nest other checks in their body.
2018-02-15 15:49:03 +11:00
f5c0df3601 Fix T53986: Crash saving during sculpt stroke
Also remove unused struct member.
2018-02-15 15:49:02 +11:00
81697c772c Fix: msvc build error with bli_fileops.h
bli_fileops.h was using uint64_t without including the proper header.

issue triggered by rBb0af44fa4d7a2e134b315c49a4fbdf573f781004
2018-02-15 15:49:02 +11:00
6f45c9d6c6 Fix T50630: Fluid fails on win32 w/ unicode paths
Allow overriding gzip open w/ elbeem.
2018-02-15 15:49:02 +11:00
d1281bf993 Fix navmesh creation w/ multiple objects
D2976 by @dertom
2018-02-15 15:49:02 +11:00
c40e9a1ad2 Docs: invoke_search_popup uses bl_property
Also add code example in docs.
2018-02-15 15:49:02 +11:00
748ada90b5 further constraint related crash fixes 2018-02-14 21:04:00 +01:00
6868e0a7d9 crash fix attempts
can still crash if you refracture a child object while its attached to others (constraints become invalid)
2018-02-14 20:26:07 +01:00
6249febf45 re-implementation of external constraints 2018-02-14 18:41:30 +01:00
d16510425f external constraints load / refresh fix 2018-02-13 19:17:52 +01:00
c491b50139 fix potential memory leak 2018-02-13 18:19:18 +01:00
4eb44b8610 another implementation attempt for external constraints 2018-02-13 18:07:41 +01:00
97a677e788 first attempt of brickify fracture 2018-02-12 22:19:07 +01:00
21f19224f3 Fix part of T53080: don't use current scene world for icon previews.
This can be very slow if it contains a big texture, and it's not
necessarily setup in a useful way anyway, and materials can be used
in multiple scenes.
2018-02-12 20:37:41 +01:00
c3d5668516 fix for "double rotation" in bind
if both objects were rotated, rotations were added up unnecessarily.
2018-02-11 10:58:44 +01:00
032b14a951 fractal boolean with regular alignment, animation bind tweaks 2018-02-10 23:50:25 +01:00
f29a691fb4 inner material is part of presets now 2018-02-09 17:40:31 +01:00
f6abf9d0ba Fix (unreported) crash when duplicating a FileBrowser window in preview draw mode.
We did not clear preview or smoothscroll timers pointers in copy code...
2018-02-09 16:25:08 +01:00
e5917d624e Fix missing group duplicated by hair in render
Was happening when viewport visibility on the particle system is disabled.
This became an issue after c45afcf, but the actual issue goes a bit deeper
and the following aspects were involved:

- Relations builder for particle system was ignoring particle system if
  it's visibility is not enabled for viewport. This is something what
  shouldn't have been done -- depsgraph relations are supposed to be the
  same no matter if it's viewport or render.

- Relation builder was only dealing with duplication set to object, but
  was ignoring group duplication.

This is NOT a regression since 2.79, but a regression since 2.79a-rc1.
2018-02-06 15:37:24 +01:00
ea82f4ce4e fix an ffmpeg qtrle crasher 2018-02-04 22:21:20 +01:00
bac2541ffa Fix T53686: VSE Render crash when zooming timeline.
Epic fail from recent 'security' fixes (rBe04d7c49dca9). ;)

To be backported to 2.79a!
2018-02-01 15:56:37 +01:00
3e2909cf9d Fix T53962: Cycles OpenCL compile error in some scenes.
This part of 212a8d9e needed to be ported over for 2ca933f to work.
2018-01-31 15:28:19 +01:00
1052497aad Fix possible concurency issue in mesh normals computation.
Failure in own code from last December, thanks @sergey for finding it.

To be backported to 2.79a.
2018-01-31 12:46:06 +01:00
567b4fa794 Fix T52634: EditMesh Remove doubles could hang
A single diagonal axis was used for sorting coordinates,
the algorithm relied on users not having vertices axis aligned.

Use BLI_kdtree to remove doubles instead.

Overall speed varies, it's more predictable than the previous method.
Some typical tests gave speedup of ~1.4x - 1.7x.
2018-01-31 09:56:53 +11:00
d7c7ce2a7b BLI_kdtree: utility function to remove doubles 2018-01-31 09:56:53 +11:00
f5ef3a7d81 animation bind rotation fix, some dynamic mode fixes 2018-01-29 20:51:25 +01:00
de563552da IMB: Add asserts that returned fps and fps base are strictly positives.
Forgot to add that in previous commit, also related to T53003.
2018-01-26 15:18:30 +01:00
3ee1a7978f Related to T53003: tweak scene fps range.
Move restricted 'reasonable' range to ui_range, and allow wider values
for manual settings.
2018-01-26 15:18:30 +01:00
a73b390f48 Fix T53003: IMB: Invalid framerate handling due to short integer overflow.
FFMPEG uses int for the numerator, while Blender uses a short. So in
cases people gave weird exotic framerate values and we cannot reduce
enough the numerator, we'd get totally weird values (even negative frame
rates sometimes!)

Now we add checks for short overflow and approximate as best as possible
in that case (error should not matter unless you have shots of at least
several hundreds of hours ;) ).
2018-01-26 15:18:30 +01:00
0e37c98257 Fix part of T53080: all material previews re-rendering after undo.
This reverts commit dc2617130b, which disabled
writing of previews for undo. While this uses some memory, re-rendering all
previews is very expensive, especially if for example you have lots of materials
using high-res image textures.
2018-01-26 08:45:37 +01:00
8fedf97883 improved rotation calculation in bind animated mesh 2018-01-26 00:08:41 +01:00
0859c99bf2 fix for loading crash with dynamic fracture
forgot to copy the fracmesh, but this now might increase mem usage
2018-01-25 16:08:25 +01:00
4c1bed0a12 Fix T53593: sculpt brush rake spacing bug after recent bugfix. 2018-01-24 16:06:13 +01:00
95a31c8a3a fix attempt for split shard to island crashes
customdata was incorrectly freed and corrupted the memory
2018-01-24 14:28:36 +01:00
d68f53a3f3 added a limit / searchradius for animated mesh binding
bind operator now clears the simulation cache too
2018-01-23 18:05:14 +01:00
2f5a027b94 Cycles: Fix bug in user preferences with factory startup
Namely, the issue would happen when CPU device was never used before.
Issue with wrong merge conflict resolution.
2018-01-23 16:16:09 +01:00
da98a2c5ff forgot to include workaround for changing vertex counts 2018-01-22 22:42:41 +01:00
3691bf1a20 fix attempt for bind animated mesh 2018-01-22 21:33:31 +01:00
61335d853d Blender 2.79a: Use latest dev-tools
This way release checker used by Linux release environment is corrected.
2018-01-22 15:48:41 +01:00
43d1bfea40 Blender 2.79a: Show both version char and rc text on splash 2018-01-22 14:41:22 +01:00
4cda3e2d87 Blender 2.79a: Use proper version char 2018-01-22 14:38:57 +01:00
dc4afef1da Blender 2.79a: Point submodules to updated hash 2018-01-22 14:32:20 +01:00
8553449cf2 Task scheduler: Start with suspended pool to avoid threading overhead on push
The idea is to avoid any threading overhead when we start pushing tasks in a
loop. Similarly to how we do it from the new dependency graph. Gives couple of
percent of speedup here, but also improves scalability.
2018-01-22 12:57:08 +01:00
af83535dd0 Task scheduler: Clarify why do we need an atomic add of 0 2018-01-22 12:56:35 +01:00
a3616980c6 Cycles: Fix crash opening user preferences after adding extra GPU
We can not store pointers to elements of collection property in the
case we modify that collection. This is like storing pointers to
elements of array before calling realloc().
2018-01-22 12:54:00 +01:00
2f6d7946a4 Cycles tests: Add extra image tests 2018-01-22 12:39:11 +01:00
c3237cdc13 Fix T53012: Shadow catcher creates artifacts on contact area
The issue was caused by light sample being evaluated to nan at some point.
This is root of the cause which is to be fixed, but is very hard to trace down
especially via ssh (the issue only happens on AVX2 release build). Will give it
a closer look when back to my AVX2 machine.

For until then this is a good check to have anyway, it corresponds to what's
happening in regular radiance sum.
2018-01-22 12:39:11 +01:00
417170159a Fix retro-futuristical atempt to include some keymaps for non-backported feature from master.
Was making unittests unhappy.
2018-01-22 12:32:08 +01:00
6036bf7497 Revert "Node selection: Stop operator when mouse selection selected a node"
This reverts commit bf58ec9265.
2018-01-22 12:22:44 +01:00
a50c381fac Cycles: Fix difference in image Clip extension method between CPU and GPU
Our own implementation was behaving different comparing to OSL and GPU,
namely on the border pixels OSL and CUDA was doing interpolation with
black, but we were clamping coordinate.

This partially fixes issue reported in T53452.

Similar change should also be done for 3D interpolation perhaps, but this
is to be investigated separately.
2018-01-22 12:20:51 +01:00
b90f3928a3 Fix T53850: Lock to Cursor breaks 3D manipulators 2018-01-22 20:34:44 +11:00
cae8c68ca6 Fix manual lookups (data is now lowercase) 2018-01-22 10:14:20 +11:00
79563d2a33 Fix old files with changed node socket type not loading correctly.
This would lead to sock.default_value pointing to the wrong data type,
possibly causing crashes. Unfortunately, this bug will still exist for
older Blender versions that try to load newer files, which makes
changing the type of a node socket problematic.
2018-01-20 23:35:10 +01:00
82f7726549 crash fix at fracturing, customdata layer index handlng was incorrect 2018-01-19 21:30:23 +01:00
b6481cbbe5 Fix T53823: Particle weight brush crash
Entering particle edit mode w/ the weight brush enabled crashed
on non-hair particle systems.
2018-01-19 15:06:19 +11:00
5b3538e02a Fix T53832: Particle weight paint crash
Drawing hair weights read before the hair array start.
This code could be improved since it currently copy-pastes,
from do_particle_interpolation, but this would need larger changes.

For now just correct existing logic.
2018-01-19 15:06:19 +11:00
c3873a5156 Fix memory leak in recent curve refactor
5b25605761fb7
2018-01-18 19:24:49 +01:00
8dbd5ea4c8 Fix buffer overflow vulnerability in curve, font, particles code.
Solves these security issues from T52924:
CVE-2017-12102
CVE-2017-12103
CVE-2017-12104

While the specific overflow issue may be fixed, loading the repro .blend
files may still crash because they are incomplete and corrupt. The way
they crash may be impossible to exploit, but this is difficult to prove.

Differential Revision: https://developer.blender.org/D3002
2018-01-18 19:24:43 +01:00
9287434fa1 Fix buffer overflow vulnerabilities in mesh code.
Solves these security issues from T52924:
CVE-2017-12081
CVE-2017-12082
CVE-2017-12086
CVE-2017-12099
CVE-2017-12100
CVE-2017-12101
CVE-2017-12105

While the specific overflow issue may be fixed, loading the repro .blend
files may still crash because they are incomplete and corrupt. The way
they crash may be impossible to exploit, but this is difficult to prove.

Differential Revision: https://developer.blender.org/D3002
2018-01-18 19:24:32 +01:00
2ae9d757b3 Fix Linux/GCC compiler warning in recent fixes. 2018-01-18 19:23:45 +01:00
04c5131281 Fix buffer overflow vulernability in thumbnail file reading.
Fixes CVE-2017-2908 from T52924.

Differential Revision: https://developer.blender.org/D3001
2018-01-18 19:23:40 +01:00
16718fe4ea Fix buffer overflows in TIFF, PNG, IRIS, DPX, HDR and AVI loading.
Solves these security issues from T52924:
CVE-2017-2899
CVE-2017-2900
CVE-2017-2901
CVE-2017-2902
CVE-2017-2903
CVE-2017-2904
CVE-2017-2905
CVE-2017-2906
CVE-2017-2907
CVE-2017-2918

Differential Revision: https://developer.blender.org/D2999
2018-01-18 19:23:33 +01:00
a972729895 Memory: add MEM_malloc_arrayN() function to protect against overflow.
Differential Revision: https://developer.blender.org/D3002
2018-01-18 19:23:27 +01:00
5ddcad4377 Fix T53810: Crash removing a scene used in render
Header drawing accesses the scene too.
2018-01-17 14:06:54 +11:00
8fd65dc0e9 corrected some more special constraint breaking activation behavior (was activating too much) 2018-01-17 00:12:49 +01:00
f72e6fcdfa Revert "Fix T53752: Draw curve fails w/ stylus"
This reverts commit d0e0f33f57.

Requested by author, since it raised new issues, better not have it in
bugfix release!
2018-01-16 17:19:17 +01:00
022d64008e small transform fix for animated mesh binding 2018-01-15 16:55:29 +01:00
7ef50296e0 some corrective changes in special breaking activation behavior 2018-01-14 20:13:53 +01:00
80671518eb put animated mesh settings to new panel, some fixes 2018-01-14 20:12:53 +01:00
91ce295796 Fix T53772: Presets don't support colons 2018-01-14 14:51:59 +11:00
db72a8a6e0 fix for binding, should leave no shards behind now 2018-01-14 01:34:12 +01:00
13973a5bbf Fix T47212: Luminance Key not working with HDR and out-of-gamut ranges.
Differential Revision: https://developer.blender.org/D2981
2018-01-13 02:50:52 +01:00
824c039230 Fix T53567: Negative pixel values causing artifacts with denoising
Now negative color values are clamped to zero before the actual denoising.
2018-01-13 02:42:39 +01:00
Stefan Werner
a623c02569 Cycles: Fixed compilation of CUDA kernels. Follow-up fix for my last commit. 2018-01-13 02:41:57 +01:00
Stefan Werner
b3adce7766 Cycles: Workaround for performance loss with the CUDA 9.0 SDK.
CUDA 9.0.176 apparently caused some slow down on high-end Pascal cards that can be mitigated by increasing the number of registers. See https://developer.blender.org/F1142667 for a detailed comparison.
2018-01-13 02:41:25 +01:00
30a0459f2c Fix T53692: OpenCL multi GPU rendering not using all GPUs.
Ensure each OpenCL device has a unique ID even if the hardware ID is not
unique for some reason.
2018-01-13 02:40:09 +01:00
2ca933f457 Fix T53755: Cycles OpenCL lamp shaders have incorrect normal. 2018-01-13 02:38:08 +01:00
758d7350d6 fixes for bind animated mesh: transform and jump issues 2018-01-13 00:39:18 +01:00
2a41da1d91 experimental bind of animated vertices (other object) to shards
this transfers vertex motion during simulation and allows some kind of "deformation" of the fractured mesh, without
refracturing it
2018-01-12 13:15:22 +01:00
f12ab4e196 Cleanup: SGI format, remove unused struct members 2018-01-12 21:20:52 +11:00
7b8b621c1d Fix SGI foramt reader CVE-2017-2901
Integer Overflow Code Execution Vulnerability.

Reader no longer crashes on corrupt images (from own fuzz testing).
2018-01-12 21:20:52 +11:00
6a86a1f082 Cleanup: SGI format, avoid overflow
Harmless but causes warnings
2018-01-12 21:20:52 +11:00
e9548a6184 Cleanup: SGI format, use uint/short/char types 2018-01-12 21:20:52 +11:00
20cccb1561 Fix bmesh.utils.face_join arg parsing 2018-01-12 15:56:53 +11:00
57b11d8b4e Fix T53311: transform edge/normal orientation
When the edge is aligned with it's own normals,
transform orientation wasn't aligned with the edge.
2018-01-12 15:56:53 +11:00
38357cd004 Fix background_job template
Update attribute and use empty file operator
2018-01-12 15:55:30 +11:00
d0e0f33f57 Fix T53752: Draw curve fails w/ stylus 2018-01-11 11:22:37 +11:00
ee7042173c fixed a crasher when moving an object in dynamic fracture and when attempting to undo/redo FM removal 2018-01-10 22:00:45 +01:00
91ea5336a5 removed some performance-deadly reallocs in remesher
remesher now atleast responds again to user input and runs with 0.6fps with 60^3 particles
2018-01-10 04:09:54 +01:00
db74c06dd6 Additional fix after cherry-picking rB870840e8b7dd (in rB72151f3e36b). 2018-01-09 14:31:20 +01:00
e4e2e3a15d Add an 'atomic cas' wrapper for pointers.
Avoids having to repeat obfuscating castings everywhere...
2018-01-09 14:27:32 +01:00
71e0894e0d Fix scalability issue in threaded code of Mesh normals computation.
We tried to do as much as possible in a single threaded callback, which
lead to using some nasty tricks like fake atomic-based spinlocks to
perform some operations (like float addition, which has no atomic
intrinsics).

While OK with 'standard' low number of working threads (8-16), because
collision were rather rare and implied memory barrier not *that* much
overhead, this performed poorly with more powerful systems reaching the
100 of threads and beyond (like workstations or render farm hardware).

There, both memory barrier overhead and more frequent collisions would
have significant impact on performances.

This was addressed by splitting further the process, we now have three
loops, one over polys, loops and vertices, and we added an intermediate
storage for weighted loop normals. This allows to avoid completely any
atomic operation in body of threaded loops, which should fix scalability
issues. This costs us slightly higher temp memory usage (something like
50Mb per million of polygons on average), but looks like acceptable
tradeoff.

Further more, tests showed that we could gain an additional ~7% of speed
in computing normals of heavy meshes, by also parallelizing the last two
loops (might be 1 or 2% on overall mesh update at best...).

Note that further tweaking in this code should be possible once Sergey
adds the 'minimum batch size' option to threaded foreach API, since very
light loops like the one on loops (mere v3 addition) require much bigger
batches than heavier code (like the one on polys) to keep optimal
performances.
2018-01-09 14:14:59 +01:00
72151f3e36 Subsurf: Avoid possible use of partially initialized edge hash 2018-01-09 14:12:17 +01:00
83b0603061 Subsurf: Avoid global lock for loops and orig index layers
This is a bit annoying to have per-DM locking, but it's way better (as in, up to
4 times better) for playback speed when having lots of subsurf objects,
2018-01-09 14:11:58 +01:00
b01fe3bf01 install_deps: Fix OCIO always re-cloning its whole git repository. 2018-01-08 17:23:33 +01:00
4c8aa61be2 No groping in Blender's Tracker!
This a small cleanup of something which I think is just a typo anyway.

With all the recent talks of harrassment and groping, I think we better avoid
that within our source code! :)

Reviewers: sergey

Reviewed By: sergey

Tags: #motion_tracking

Differential Revision: https://developer.blender.org/D2979
2018-01-08 17:23:22 +01:00
a1d05ac2a1 Fix T53612: Blender crashes on CleanTracks with 'DELETE_SEGMENTS' and a disabled marker
Simple fix, which is totally safe for 2.79a!
2018-01-08 17:23:09 +01:00
0c365472b6 Fix T53509: Datablock ID Properties attached to bpy.types.Material are not loaded.
Stupid mistake in material reading code, thanks to Simon Wendsche (@BYOB) for the investigation and fix!

To be backported to 2.79a.
2018-01-08 17:23:02 +01:00
010cf35e7e (Nodes) Display image name if any in the Image and Texture Image node title 2018-01-08 17:21:45 +01:00
2a9abc0f5e Fix T53650: remove hard limits on force field size and max distance.
Differential Revision: https://developer.blender.org/D2987
2018-01-08 17:21:34 +01:00
Dalai Felinto
e4dce3b3d7 Fix leak when rendering OpenGL animations
We were duplicating rectf twice :/

Patch by Clément Foucault.
2018-01-08 17:21:16 +01:00
243b961c29 Fix T52953: Crash removing material 2018-01-08 17:21:04 +01:00
42e207b599 Fix T53678: Smart Project UV margin ignores units 2018-01-08 17:19:15 +01:00
32fb50179f nstall_deps: llvm downloads new website location
Patch by Lucas Walter (@lucasw), thanks.

Reviewers: mont29

Reviewed By: mont29

Subscribers: mont29

Differential Revision: https://developer.blender.org/D2983
2018-01-08 17:18:52 +01:00
Dalai Felinto
c70a45027d Fix T53513: Particle size showing in multiple places
Technically this was introduced in 01b547f993 when
exposing size and randomness for particles.

This "fixes" makes sure particle size and size randomness is always in the
Render panel when it affects the particle system (i.e., always unless using
advanced hair or hair that is not rendering groups/objects).
2018-01-08 17:17:01 +01:00
8f7030e5f3 Fix T53639: text sequence strips no stamped into render.
Differential Revision: https://developer.blender.org/D2977
2018-01-08 17:16:46 +01:00
405874bd79 Fix MSVSC2017 error
The last compiler version needs this include
2018-01-08 17:16:05 +01:00
6afe655be0 bpy_extras: add missing colorband keymap to keyconfig_utils.py
fixes failing ctest script_load_keymap
2018-01-08 17:15:44 +01:00
c721f93958 Fix missing SpinLock typedef on macOS 2018-01-08 16:49:31 +01:00
dfed7c48ac Fix T53068: AMD Threadripper not working well with Blender
The issue was caused by SpinLock implementation in old pthreads we ar eusing on
Windows. Using newer one (2.10-rc) demonstrates same exact behavior. But likely
using own atomics and memory barrier based implementation solves the issue.

A bit annoying that we need to change such a core part of Blender just to make
specific CPU happy, but it's better to have artists happy on all computers.

There is no expected downsides of this change, but it is so called "works for
me" category. Let's see how it all goes.
2018-01-08 16:49:27 +01:00
391f7cc406 Cycles: Fix compilation error of standalone application 2018-01-08 16:49:22 +01:00
b6f3fec259 Cycles: Fix compilation error with OIIO compiled against system PugiXML 2018-01-08 16:49:16 +01:00
49f57e5346 Cycles: Fix compilation error with latest OIIO
There was some changes about namespaces, which causes ambiguities.

Replaces using namespace with an explicit symbols we need. Is good idea to NOT
pull in the whole namespace anyway!
2018-01-08 16:49:11 +01:00
9a5320aea3 Fix T52818: Tangent space calculation is really slow for high-density mesh with degenerated topology
Now we replace O(N^2) computational complexity with O(N) extra memory penalty.
Memory is much cheaper than CPU time. Keep in mind, memory penalty is like
4 megabytes per 1M vertices.
2018-01-08 16:47:08 +01:00
85dc915413 Mikkspace: Cleanup, reduce indentation level 2018-01-08 16:47:01 +01:00
4c46f69376 Fix T53398: Surface deform modifier says that convex polygons are concave for big faces
Dot-product for angle check need either to be divided by vectors magnitude or be
calculated for normalized vectors.
2018-01-08 16:46:50 +01:00
b8bdca8c0a Fix T53499: Cannot load DPX files
The issue was caused by unspecified color transfer. New behavior gives same
result as other viewers here, so likely is fine :)
2018-01-08 16:46:37 +01:00
ba40d8f331 Fix T53007: OpenSubdiv + transparency = artefact/crashes 2018-01-08 16:46:08 +01:00
3ad84309df Fix T52940: VSE Glow Effect Strip on transparent images has no blur 2018-01-08 16:45:57 +01:00
09c387269a Fix T52982: Join operator with context override crashes Blender 2.79 2018-01-08 16:45:45 +01:00
259e9ad00d Fix T52927: Compositor wrong scale when scale size input is connected to complex node
The issue here is that we can not read scale from socket when determining
dependent area of interest. This area will depend on current pixel. Now fall
back to more stupid but reliable thing: if scale size input is connected to some
nodes, we use the whole frame as area of interest.
2018-01-08 16:45:33 +01:00
d305c10104 Fix T52920: Saving Tiff Files type Blender crashes
Was only happening for 3 and 1 channel sources.
2018-01-08 16:45:07 +01:00
9f916baa70 Fix T52086: Graph editor "normalize" drag errors for integers 2018-01-08 16:44:42 +01:00
754630cee4 Fix T52823: New Depsgraph - Shrinkwrap crashes blender
The issue was caused by threading conflict around looptris: it was possible
that DM will return non-NULL but non-initialized array of looptris.

Thanks Campbell for second pair of eyes!
2018-01-08 16:42:36 +01:00
00d8097510 Fix T52763: Boolean problem with vertex group 2018-01-08 16:42:27 +01:00
7377b36660 Fix copy-paste error in recent particles fix
Was intersecting same triangle twice.
2018-01-08 16:42:16 +01:00
17c00d222f Fix T52732: Particle system volume grid particles out of volume
Use more watertight and robust intersection test.

It uses now ray to triangle intersection, but it's all fine because segment was
covering the whole bounding box anyway.
2018-01-08 16:42:09 +01:00
1b8e8326b4 Fix T52537: Dyntopo "detail flood fill" doesn't work in some cases
Mainly when object origin is not at the geometry bounding box center.

Seems to be straightforward to fix, hopefully it doesn't break some obscure case
where this was a desired behavior.
2018-01-08 16:41:39 +01:00
3ffb0f6983 Cycles: Tweaks to avoid compilation error of megakernel
Also moved code out of deep-inside ifdef block, otherwise it was quite confusing.
2018-01-08 16:38:36 +01:00
6f19787e52 Fix T53552: Unneeded particle cache reset on frame change
There shouldn't be a time dependency to cache reset operation.
2018-01-08 15:26:51 +01:00
0596d208a0 Depsgraph: Add missing checks from previous commit 2018-01-08 15:24:12 +01:00
76032b133c Depsgraph: Don't make non-dynamic hair dependent on time
This way hair system used for static forest does not make playblack slow.

A bit dangerous, but let's see how far we can go!
2018-01-08 15:21:21 +01:00
8cdda3d2ad Fix T53547: Metaballs as dupli objects are not updated with the new Depsgraph
Follow relations from old dependency graph.
2018-01-08 15:14:05 +01:00
7103c6ef3b Depsgraph: Fix relations for metaballs
Initially spotted and investigated by Dalai and Germano.
2018-01-08 15:12:31 +01:00
075950ad66 Cycles: Fix wrong shading when some mesh triangle has non-finite coordinate
This is fully unpredictable for artists when one damaged object makes the whole
scene to render incorrectly. This involves two main changes:

- It is not enough to check triangle bounds to be valid when building BVH.
  This is because triangle might have some finite vertices and some non-finite.

- We shouldn't add non-finite triangle area to the overall area for MIS.
2018-01-08 15:09:01 +01:00
93d711ce55 Cycles: Fix possible race condition when initializing devices list 2018-01-08 15:06:56 +01:00
d91b6099a6 Depsgraph: Fix wrong flag being assigned 2018-01-08 15:05:53 +01:00
d5dbe0c566 Fix T52741: Follow track with depth object crashes Blender with new depsgraph 2018-01-08 15:01:32 +01:00
c8f95c7829 Fix T53419: Masking "Add" menu is not present in Image editor, but shortcut is 2018-01-08 14:52:51 +01:00
26ffade5c1 Fix T53713: User remap failed w/ texface images 2018-01-08 17:00:36 +11:00
1611177ac9 Fix T53586: Surfaces collapse when joined 2018-01-08 14:50:30 +11:00
1c32d67f46 Cleanup: --help text
Sync with manual
2018-01-08 09:50:57 +11:00
c63e08863d Fix T53054: Parentless bone + IK crashes 2018-01-08 09:44:42 +11:00
528e00dae0 Fix T53696: Compositor HSV limits changed 2018-01-08 09:30:12 +11:00
a123dafdc0 fix T52831 removed enforcement of matrix decomposition when animations are exported 2018-01-06 16:38:19 +01:00
Mathieu Menuet
1f50f0676a Fix T53017: Cycles not detecting AMD GPU when there is an NVidia GPU too.
Best guess is that cuInit() somehow interferes with the AMD graphics driver
on Windows, and switching the initialization order to do OpenCL first seems
to solve the issue.
2018-01-06 16:34:50 +01:00
4f247ed07a Fix T53143: Knife Crash after Grid Fill
BM_ELEM_INTERNAL_TAG flag wasn't ensured to be cleared.
2018-01-05 10:48:39 +11:00
868bde5920 BLI_utildefines_iter: Use for iteration helpers 2018-01-05 10:48:39 +11:00
02b206780e BMesh: move bridge tools stepping logic into macro
Also use floor division since regular division was giving a bias
on negative error values.
2018-01-05 10:48:39 +11:00
8ca11b7084 Math Lib: add divide_floor_i
Integer division that floors on negative output (like Python's).
2018-01-05 10:48:39 +11:00
8c484d0bda Fix T53637: Keymap from app-template ignored
Addon's were also ignored
2018-01-05 10:20:16 +11:00
3815c3a324 Revert "BLI_utildefines: Support SWAP macro with two args"
This reverts commit d749320e3b.

It's possible the container struct is larger,
we could do sizeof checks that falls back to memmove
but rather avoid complicating things.
2018-01-05 10:20:16 +11:00
36971ea276 Use custom SWAP macro for swapping userdef data
Avoids complicating the common case
2018-01-05 10:20:16 +11:00
38fdfe757d Fix T53274: Saving template prefs overwrites default prefs 2018-01-05 10:20:15 +11:00
6cba84edf2 BLI_utildefines: Support SWAP macro with two args 2018-01-05 10:20:15 +11:00
9f0ebb0941 WM: load UI for new file, even when pref disabled
Loading startup file always loads the UI now.
2018-01-05 10:20:15 +11:00
571e801b27 WM: don't load preferences on 'File -> New'
User preferences are now only loaded on...

- Initial startup.
- Factory-settings.
- Setting app-templates.
2018-01-05 10:20:15 +11:00
7622563ae3 mblur for fm use centroids / use vertices was missing on remesher, some crash fixes 2018-01-05 00:00:01 +01:00
facc7658db crash fixes, was accessing non-existing layers 2018-01-04 20:44:02 +01:00
054d6d7ac3 deform motionblur support for FM and remesher with variable topology
furthermore some tweaks to final solid mesh generation and trigger stuff
option to only output particles as vertexcloud in remesher
2018-01-04 19:32:13 +01:00
71ffddfa0f fixed some crashers 2018-01-04 02:38:18 +01:00
ad2e6534cc first attempt of deform mblur with remeshed particles, but it still has issues 2018-01-04 02:08:44 +01:00
08cd50dcde crash fix in updateAccelerationMap, forgot to check for dm being null 2018-01-03 17:24:32 +01:00
d88b0ac261 fix for transformation issue with particle remeshing 2018-01-03 16:26:44 +01:00
7735128993 fix for presets, forgot some commas 2018-01-03 16:07:12 +01:00
942b6e933b BLI_heap: minor changes to the API
Recent addition of 'reinsert' didn't match logic for ghash API.

Rename to BLI_heap_node_value_update,
also add BLI_heap_insert_or_update since it's a common operation.
2018-01-03 22:49:51 +11:00
eaeb0a002e Use BLI_heap_reinsert for decimate and beautify
Improves performance for high poly meshes,
~70% faster for decimate, only ~10% for beautify.
2018-01-03 22:49:51 +11:00
71d79e6ea2 BLI_hash: add BLI_heap_reinsert
Allows avoiding remove/insert calls.
2018-01-03 22:49:51 +11:00
a68cc528dd GTest: initial BLI_heap test 2018-01-03 22:49:51 +11:00
e79e0c7483 Correct gtest error in recent beautify change 2018-01-03 22:49:50 +11:00
4a457d4f1e Polyfill Beautify: half-edge optimization
Was using an edge hash for triangle -> edge lookups,
updating triangle indices for each edge-rotation.

Replace this with half-edge which can rotate edges much more simply,
writing triangles back once the solution has been calculated.

Gives ~33% speedup in own tests.
2018-01-03 22:49:50 +11:00
1b6130533f Beauty fill was skipping small faces 2018-01-03 22:49:50 +11:00
9d501d23cb Fix T52871: beauty fill error
Only lock tri's facing different directions.
Needed because scanfill creates zero area faces.
2018-01-03 22:49:50 +11:00
39fc93208a Revert "Fix T52871: BLI_polyfill_beautify_quad_rotate_calc_ex was mistakenly considering the state as degenerated"
This reverts commit a8f11f5422.

Result is no longer symmetrical, will investigate a different fix.
2018-01-03 22:49:50 +11:00
9298d99b77 Fix T52871: BLI_polyfill_beautify_quad_rotate_calc_ex was mistakenly considering the state as degenerated 2018-01-03 22:49:50 +11:00
9e18fcbb36 BLI_polyfill2d_test: script to generate test data 2018-01-03 22:49:50 +11:00
ef5b7d34a1 Cleanup: redundant casts 2018-01-03 22:49:49 +11:00
426616da43 Correct test ifdef in polyfill 2018-01-03 22:49:49 +11:00
9be59fa752 BLI_polyfill2d_test: add test for T52834
Commented since it currently fails.
2018-01-03 22:49:49 +11:00
93d3015e61 BLI_polyfill2d_test: Try flipped x/y axis
In T52834 this makes a difference.
2018-01-03 22:49:49 +11:00
fe3f504902 Missing from last commit 2018-01-03 22:49:49 +11:00
9299936726 Cleanup: use stubs for eigen gtest 2018-01-03 22:49:49 +11:00
8131eda51e Boolean Modifier: add debug options
Only show & use when running in debug mode.
2018-01-03 22:49:48 +11:00
569d2df634 Avoid bias when calculating quad split direction
Some error checks weren't being done in both directions
when calculating the best split direction for a quad.
2018-01-03 22:49:48 +11:00
6e133ad8b1 Correct recent error in boolean quad split check 2018-01-03 22:49:48 +11:00
58ab62ed6d BMesh: use less involved check for edge rotation
Was using function for edge rotation which was doing unnecessary checks
Use the face normal and BLI_polyfill_beautify_quad_rotate_calc directly.
2018-01-03 22:49:48 +11:00
0834eefae0 Polyfill Beautify: option to rotate out of degenerate state
Needed for 3D iterative edge-rotation to avoid flipping when projected
from different angles,
but could keep zero area faces in 2D polygons.
2018-01-03 22:49:48 +11:00
34857b2032 Fix error in recent boolean changes w/ quad split 2018-01-03 22:49:48 +11:00
78cc3c828f Fix T52291: Boolean fails w/ co-linear edged ngons
This means boolean tessellation wont match viewport tessellation
however it's needed to avoid zero area triangles causing problems.
2018-01-03 22:49:48 +11:00
04125d8a9c Math Lib: clamped rounding utility functions 2018-01-03 22:49:48 +11:00
659dc34823 BLI_utildefines: sync w/ 2.8 2018-01-03 22:49:47 +11:00
eaf14b1ebf fix T53230: avoid Nullpointer problems in Collada Exporter 2018-01-02 14:55:53 +01:00
866be3423c Fix incorrect MIS with principled BSDF and specular roughness 0. 2018-01-01 17:46:44 +01:00
440d647cc1 Fix part of T53038: principled BSDF clearcoat weight has no effect with 0 roughness. 2018-01-01 17:29:47 +01:00
cd9c68f0c5 CMake: support CUDA 9 toolkit, and automatically disable sm_2x binaries.
Fermi cards (GTX 4xx and 5xx) are no longer supported with this version, so
we can keep supporting both CUDA 8 and 9 for a while.
2018-01-01 17:29:26 +01:00
f1ee24a284 Fix T52801: reload scripts causes Cycles viewport render crash. 2018-01-01 17:28:45 +01:00
df1af9b349 Fix Cycles bug in RR termination, probability should never be > 1.0.
This causes render differences in some scenes, for example fishy_cat
and pabellon scenes render brighter in a few spots. This is an old
bug, not due to recent RR changes.
2018-01-01 17:27:16 +01:00
836a1ccf72 Fix T53600: Cycles shader mixing issue with principled BSDF and zero weights.
SVM nodes need to read all data to get the right offset for the following node.
This is quite weak, a more generic solution would be good in the future.
2018-01-01 17:13:04 +01:00
c4f8d924e1 Fix T53309: Remove default 'Clear loc/rot/scale delta transform' shortcuts.
The loc one (shift-alt-G) was same as 'remove selected from active group'
action... Clear delta transform is not a common operation, so we can
live without a default shortcut for it.

Note that using same key (G) in same space for two completely different
kind of operations is probably a rather bad thing, nice topic for future
keymap work. ;)

Probably nice to have in 2.79a.
2018-01-01 16:13:53 +01:00
08e16e0bd1 Fix: Undo pushes were missing for Add/Remove Driver Variable buttons, and Remove Driver button 2018-01-01 16:03:30 +01:00
969196069a Fix T53300: Bone Extrude via Ctrl + Click is not done from active bone tail 2018-01-01 16:03:25 +01:00
6cfc5edb86 Fix T53185: After rendering an animation (Ctrl-F12), pressing F12 no longer renders single frames only 2018-01-01 16:03:20 +01:00
99e4c819f7 Fix: When transforming GP strokes in "Local" mode, the strokes would get obscured
by the transform constraint lines

Ported over e7395c75d5 from the
greasepencil-object branch. I should've fixed this ages ago, but
couldn't figure out why at the time.
2018-01-01 16:03:14 +01:00
ca236408f3 Fix T52861: Keymap editor filter doesn't show shortcuts using "+" 2018-01-01 16:03:09 +01:00
f887b8b230 T50354: Action length calculation added unnecessary padding if some F-Curves
only contained a single key (on the last real frame of the action).
2018-01-01 16:03:03 +01:00
48079e1f11 Fix T52733 Percent mode for Bevel sometimes had nans.
Forgot some initialization.
2018-01-01 16:02:21 +01:00
bae796f0d5 Alembic import: fixed mesh corruption when changing topology
When the mesh changed topology but kept the vertex count the same, it would
result in a corrupt mesh. By checking the face & loop counts too, this has
become less likely.

I've checked IPolyMeshSchema::isConstant(), but it returns true even when
we see that the mesh changed topology.
2018-01-01 16:01:36 +01:00
Stefan Werner
02bac54fa9 Compositor: Ensured 16 byte alignment for variables accessed by SSE instructions.
Before this patch, the XBlur/YBlur compositor nodes would crash for me when run in a MSVC 2015 debug build (test scene: BMW27_cpu). I added the compiler instructions to explicitly align the local variables that the SSE instructions are accessing.
2018-01-01 16:01:29 +01:00
Dalai Felinto
8f9d9ba14e Fix logic for pinning textures users from context
This was wrong since it's concenption in 28ee0f9218.
The if statement was returning true when pinid was NULL, and false otherwise.

However when scene is pinned we also want to run this code.
Code snippet by Brecht Van Lommel.
2018-01-01 15:58:23 +01:00
José Luis Oliveira Cunha
576899b90a Fix T53116: default texture coordinates for volume materials are blank.
Differential Revision: https://developer.blender.org/D2935
2018-01-01 15:57:51 +01:00
0f841e24b0 Fix T53572: Alembic imports UV maps incorrectly
Since in Alembic the loop order seems to be reversed when exporting and
importing, and this was the only place where it was not, I was thinking
to match this to the convention of reversing the loop order as well.

Reviewers: sybren, kevindietrich

Tags: #alembic

Differential Revision: https://developer.blender.org/D2968
2018-01-01 15:57:23 +01:00
Daniel Silva
ce35151f38 Proposed fix for T53263 -- Blender crashes when rendering with Stabilizer 2D node without movie selected
The program won't crash anymore, but a warning won't be displayed. Anyway, this gives the user the chance to save the project.

https://developer.blender.org/T53263

Reviewers: lukastoenne

Differential Revision: https://developer.blender.org/D2934
2018-01-01 15:56:50 +01:00
3659620b47 Fix compilation error with clang-5 2018-01-01 15:56:18 +01:00
f3002ab43b Space clip: Make it more clear that filter track does not use any settings from tool shelf 2018-01-01 15:55:46 +01:00
3a1ade22e5 GPU: Fix memory corruption in GPU_debug on GTX1080
Number of texture formats is 51, which is greater than allowed size of 32.
2018-01-01 15:54:54 +01:00
b5c629e604 Cycles: Fix possible race condition when generating Beckmann table
Two issues here:

- Checking table size to be non-zero is not a proper way to go here. This is
  because we first resize the table and then fill it in. So it was possible that
  non-initialized table was used.

  Trickery with using temporary memory and then doing table.swap() might work,
  but we can not guarantee that table size will be set after the data pointer.

- Mutex guard was useless, because every thread was using own mutex. Need to
  make mutex guard static so all threads are using same mutex.
2018-01-01 15:54:02 +01:00
89de073ea5 Fix T52835: When driven IK influence change, ik animation have 1 frame delay 2018-01-01 15:53:54 +01:00
0cdfe887b4 OpenVDB: Fix compilation error against OpenVDB 4
One crucial thing here: OpenVDB shoudl be compiled WITHOUT
OPENVDB_ENABLE_3_ABI_COMPATIBLE flag. This is how OpenVDB's Makefile is
configured and it's not really possible to detect this for a compiled library.

If we ever want to support that option, we need to add extra CMake argument and
use old version 3 API everywhere.
2018-01-01 15:53:48 +01:00
7de7e47a97 CMake: Add extra requests dependencies
Apparently, we already had some code to deal with this. So for now just
added some extra dependencies needed for latest requests.
2018-01-01 15:53:41 +01:00
2213153c27 Fix T52432: Blender crashes while using Ghost (new depsgraph) 2018-01-01 15:53:35 +01:00
ef04aa4a43 Transform: Enable recursion dependency check for new depsgraph 2018-01-01 15:53:28 +01:00
538182511a Fix T52749: New Depsgraph - Render View Mask is not initialized correctly 2018-01-01 15:53:22 +01:00
3532fe2b8b Masks: Split layer evaluation into separate function
This way we can easily re-use bits of code for new dependency graph.

Currently should be no functional changes.
2018-01-01 15:53:15 +01:00
3182336666 Fix T52113: Compositor doesnt mix unrendered render layers well
Compositor was always defaulting to all-zero s output for missing passes.

This was broken in 4cf7fc3.
2018-01-01 15:53:09 +01:00
5efc8e16e6 Compositor: Cleanup, get rid of nested ternary operators
Having single switch statement is much more readable.
2018-01-01 15:53:03 +01:00
7947eead71 Compositor: Cleanup, de-duplicate some code 2018-01-01 15:52:56 +01:00
8cd3bd99f7 Compositor: Cleanup, reduce indentation level in render layer node
There is absolute no reason to have such an indentation level, it only causes
readability and maintainability issues. It is really simple to make code more
"streamlined".
2018-01-01 15:52:49 +01:00
e7aad8fd0e Fix T53559: Auto texture space for text and font is wrong in Cycles
The issue actually goes a bit deeper, converting curve to mesh will
change texture space just because font and bezier curves are using CV
to calculate texture space.

So now when those objects are converted to mesh, we disable auto
texture space and copy evaluated space over.
2018-01-01 15:45:56 +01:00
bf58ec9265 Node selection: Stop operator when mouse selection selected a node
Previously, hitting Shift-LMB will first invoke selection operator, which
then later on is transformed to mouse tweak used for reroute operator.

This was causing problems extending selection with Shift-LMB when clicking
fast or from a tablet.
2018-01-01 15:45:07 +01:00
1c7657befb Fix T53371: Keying Node fails with values above 1
This was expected behavior for over-exposured lamps when the mode was originally
created for Tears of Steel. Turns out, there could be really bad green screen in
real production which will only have green (or rather screen) channel over
exposured.

Tweaked condition now so we use least bright channel to see if the area has
proper exposure or not.

Seems to work fine in tests, but further tweaks are possible.
2018-01-01 15:45:01 +01:00
333ef6e6f7 Tracking: Create mesh from selected tracks only
Patch by Sebastian Koenig. thanks!
2018-01-01 15:44:56 +01:00
ad7385422e Fix T53048: OSL Volume is broken in Blender 2.79
Was a mistake in optimization commit which was disconnecting closures and nodes
which does not make sense for volume output.

OSL script we can't ignore and can't currently know in advance if it's a proper
volume shader or not. So we never disconnect OSL nodes from volume output.

This is a good candidate for corrective release.
2018-01-01 15:44:50 +01:00
ad834085b7 Fix T52932: Driver with target of custom property from scene fails to update
Note that this is only supported in new depsgraph.
2018-01-01 15:44:45 +01:00
2edc2b4912 Curves: Fix wrong bitset being checked against CYCLIC bit flag
Based on report from Talos Security Advisory.
2018-01-01 15:44:39 +01:00
d87bf29399 Tracking: Followup to previous fix, need to remap frame number for sequence tracking 2018-01-01 15:44:33 +01:00
990ce0c4f0 Tracking: Cleanup, reuse existing variable 2018-01-01 15:44:27 +01:00
f0743b56ec Fix T52851: Per-frame traking is broken when sequence doesn't start at frame 1 2018-01-01 15:44:21 +01:00
350f5c6894 Tracking: Fix crash when tracking failed
Was a dangling pointer to a freed memory left behind.
2018-01-01 15:44:15 +01:00
69062cdd8d Fix T52840: New Depsgraph - Mask editor not working correctly 2018-01-01 15:44:09 +01:00
3163d0e205 Fix T52811: At any framerate selected, video exported with 1000fps 2018-01-01 15:43:31 +01:00
aafe528c7d Fix T51416: Blender Crashes while moving Sliders
The issue here was that removing datablock from main database will poke editors
update, which includes buttons context to free users of texture. Since Cycles
will free datablocks from job thread, it might crash Blender since main thread
might be in the middle of drawing.

Solved by exposing extra arguments to bpy.data.foo.remove() which indicates
whether we want to perform ID user count and interface updates. While scripts
shouldn't be using those normally, this is the only way to allow Cycles to skip
interface update when removing datablock.

Reviewers: mont29

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D2840
2018-01-01 15:43:25 +01:00
9c39f021ad Fix T52739: Crash loading corrupted video files
Affects both "normal" open as a video file and thumbnail generation.
2018-01-01 15:43:19 +01:00
cdc35e63bd Fix T52299: X resolution of 4 causes nodes to collapse
Was caused by numeric overflow when calculating preview dimensions.
Now we try to avoid really insance preview resolutions by fitting
aspect into square.
2018-01-01 15:42:39 +01:00
3a0f199aa7 Fix T52140: Align objects centers using origin for text
The issue was caused by operator redo which frees all object's evaluated data,
including bounding box. This bounding box can not be reconstructed properly
without full curve evaluation (need to at least convert font to nurbs, which is
not cheap already).
2018-01-01 15:42:32 +01:00
b0c55d5c94 Fix T52573: Cycles baking artifacts
Synchronize condition for faces split between Cycles itself and baking API.
2018-01-01 15:42:25 +01:00
759af7f1ee Fix T52679: Hole in bake normal
In fact, any type of baking might have caused holes in mesh.

The issue was caused by zspan_scanconvert() attempting to get order of traversal
'a-priori', which might have failed if check happens at the "tip" of span where
`zspan->span1[sn1] == zspan->span2[sn1]`.

Didn't see anything bad on making it a check when iterating over scanlines and
pick minimal span based on current scanline. It's slower, but unlikely to cause
measurable difference. Quality should stay the same unless i'm missing something.

Reviewers: brecht, dfelinto

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2837
2018-01-01 15:42:16 +01:00
c616dd58c6 minor fix for collision problem with mesh 2017-12-31 01:57:54 +01:00
4bc89d815c Fix T53630: Effect strips not displaying Input data.
Fix T52977: Parent bone name disappeared in the UI in pose mode.

Regression caused by own rBc57636f060018. So instead of changing widget
type, just flag it as disabled.

Note that core of the issue is elsewhere though - there is absolutely no
reasons to have a search widget for pointers we cannot change nor
search! But fixing this is not really top priority, one of the many
glitches of our UI code, so think we can live with current code.

To be backported to 2.79a.
2017-12-30 17:52:33 +01:00
8a9d64b578 Fix T53463: Rotation numerical input shows instable behaviour.
Inverting a number in radians when user is in degrees gives rather
unexpected results. ;)
2017-12-30 17:52:28 +01:00
50ca70b275 Fix T53420: Vertex Groups: The "-" button gets a hidden function
Guess 'remove all unlocked' is new-ish feature...

To be backported to 2.79a (I think).
2017-12-30 17:52:21 +01:00
ff8c9c5931 Fix T53343: Custom Normal Data Transfer Crashes when some vertexes have no faces.
Odd nobody noticed this earlier, was obvious bug in code logic here... :/

To be backported to 2.79a.
2017-12-30 17:52:16 +01:00
06df30a415 Fix T53250: Crash when linking/appending a scene to a blend when another linked scene in this blend is currently open/active.
Inner DAG code would not check against NULL pointer, and in case of an
active linked scene, scene pointer will be NULL here, so we have to
check it ourself. ;)
2017-12-30 17:51:30 +01:00
5f2307d1a7 Fix T53191: Python API Reference link wrong in splash screen.
Forgot to update splashscreen links when we switched API doc naming
scheme...
2017-12-30 17:51:25 +01:00
3193045c59 Fix bad 'poll' prop callback API doc.
This was added to all prop types, when it is only available for Pointer ones.
2017-12-30 17:51:12 +01:00
2895cb22a7 3D View: use shortest angle between quaternions
Gave incorrect smoothview speed changing between some axis and
axis locking.
2017-12-30 17:45:40 +01:00
01ff07af56 Math Lib: signed versions of quaternion angle
There was no simple way to get the shortest quaternion angle.
2017-12-30 17:45:33 +01:00
6d640504e8 bl_app_override: support empty UI layout items
Returning None from ui_ignore functions creates empty labels,
allows removing items without breaking layout in some cases.
2017-12-30 17:45:27 +01:00
5ab1897de7 Fix T53430: Cut at the strip end fails w/ endstill 2017-12-30 17:45:21 +01:00
75aec5eeaa WM: minor correction to user-pref writing
When saving templates had wrong return value.
2017-12-30 17:44:44 +01:00
0c456eb90a Docs: clarify return value for BVH API 2017-12-30 17:44:38 +01:00
6639350f92 Fix BMesh PyAPI internal flag clearing logic
Would leave the flag set on raising an exception.
2017-12-30 17:43:53 +01:00
ce6e30b3dc Fix edge-split bmesh operator giving empty result 2017-12-30 17:43:47 +01:00
69f6ab98e7 Docs: correct descriptions 2017-12-30 17:43:39 +01:00
3e3a27d089 Edit Mesh: click extrude, ensure inverse matrix
Relied on this being set elsewhere which isn't assured.
2017-12-30 17:43:33 +01:00
a253b1b7bc Docs: add note for bmesh face_split_edgenet 2017-12-30 17:43:24 +01:00
6058b651c4 Fix sculpt secondary color missing some brushes
D2841 by @uvwxyz w/ edits
2017-12-30 17:43:17 +01:00
98dc9072e5 Fix brush reset (missing notifier)
D2843 by @uvwxyz
2017-12-30 17:43:06 +01:00
6b2d1f63db Fix incorrect allocation size 2017-12-30 15:48:49 +01:00
275002106c makesdna/makesrna: silence output by default
No need to print status for basic & reliable operations,
build systems can output operations they run if needed,
or debug output changed in the source if developers are debugging.

Nice for ninja, so any printed text hints at a problem to fix.
2017-12-30 15:48:43 +01:00
413817a3d2 Fix T53577: Rake sculpt/paint wrong on first step 2017-12-30 15:48:33 +01:00
869e4a3420 Fix T53322: Collada export crash w/ shape keys
D2958 by @cmbasnett
2017-12-30 15:48:28 +01:00
84361a0709 Fix missing update for particles w/ fluids
D2955 by @GonVas
2017-12-30 15:48:22 +01:00
52a5daa404 Fix T53529: Rip crashes w/ wire edge 2017-12-30 15:48:16 +01:00
db3e3f9c24 Fix for inset when accessed from spacebar search 2017-12-30 15:48:10 +01:00
19b27d84ab Fix T53441: Inset doesn't start at zero 2017-12-30 15:48:05 +01:00
480b0b5dfc Fix T53410: 3D Text always recalculated 2017-12-30 15:47:58 +01:00
7153cee305 Fix T53342: Outliner 'select hierarchy' broken
Was using cursor position from within menu,
clicking on the same position for every selected item (toggling).

Now operate on each selected outliner element, without toggling.
2017-12-30 15:47:52 +01:00
d2d207773e Fix BGE sound actuator property access 2017-12-30 15:47:46 +01:00
8ea3f6438d Fix T53294: bpy.ops.image.open crash 2017-12-30 15:47:41 +01:00
60e8d86fb1 Fix T53131: Incorrect vert-edge angle calculation
Vertex w/ a single edge wasn't detected
2017-12-30 15:47:34 +01:00
1ab828d4bb Fix T53004: XWayland ignores cursor-warp calls
There is currently a limitation in XWayland,
the cursor needs to be hidden during warp calls.
2017-12-30 15:47:28 +01:00
7f6e9c595b Fix T52959: Local view looses clip range on exit 2017-12-30 15:47:21 +01:00
b0fbe95a1b Fix ruler access from search pop-up
D2831 by @1xundoredo
2017-12-30 15:46:26 +01:00
8c9bebfe28 Fix setting the operator name in Py operator API 2017-12-30 15:46:20 +01:00
9f032c3867 Fix error copying smoke modifier uv layer 2017-12-30 15:46:13 +01:00
eaba111bd5 Fix T52890: Crash unlinking sequencer sound 2017-12-30 15:46:07 +01:00
b969f7eb55 Fix T52860: 3D Text crashes w/ Ctrl Backspace 2017-12-30 15:46:01 +01:00
4c3e2518c8 UI: fullstop at end of tooltips
Allows for multiple sentences not to look strange.
Convention not to include in RNA remains.
2017-12-30 15:45:55 +01:00
a437b9bbbe UI: avoid int cast before clamping number input
Values outside int range would overflow.
2017-12-30 15:45:02 +01:00
d07011da71 Fix T51074: Boolean modifier inverts operation
Support for negative scaled objects.
2017-12-30 15:44:55 +01:00
acae901a10 Fix writing Iris images w/ invalid header
Regression in e142ae77ca
2017-12-30 15:44:49 +01:00
495aa77b53 Fix T52384: Bridge pair result depends on other loops
When 2x loops have different number of vertices,
the distribution for vertices fan-fill depended on the loop order
and was often lop-sided.

This caused noticeable inconstancies depending on the input
since edge-loops are flipped to match each others winding order.
2017-12-30 15:44:43 +01:00
e627620efd Docs: only show versions in changelog side-bar 2017-12-30 15:44:38 +01:00
7d872629c4 Correct error in last commit 2017-12-30 15:43:36 +01:00
60bfa969e2 Fix T52748: Select shortest face path fails 2017-12-30 15:43:29 +01:00
d89353159f Fix T52442: bl_app_templates_system not working
Portable builds LOCAL files need to be
treated as system instead of using as a fallback to USER templates.
2017-12-30 15:43:23 +01:00
21ecdacdf1 Fix bpy.utils.resource_path('SYSTEM') output
Would return the test path for developer builds:
{blender-dirname/release}

Now return an empty string when no path is found.
2017-12-30 15:43:16 +01:00
0641069778 Fix T52723: Reset UV layers failed 2017-12-30 15:43:09 +01:00
5b2d5f9077 Fix T53171: lamp specials strength tweak fails with renamed emission nodes. 2017-12-30 15:32:59 +01:00
f901bf6f47 Fix T53092: errors reading EXR files with different data/display window.
Multilayer/multiview OpenEXRs did not read the full data window like single
layer, now it should be consistent.
2017-12-30 15:32:52 +01:00
198fd0be43 Fix T53348: Cycles difference between gradient texture on CPU and GPU. 2017-12-30 15:32:45 +01:00
f968268c1e Fix build with OSL 1.9.x, automatically aligns to 16 bytes now. 2017-12-30 15:32:40 +01:00
2bc667ec79 Fix T52368: Cycles OSL trace() failing on Windows 32 bit. 2017-12-30 15:32:34 +01:00
d564beda44 Fix T53217: GLSL principled BSDF black with zero clearcoat roughness. 2017-12-30 15:32:28 +01:00
f1a4e130b3 Fix T53145: bevel tool does not start with amount at zero. 2017-12-30 15:32:18 +01:00
36f324fc55 Fix T53145: bevel tool fails when used a second time.
Pixel size was not initial early enough. For first time this was not a problem
because the bevel amount starts at 0 then, and after the mouse moves the pixel
size is initialized. For the second time the bevel amount starts at a non-zero
value, and it failed then.
2017-12-30 15:32:13 +01:00
bb89759624 Fix T53360: crash with GLSL bump mapping and missing group output node. 2017-12-30 15:32:06 +01:00
825aecaee3 Fix T53273: render bake settings properties not showing correct Python path. 2017-12-30 15:32:00 +01:00
1dbdcfe9a9 Fix incorrect color management when saving JPG previews for EXR. 2017-12-30 15:31:53 +01:00
a6e5558194 Fix T53129: Cycles missing update when changing image auto refresh.
Previously auto refresh worked, but only if it was already enabled before
starting the viewport render.
2017-12-30 15:31:46 +01:00
6bd1189e5c Fix compositor node links getting lost on file load for custom render passes. 2017-12-30 15:31:13 +01:00
625b2f5dab Fix T52514: don't clear filename when dropping directory path in file browser. 2017-12-30 15:31:06 +01:00
20c96cce86 Fix T52998: disabled menu entries responding to key shortcuts. 2017-12-30 15:30:57 +01:00
c85a305c09 Fix T52800: fix UI flickering with Mesa on Linux.
Use triple buffer by default now on all platforms, remaing ones where:
* Mesa: seems to have been working well for a long time now, and not using
  it gives issues with the latest Mesa 17.2.0.
* Windows software OpenGL: no longer supported since OpenGL 2.1 requirement
  was introduced.
* OS X with thousands of colors: this option was removed in OS X 10.6, and
  that's our minimum requirement.
2017-12-30 15:30:43 +01:00
30f53d56b6 Fix potential string buffer overruns.
Note that our library path handling is still rather dodgy on this
regards, shall take some time at some point to seriously sanitize it...
2017-12-30 15:25:04 +01:00
47a388b2a9 Fix T53002: Batch-Generate Previews generate empty or none image for large objects.
Camera clipping was left to default values, which won't work well for
very large (or small) objects. Now recompute valid clipping start/end
based on boundingbox of rendered data, and final location of camera.
2017-12-30 15:24:54 +01:00
9f6d5d679e Fix missing ID remapping in Action editor callback.
Spotted by Joshua Leung (@aligorith), thanks!

Should probably be backported to 2.79a should we do it.
2017-12-30 15:24:45 +01:00
a4116673c7 Fix T52816: regression can't open file in 2.79 (crash).
Tentative fix, since I cannot reproduce thenissue for some reason here
on linux.

Core of the problem is pretty clear though, thanks to Germano Cavalcante
(@mano-wii): another thread could try to use looptris data after worker
one had allocated it, but before it had actually computed looptris.

So now, we use a temp 'wip' pointer to store looptris being computed
(since this is protected by a mutex, other threads will have to wait on
it, no possibility for them to double-compute the looptris here).

This should probably be backported to 2.79a if done.
2017-12-30 15:05:28 +01:00
7e4be7d348 Add some security checks against future bad float UIprecision values.
This commit and previous one should be backported to 2.79a should we
release it.
2017-12-30 15:05:20 +01:00
8e43a9e9cc Fix (irc-reported by @sergey) invalid precision value in a float RNA property.
Maximum allowed UI float precision value is 6 (which means 7 digits).

Will change code checking on that in next commit.
2017-12-30 15:05:10 +01:00
5384b2a6e2 Fix T52729: Decimals not showing over 100m or 100 feet
Use same 5 digits precision as we already use for e.g. Object's
location, for Object's dimensions too.

To be backported to 2.79a, should we do it.
2017-12-30 15:04:56 +01:00
e8e40b171b Fix failure in our UI code that could allow search button without search callbacks, leading to crash.
Related to (exposed by) T52735, fixes the reported crash but not the
underlying issue.

To be backported to 2.79a should we do one.
2017-12-30 15:04:44 +01:00
882fe36f0d Fix T52984. Trackpad rotation to natural direction 2017-12-30 15:04:26 +01:00
ce058207fc acceleration maps are kinda hard to get right... another attempt 2017-12-30 11:37:31 +01:00
1dbaf88150 fix, possibly return an empty mesh and default psys index is 1 now 2017-12-30 02:14:52 +01:00
1151442204 fix for randomized particle sizes
was accessing wrong indexes after particles died
2017-12-30 01:28:43 +01:00
d165b13ee4 added override with particle size option to mball remesher 2017-12-29 21:54:02 +01:00
4945003ffd remesh modifier can now remesh particle systems as well 2017-12-29 20:38:53 +01:00
23a9504df1 small fixes for acceleration map 2017-12-29 02:07:29 +01:00
026b847bd9 refactored acceleration map, but might still have issues
also attempted to improve triggering (make exacter, but slow and error prone)
2017-12-29 01:46:36 +01:00
e8c6f05eba fix attempt for acceleration map... still issues 2017-12-28 00:17:45 +01:00
656ab1cf6a reworked the bake correction method, some smaller fixes
shuffling happens now across all individual rigidbodies
2017-12-27 19:47:47 +01:00
1da64c2540 fixes for acceleration map 2017-12-26 23:07:21 +01:00
24f93213f2 invalidate rigidbody cache/bake if rigidbody objects are duplicated or deleted as well 2017-12-26 21:15:01 +01:00
c77878abab added final solid mesh source for mesh, some sphere margin fixes 2017-12-26 17:40:40 +01:00
16f161e5f6 added acceleration maps which should be also be usable in playback 2017-12-25 23:30:15 +01:00
9bf8ba16c2 added an acceleration map (vgroup), some remesher fixes 2017-12-25 16:45:27 +01:00
01a589c0af tweak of value display in FM UI 2017-12-25 14:13:16 +01:00
3d3ece2c67 fix for collision condition, it failed for regular case 2017-12-25 14:12:45 +01:00
df7d0e5423 extended the remesh modifier by a metaball mode 2017-12-25 01:12:23 +01:00
dbd1212dfb rearranged some FM Properties in UI 2017-12-24 20:50:31 +01:00
a96832cd21 fixes for cluster constraint island detection and a couple of minor fixes in fracture RNA 2017-12-24 20:49:25 +01:00
7babce3052 added "self collision" option for constraint islands, and randomize option for sphere shape radius and margin 2017-12-24 16:05:08 +01:00
95ae90cab0 sphere shape now takes its margin into account too, allow also negative margin now (optionally) 2017-12-23 15:15:45 +01:00
93bf8fc8e1 now fixing shard order problems directly after loading and jumping to another frame as well 2017-12-23 01:25:00 +01:00
1010cdf421 added option to only output verts, meta threshold max is 100 now 2017-12-21 17:12:17 +01:00
fc58dbc186 do not invalidate cache when enabling / disabling centroid output 2017-12-21 15:14:44 +01:00
e8958954ba added option to only output centroids as vertices
might be useful in conjunction with duplicated metaballs to have simple fluid-like behavior
2017-12-21 12:59:03 +01:00
fa7a666e2b added grid fracture option, removed rigidbody shape drawing with fm, alembic importer fix 2017-12-19 23:09:01 +01:00
4bc10e6a81 allow rigidbody being a forcefield effector too
this was disabled intentionally for some unknown reason
2017-12-16 16:09:37 +01:00
aacada54f8 fix, threshold and cluster threshold application was swapped 2017-12-15 22:23:38 +01:00
d99e1dc283 exposed meshisland constraints and modifier vertex groups to python
this was done to enable a new feature in the addon, the cluster editor.
2017-12-15 16:34:48 +01:00
c5e7265b1e fix for infinite recursion with cluster percentage activation
also remove kinematic state of stopped shards (if object is triggered and not kinematic) at start frame now
2017-11-16 20:28:39 +01:00
57d70b3c87 fix for autogenerating inner material, just append at the end of the stack instead taking always the 2nd one 2017-10-08 21:42:48 +02:00
d13f6ae2bf fix: separated comparison angle/distance for break/deform, propagate weakened threshold now 2017-10-07 19:59:44 +02:00
855d2955c4 Docs: update API changelog to 2.79 2017-10-03 19:58:21 +02:00
28f2865cfa added some previously missing tooltips 2017-09-26 14:01:20 +02:00
993c98779c increased UI digits precision to 5 for almost all FM float RNA properties
exception are properties which had higher precision even
2017-09-17 17:39:30 +02:00
3955fb3dcc compile fixes after merge 2017-09-12 13:26:30 +02:00
8c97b99daf Merge remote-tracking branch 'refs/remotes/origin/blender-v2.79-release' into fracture_modifier
Conflicts:
	source/blender/blenkernel/intern/rigidbody.c
2017-09-12 13:25:40 +02:00
fa859b0d72 only break constraints with threshold >= 0 2017-09-12 12:36:00 +02:00
8ef39d5c88 Update submodules to 2.79 release commits.
Should have been done before ahoy, sorry about that. Means 2.79 tag will
be one (no functionnal changes) commit ahead from our 2.79 builds, think
we can live with that.
2017-09-12 10:47:15 +02:00
5bd8ac9abf Update release cycle to 'release'. 2017-09-11 12:43:47 +02:00
9a9e9b1c4d Fix T52696: Sculpt - Brush spacing pressure artifacts
Was caused by divide-by-zero in paint_stroke_integrate_overlap()
in paint_stroke.c, as identified by Bob Smith (uvwxyz).

Thanks for the report!
2017-09-11 09:37:00 +02:00
904831e62e Fix T52701: Mesh shortest path fails at boundaries 2017-09-11 09:36:25 +02:00
1a7dda046b PyAPI: Fix mathutils freeze allowing owned data 2017-09-10 20:18:42 +02:00
82466852fe Fix T52531: Blender 2D stabilisation node issue when autoscale is selected
Threading conflict, should be safe for 2.79.
2017-09-10 20:18:04 +02:00
fbb4be061c Cycles: Safer fix for infinite recursion
Previous fix wasn't working correct for certain compiler and CPU intrinsics
mode, causing quite some crashes.

This should be a safer fix, which is closer in behavior to previous release
but which should still fix issues with robust curve intersection.
2017-09-08 14:47:32 +02:00
87cc8550e2 Fix T52650:Grease pencil selection its not automatically updating in Clip Editor 2017-09-08 12:33:00 +02:00
ccf1bb11b6 Math Lib: normalized vector project functions 2017-09-08 12:00:52 +02:00
9ae35fafb6 Fix T52149: LoopTriArray computation was not correctly protected against concurrency.
Note: this commit seems to work as expected (also with transform
snapping etc.). However, it is rather unsafe - not enough for 2.79 at
least, unless we get much more testing on it. It also depends on three
previous ones.

Note that using a global lock here is far from ideal, we should rather
have a lock per DM, but that will do for now, whole DM thing is doomed
to oblivion anyway in 2.8.

Also, we may need a `DM_DIRTY_LOOPTRIS` dirty flag at some point. Looks
like we can survive without it for now though... Probably because cached
looptris are never copied accross DM's?
2017-09-08 11:53:05 +02:00
7c3b435c3a Cleanup: remove useless DM_ensure_looptri().
That one was doing exactly same thing as `dm->getLoopTriArray()`, no
point in having twice the same code here...
2017-09-08 11:52:59 +02:00
9cc7e32f39 Fix transform snap code using 'allocated' flags to get verts/edges/etc. arrays again from DM.
This was... horribly wrong, CDDM will often *not* need to allocate
anything to return arrays of mesh items! Just check whether array
pointer is NULL.

Also, remove `DM_get_looptri_array`, that one is useless currently,
`dm->getLoopTriArray` will always return cached array (computing it if
needed).
2017-09-08 11:52:50 +02:00
9f0acc2c9e Cleanup: deduplicate DM's getLoopTriArray() callback.
All three functions were doing exactly the same thing, simpler to only
have one in that case!
2017-09-08 11:52:45 +02:00
300abf241e Fix T52639: Weight paint smooth tool crash 2017-09-08 11:52:30 +02:00
9da098536d UI: fix memory leak when copy-to-selected failed 2017-09-08 11:52:24 +02:00
3aaf908719 Fix T52678: Crash editing gpencil w/ frame-lock 2017-09-08 11:52:17 +02:00
a67aae98fe Screw Modifier: remove doubles option
Vertices on the axis can be optionally merged,
nice for creating objects which close at the end-points.
2017-09-08 11:52:10 +02:00
163a196f29 View3D Remap: skip defmaterial
This isn't library data.
2017-09-08 11:52:00 +02:00
b895c7337e Fix T52663: Remap used invalid local-view data
Only the camera from View3D.localvd is used,
other pointers may be invalid.

Longer term we should probably clear these to ensure no accidents.
For now just follow the rest of Blender's code and don't access.
2017-09-08 11:51:52 +02:00
a8bd08ffdd Fix T52522: VSE renders with alpha transparent PNG image incorrectly
Need some extra checks and should be probably end up in 2.79 since that's a regression.
2017-09-08 11:51:19 +02:00
e91f9f664d Rigidbody: Fix regression introduced in ee3fadd
Baking rigid body cache was broken if some cached frames already
existed.

This is just a band aid for release, the logic need to be looked into
further.
2017-09-06 09:32:46 +02:00
d84f559555 Fix T52374: Changes of rigid body related settings during simulation will break the simulation
Revert 9cd6b03, 3edc8c1, b87d10d and do a better fix for T50230.
2017-09-06 09:32:38 +02:00
ec50734106 Buildbot: Fix paths to sndfile and flac
Need this in 2.79 branch as well, since build rules are based on this files.
2017-09-06 09:32:14 +02:00
a8c7f1329b Fix T52251: Knife cur displaces surface 2017-09-06 09:31:44 +02:00
9b7d506779 T52534: Compositor artifacts when scaling
Increased the maxx and maxy area of interest when scaling in this case.
2017-09-04 15:45:27 +02:00
2deeec9e28 This copyright text (copied to binary distros) had a confusing statement about
scripts being "Artwork" which is your sole property and free to license.

I've removed the reference to scripts in this text.

This was from 2002! With our Python scripts becoming part of how Blender runs,
such scripts now are officially required to be compliant with GNU GPL.

For more information; check the FAQ or consult foundation@blender.org
https://www.blender.org/support/faq/
2017-09-04 15:43:20 +02:00
Dalai Felinto
9ca3d4cbbd Cycles Bake: Fix overflow when using hundreds of images
We have a hardcored limit of 1000 images to be baked.
However anything anove 100 would be leading to overflow in the code.

Caught by warning from builder bot (my compiler doesn't even complain
about this, but it should).
2017-09-04 15:43:12 +02:00
0bee126977 Fix T52209: New Depsgraph - animated follow curve constraint sometimes freaks out when the curve has a parent 2017-09-04 14:12:42 +02:00
c9d653e560 Fix T52533: Blender shuts down when rendering duplicated smoke domain 2017-09-04 14:06:08 +02:00
1ae3056261 Cycles: Fix compilation warning 2017-09-04 14:06:02 +02:00
5f17d47629 Cycles: Correct logging of sued CPU intrisics 2017-09-04 14:04:35 +02:00
edded659c6 Fix T51907: New Depsgraph - Camera constraint is not evaluated properly
This is more a workaround for until we've got proper visibility flush, which
will likely happen in blender2.8 branch.
2017-09-04 14:04:28 +02:00
95d871c1a2 Cycles: FIx issue with -0 being considered a non-finite value 2017-09-04 14:04:22 +02:00
4b90830cac Alembic: Fix T52579: crash when replacing slightly different alembic files
Apparently with Maya in a certain configuration, it's possible to have an
Alembic object without schema in the Alembic file. This is now handled
properly, instead of crashing on a null pointer.
2017-09-04 14:04:13 +02:00
a1e8ef264f Fix: Deleting GPencil keyframes in DopeSheet didn't redraw the view 2017-09-04 13:03:09 +02:00
f5d02f055f Fix: Border select for GPencil keyframes was including those in the "datablock" channels even though those weren't visible
This meant that it was easy to accidentally select too many keyframes
2017-09-04 13:03:01 +02:00
ed0429e7e6 Fix: GPencil Sequence Interpolation for thickness/strength was inverted
For example, if you have two keyframes:
  k1 = 1px, k2 = 10px

it was doing:
  1px, 9px, 8px, ..., 3px, 2px, 10px
instead of:
  1px, 2px, 3px, ..., 8px, 9px, 10px
2017-09-04 13:02:53 +02:00
27c42e05c4 Fix T52483: Fill is incorrect for interpolated strokes
The recalc flag must be enabled for new interpolated strokes.
2017-09-04 13:02:41 +02:00
374ddd022c BMesh: use predictable order for remove-doubles
Each qsort implementation may give different results when values match.

Now fallback to sorting by index.
2017-09-04 12:59:40 +02:00
8a254b6271 Docs: BMesh.from_mesh behavior w/ multiple calls 2017-09-04 12:59:33 +02:00
8193e50fd3 Fix T51400: Pasting hex code fails
The # prefix is supported,
the button didn't give enough space to paste it.

D2812 by @candreacchio
2017-09-04 12:59:27 +02:00
8c4b4fdd14 Missed last commit 2017-09-04 12:59:20 +02:00
5fd4eca8c0 Fix T52515: Crash on BMesh.to_mesh() 2017-09-04 12:59:13 +02:00
6fec06926e Fix minor Mesh -> BMesh conversion issues
- Vertex only meshes never restored their selection history.
- Select history was cleared on the source instead of the target.

Simple Optimizations:
- Avoid O(n^2) linked list looping that checked the entire list before
  adding elements (NULL values in the source array to prevent dupes).
- Re-use vert & edge lookup tables instead of allocating new ones.
2017-09-04 12:59:06 +02:00
bb92bb5329 Docs: rename var and comment how it's used
switch_from_camera wasn't right since it was used for auto-perspective.
2017-09-04 12:59:00 +02:00
7997646c2d Correction to last fix 2017-09-04 12:58:54 +02:00
0ed5605bd5 Fix T52490: NDOF orbit doesn't lock in ortho view
Regression in af3f7db caused by own fix for T51324
2017-09-04 12:58:47 +02:00
76e8dcafa3 Fix T52396: Crash loading template w/o config dir 2017-09-04 12:58:41 +02:00
73cdf00ea8 Fix T52227: Time Slide tool doesn't take NLA mapping into account
To be backported to 2.79
2017-09-04 12:57:16 +02:00
Dalai Felinto
ecdb16d1d8 Increase max/min frame range to over a million
For some specific pipelines (e.g., holographic rendering) you can easily
need over a million frames (1k * 1k view angles).

It seems a corner case, but there is no real reason not to allow users
doing that.

That said we do loose subframe precision in the highest frame range. Which can
affect motionblur. The current maximum sub-frame precision we have is 16.
While the previous limit of 500k frames has a precision of 32.

Thanks to Campbell Barton for the help here.

To be backported to 2.79
2017-09-04 12:57:10 +02:00
022b9676b0 Fix T52472: VSE Audio Volume not set immediately
Audio mixing is done with volume interpolation. A new handle started at
volume 1, now starting at volume 0 for a smooth fade in.
2017-09-04 12:57:03 +02:00
e9ca9dd5d7 Fix T52588: Shape key value driver variables of duplicated object sets refer to old objects.
Regression since 2.78, to be backported to 2.79.
2017-09-04 12:56:57 +02:00
82a6889d83 Fix T52498: Deleting force field doesn't remove "Surface" from modifier stack.
Logic in `ED_object_check_force_modifiers` was inconsistent between add
and remove modifier cases.

Should be safe enough for 2.79.
2017-09-04 12:56:50 +02:00
a5213924a8 Fix T52478: Error report "Shrinkwrap: out of memory" on invisible target.
Shrinkwrap must check it does have valid target data.

Safe for 2.79 release.
2017-09-04 12:56:43 +02:00
42760d922e Fix T52538: Outliner crash when displaying groups and using Show Active on editmode bone not in any groups
There's no guaranty that given ID is found in current outliner tree...

Safe for 2.79, though not a regression.
2017-09-04 12:56:36 +02:00
6f4a0c23cc Cycles: Mark pixels with negative values as outliers
If a pixel has negative components, something already went wrong, so the best option is to just ignore it.

Should be good for 2.79.
2017-09-04 12:56:29 +02:00
fc26280bcb Fix T52481: After making all local, local proxies of linked data get broken after file save and reload.
Issue was nasty hidden one, the dual status (mix of local and linked)
of proxies striking again.

Here, remapping process was considering obdata pointer of proxies as
indirect usage, hence clearing the 'LIB_TAG_EXTERN' of obdata pointer.
That would make savetoblend code not store any 'lib placeholder' for
obdata data-block, which was hence lost on next file read.

Another (probably better) solution here would be to actually consider
obdata of proxies are fully indirect usage, and simply reassign proxies
from their linked object's obdata on file read...

However, that change shall be safer for now, probably good for 2.79 too.
2017-09-04 12:56:22 +02:00
75e392ae9f Cycles: Fix stack overflow during traversal caused by floating overflow
Would be nice to be able to catch this with assert as well, will see what would
be the best way to do this/.\

Need to verify with Mai that this solves crash for her and maybe consider
porting this to 2.79.
2017-09-04 12:56:15 +02:00
6825439b36 Fix T51805: Overlapping volumes renders incorrect on AMD GPU
We need to make sure we can store all volume closures for all objects in volume
stack. This is a bit tricky to detect what would be the "nestness" level of
volumes so for now use maximum possible stack depth. Might cause some slowdown,
but better to give reliable render output than to fail quickly.

Should be safe for 2.79 after extra eyes.
2017-09-04 12:56:08 +02:00
f2aa9bec9d Fix T52218: Missing update when reconnecting node
If node was connected to output, we tag tree for update no matter where
the node was re-plugged to.

Should be safe for 2.79.
2017-09-04 12:56:01 +02:00
8cb217069e Fix T52466: Silence search for button_context menu type.
We were showing "search for unknown menutype WM_MT_button_context" messages in terminal which were not helpful for users, so now they are disabled.

To be backported to 2.79
2017-09-04 12:55:54 +02:00
9997f5ca91 Fix threading conflict when doing Cycles background render
It is possible to have same image used multiple times at different frames,
which means we can not free it's buffers without any guard. From quick tests
this seems to be doing what it is supposed to.

Need more testing and port this to 2.79.
2017-09-04 12:55:47 +02:00
63e21e7218 Fix T52454: Crash in DEG_graph_on_visible_update when activating scene layer
Most likely needs in 2.79 final release.
2017-09-04 12:55:40 +02:00
dd84324485 Fix T52473: blender internal Fresnel and Layer Weight only work with linked normal.
Please backport this to 2.79.
2017-09-04 12:55:30 +02:00
d2f20aed04 Fix T52439: Crash after adjusting lenght of hair particles.
Regression from rBfed853ea78221, calling this inside thread worker was
not really good idea anyway, and we already have all the code we need in
pre-threading init function, was just disabled for vertex particles
before.

To be backported to 2.79.
2017-09-04 12:55:22 +02:00
c0a9fdd93f Cleanup: remove space from filenames 2017-09-04 12:53:48 +02:00
e00f3a6565 Tests: fix incorrect check for hidden dir
Copy-pasted mistake in tests and tools.
2017-09-04 12:53:39 +02:00
6692af3997 Fix error in PointerProperty argument list
Regression in a7b3047
2017-09-04 12:53:28 +02:00
058a358e98 Modify menu from last commit
Also correct tool-tip.
2017-09-04 12:48:17 +02:00
ba600ff7fa Fix T52434: Restore mesh center of mass calculation
The new method while improved for solid objects
doesn't work for non-manifold meshes, keep both.
2017-09-04 12:48:04 +02:00
fd0fbf2564 Fix bpy library load: invalid function signature 2017-09-04 12:47:55 +02:00
beea9421bd PyAPI: avoid redundant PyLong_AsLong call
Assigning to an RNA array converted from Python to C twice.
2017-09-04 12:47:41 +02:00
c79f216066 fix for angle calculation due to usage of initially rotated rigidbodies in external mode 2017-08-28 16:27:48 +02:00
be7ef0060f fix for initial rotation in convert to object and convert to keyframes 2017-08-24 11:39:09 +02:00
e6341b5107 fix for rotated box shapes in external mode + print -1 for unbreakable threshold in phys viz 2017-08-24 10:30:28 +02:00
b25b4c550e use areabased centroid calculation again for shards + small fix in loading routine
new volumebased method gave incorrect results with nonmanifolds
2017-08-22 14:48:24 +02:00
d273e2002c added an automerge distortion cache 2017-08-22 12:37:53 +02:00
612030983d Merge remote-tracking branch 'refs/remotes/origin/blender-v2.79-release' into fracture_modifier 2017-08-21 15:21:13 +02:00
d7b094a807 fix attempt for "merge cache" 2017-08-18 18:45:25 +02:00
7b397cdfc8 Fix T52401: "Export Keying Set" operator generated incorrect ID's for shapekeys
To be backported.
2017-08-18 14:53:52 +02:00
d48f4b61c9 Blender 2.79: Point subodules to updated hash 2017-08-18 14:12:04 +02:00
9bc5549222 PyAPI: Fix memory leak w/ empty, allocated enums 2017-08-18 14:04:07 +02:00
48da381e37 another fix attempt to get the masses right 2017-08-17 22:50:13 +02:00
afa33574de fixes for centroid and volume calculation for non-manifolds, fix attempt for storage of merge info 2017-08-17 17:34:37 +02:00
6bc962d7bc Fix T46329: scene_update_{pre,post} doc needs clarification
The documentation for the bpy.app.handlers.scene_update_{pre,post}
handlers states that they're called "on updating the scenes data".
However, they're called even when the data hasn't changed. Of course
such handlers are useful, but the documentation should reflect the
current behaviour.

Reviewers: mont29, sergey

Subscribers: Blendify

Maniphest Tasks: T46329

Differential Revision: https://developer.blender.org/D1535
2017-08-17 16:30:01 +02:00
e6830167e2 Fixed Alembic unit test
Commit b6d7cdd3ce changed how the mesh data
is deformed, which wasn't taken into account yet in this unit test.

Instead of directly reading the mesh vertices (which aren't animated any
more), we convert the modified mesh to a new one, and inspect those
vertices instead.
2017-08-17 15:41:27 +02:00
f21020f45f Fix T52240: Alembic Not Transferring Materials Per Frame
When a mesh changes its number of vertices during the animation,
Blender rebuilds the DerivedMesh, after which the materials weren't
applied any more (causing the default to the first material slot).
2017-08-17 15:40:49 +02:00
455c016ba6 Alembic: Renamed variable assigned_name → assigned_mat
The variable is a pointer to a Material, not to a name/string.
2017-08-17 15:40:44 +02:00
6e7d962118 Fix OSX duplicate path in Python's sys.path
The '..' in the path caused simple comparisons to fail.

D2780 by @akitula
2017-08-17 14:29:19 +02:00
210f839e93 Blender 2.79: We are entering RC2 stage 2017-08-17 14:20:30 +02:00
b1d998ec5d Fix T52255: New Depsgraph - Constraint and Drivers not working together when the driver references itself 2017-08-17 14:13:01 +02:00
78c288d377 Alembic import: report object name in face color index out of bounds error 2017-08-17 14:07:20 +02:00
2307ea88b5 Alembic import: fix crash when face color index is out of bounds.
This can happen with Alembic files exported from Maya. I'm unsure as to the
root cause, but at least this fixes the crash itself.

Thanks to @looch for reporting this with a test file. The test file has to
remain confidential, though, so it's on my workstation only.
2017-08-17 14:07:20 +02:00
8138082ab8 Fix T51701: Alembic cache screws up mesh.
Use same trick as in DataTransfer modifier e.g. to avoid modifying
existing mesh's data.
2017-08-17 14:07:20 +02:00
265d620179 Forgot to change magicnumber of OIIO built lib in previous commit... 2017-08-17 14:07:20 +02:00
2ff041b7a5 install_deps: disable PTex in our OIIO building for now, broken on newest systems. 2017-08-17 14:07:20 +02:00
edd0dbd23b Fix compilation error when building without Blender
Simply disabled python tests, they can't be run anyway (since blender target is
not enabled) and we don't have any player-related tests in that folder.
2017-08-17 14:07:20 +02:00
8604557b75 CMake: test build configuration support
D2765 by @akitula
2017-08-17 14:07:20 +02:00
a52ec5308f Fix T52278: 'Default' application template fails
Own error in 7398b3b7
2017-08-17 14:07:20 +02:00
0cb38b2875 Fix T52329: Boolean with aligned shapes failed
Creating ngons with multiple axis aligned shapes in the middle of a
single face would fail in some cases.

This exposed multiple problems in BM_face_split_edgenet_connect_islands

- Islands needed to be sorted on Y axis when X was aligned.
- Checking edge intersections needed increased endpoint bias.
- BVH epsilon needed to be increased.
2017-08-17 14:07:19 +02:00
6f935dbb38 Math Lib: add isect_seg_seg_v2_point_ex
This exposes end-point bias argument, needed in rare cases.
2017-08-17 14:07:19 +02:00
Stefan Werner
10764d31d4 Cycles: Fixed broken camera motion blur when motion was not set to center on frame
Reviewers: #cycles, sergey

Reviewed By: #cycles, sergey

Subscribers: sergey

Differential Revision: https://developer.blender.org/D2787
2017-08-17 14:07:19 +02:00
69c389fd63 Cycles: Guard memcpy to potentially re-allocating memory with lock
Basically, make re-alloc and memcpy from the same lock, otherwise one
thread might be re-allocating thread while another one is trying to
copy data there.

Reported by Mohamed Sakr in IRC, thanks!
2017-08-17 14:07:19 +02:00
686b8e8fed Fix width estimation for buttons with short labels in pie menus
Differential Revision: https://developer.blender.org/D2781

To be backported to 2.79 branch
2017-08-17 14:07:19 +02:00
0aae208749 iFix T52050: Empty VSE preview for scene strips with OpenGL preview + Rendered settings.
'OpenGL Preview' checkbox was redundant now, just use seq_prev_type
value only.

Might be OK for 2.79, but should be double-checked first...
2017-08-17 14:07:19 +02:00
3689be736b Fix T52327: Entering/Exiting NLA Tweakmode disables Scene -> Only Keyframes from Selected Channels
The tweakmode flag and the selected-channels flag accidentally
used the same value, due to confusion over where these flags were
supposed to be set. The selected-channels flag has now been moved
to use a different value, so that there shouldn't be any further
conflicts.

To be ported to 2.79.
2017-08-17 14:07:19 +02:00
9a239eea68 Fix T52344: Softbody on Text.
Own previous fix (rBd5d626df236b) was not valid, curves are actually
supported by SoftBodies. It was rather a mere UI bug, which was not
including Surfaces and Font obect types in those valid for softbody UI.

Thanks to @brecht for the head up!

Also, fix safe for 2.79, btw.
2017-08-17 14:07:19 +02:00
28451a9cec Pie menu's sub-rows ignore 'EXPAND' flag
Regression, to be backported in 2.79.
2017-08-17 14:07:19 +02:00
efa840f99f Fix T52344: Softbody on Text.
For some reasons (c) softbody modifier was marked as compatible with
curves... Would need much more work though, so for now just removing
that flag!
2017-08-17 14:07:18 +02:00
518d690628 DPI: add back option to control line width, tweak default width.
Adds thin/default/thick modes to add -1/0/1 to the auto detected line width,
while leaving the overall UI scale unchanged.

Also tweaks the default line width threshold, so thicker lines start from
slightly high UI scales.

Differential Revision: https://developer.blender.org/D2778
2017-08-17 14:07:18 +02:00
35f5d80f3a Fix T52334: images with non-color data should not change color space on save. 2017-08-17 14:07:18 +02:00
0d86bc9f98 Tweak and extend POV syntax hilghting.
*Changed categories of some keywords
*reordered some longer keywords that didn't appear
*Activated another color (reserved builtins) by Leonid
*added some HGPOV and UberPOV missing keywords

Patch by Maurice Raybaud (@mauriceraybaud). Thanks to Leonid for additions, feedback and Linux testing.
Related diffs: D2754 and D2755.

While not a regression, this is new feature and would be nice to have it
backported to final 2.79.
2017-08-17 14:07:18 +02:00
ff47118c73 Fix T52324: Metaball disappears when deleting first metaball object.
Lost specific MBall 'need update' case here in last year's refactor.

While technically not a regression, nice to have in 2.79.
2017-08-17 14:07:18 +02:00
0146ab2fd5 Fix T52315: Crash on duplicating Scene without world.
Regression from rBa7b3047cefcbf, to be backported to 2.79.

Like... seriously... :|
2017-08-17 14:07:18 +02:00
e54df78c82 Fix T52280: The Image node in Compositing can't read Z buffer of openEXR in 2.79
As part of the fix for T51587, I removed the Depth output for non-Multilayer
images since it seemed weird that PNGs etc. that don't have a Z pass still get
a socket for it.
However, I forgot about non-multilayer EXRs, which are a special case that can
actually have a Z pass.

Therefore, this commit brings back the Depth output for non-multilayer images
just like it was in 2.78.
2017-08-17 14:07:17 +02:00
909320e3ff Fix fixed width box layouts
Regression, to be backported in 2.79.
2017-08-17 14:07:17 +02:00
fa34f864a2 Fix T52260: Blender 2.79 Objects made duplicates real still refer armature proxy.
New code was handling correctly ID's internal references to self, but
not references between 'made real' different objects...

Regression, to be backported in 2.79.
2017-08-17 14:07:17 +02:00
205202361c Fix width estimation for empty layouts in pie menus 2017-08-17 14:07:17 +02:00
fb73cee1ec Fix T52263: Crash When Splitting and Merging Areas with Header Text Set.
Not a regression, but safe enough to be included in 2.79.
2017-08-17 14:07:17 +02:00
8ae6e35923 Fix broken API doc generation: Partially revert rBa372638a76e0
Making those arrays static remove them from exported symbols, which
breaks API doc generation script.

To be backported to 2.79 branch.
2017-08-17 14:07:17 +02:00
ade9fc9245 Fix T52250: Glitch in UI in the addon panel regression 2017-08-17 14:07:17 +02:00
78b3061c32 fix attempt for avoiding incorrect inner collisions between constrained objects 2017-08-16 01:20:11 +02:00
f233ecd511 use exact volume calculation for convexhull and mesh when calculating masses of initial objects only 2017-08-15 03:26:44 +02:00
63ad55f295 fixes for FM mesh island rigidbody path problem and volume calculation
scaling was ignored and only half of the dimensions for the volume were used, thus the calculated mass was 1/8th of the
correct mass.
2017-08-15 02:52:59 +02:00
e3e6270241 fix, forgot to set angular spring stiffness and damping when converting to objects 2017-08-14 15:47:29 +02:00
155f2a4a52 fix for break of rigidbody behavior after 2.78c and stoptriggers are speed-dependent now 2017-08-13 13:20:08 +02:00
8af66d6088 versioning fixes for angular spring stiffness / damping and exposed those to FM python api 2017-08-13 01:39:10 +02:00
f68da08a05 fix for initial kinematic state after triggering and jumping back to startframe 2017-08-13 01:00:45 +02:00
97dd7b540f compile fixes after merge 2017-08-12 22:48:47 +02:00
86da0f4749 Merge remote-tracking branch 'refs/remotes/origin/blender-v2.79-release' into fracture_modifier
Conflicts:
	build_files/buildbot/slave_compile.py
	build_files/cmake/buildinfo.cmake
	build_files/cmake/config/blender_release.cmake
	build_files/cmake/macros.cmake
	build_files/cmake/packaging.cmake
	build_files/cmake/platform/platform_win32_msvc.cmake
	doc/python_api/sphinx_doc_gen.py
	doc/python_api/sphinx_doc_update.py
	intern/atomic/atomic_ops.h
	intern/atomic/intern/atomic_ops_ext.h
	intern/atomic/intern/atomic_ops_unix.h
	intern/cycles/CMakeLists.txt
	intern/cycles/blender/addon/properties.py
	intern/cycles/blender/addon/ui.py
	intern/cycles/blender/blender_mesh.cpp
	intern/cycles/blender/blender_object.cpp
	intern/cycles/blender/blender_object_cull.cpp
	intern/cycles/blender/blender_object_cull.h
	intern/cycles/blender/blender_python.cpp
	intern/cycles/blender/blender_session.cpp
	intern/cycles/blender/blender_session.h
	intern/cycles/blender/blender_shader.cpp
	intern/cycles/blender/blender_util.h
	intern/cycles/bvh/bvh.cpp
	intern/cycles/bvh/bvh.h
	intern/cycles/bvh/bvh_build.cpp
	intern/cycles/bvh/bvh_node.h
	intern/cycles/device/device.cpp
	intern/cycles/device/device.h
	intern/cycles/device/device_cpu.cpp
	intern/cycles/device/device_cuda.cpp
	intern/cycles/device/device_opencl.cpp
	intern/cycles/device/device_task.cpp
	intern/cycles/device/opencl/opencl.h
	intern/cycles/device/opencl/opencl_base.cpp
	intern/cycles/device/opencl/opencl_mega.cpp
	intern/cycles/device/opencl/opencl_split.cpp
	intern/cycles/device/opencl/opencl_util.cpp
	intern/cycles/kernel/bvh/bvh.h
	intern/cycles/kernel/bvh/bvh_nodes.h
	intern/cycles/kernel/bvh/bvh_shadow_all.h
	intern/cycles/kernel/bvh/bvh_volume_all.h
	intern/cycles/kernel/bvh/qbvh_shadow_all.h
	intern/cycles/kernel/bvh/qbvh_subsurface.h
	intern/cycles/kernel/bvh/qbvh_traversal.h
	intern/cycles/kernel/bvh/qbvh_volume.h
	intern/cycles/kernel/bvh/qbvh_volume_all.h
	intern/cycles/kernel/closure/bsdf.h
	intern/cycles/kernel/closure/bsdf_microfacet.h
	intern/cycles/kernel/closure/bsdf_microfacet_multi.h
	intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h
	intern/cycles/kernel/geom/geom.h
	intern/cycles/kernel/geom/geom_curve.h
	intern/cycles/kernel/geom/geom_motion_curve.h
	intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
	intern/cycles/kernel/geom/geom_motion_triangle_shader.h
	intern/cycles/kernel/geom/geom_object.h
	intern/cycles/kernel/geom/geom_triangle.h
	intern/cycles/kernel/geom/geom_triangle_intersect.h
	intern/cycles/kernel/geom/geom_volume.h
	intern/cycles/kernel/kernel_accumulate.h
	intern/cycles/kernel/kernel_bake.h
	intern/cycles/kernel/kernel_compat_cpu.h
	intern/cycles/kernel/kernel_compat_cuda.h
	intern/cycles/kernel/kernel_emission.h
	intern/cycles/kernel/kernel_image_opencl.h
	intern/cycles/kernel/kernel_light.h
	intern/cycles/kernel/kernel_passes.h
	intern/cycles/kernel/kernel_path.h
	intern/cycles/kernel/kernel_path_branched.h
	intern/cycles/kernel/kernel_path_common.h
	intern/cycles/kernel/kernel_path_surface.h
	intern/cycles/kernel/kernel_path_volume.h
	intern/cycles/kernel/kernel_random.h
	intern/cycles/kernel/kernel_shader.h
	intern/cycles/kernel/kernel_shadow.h
	intern/cycles/kernel/kernel_subsurface.h
	intern/cycles/kernel/kernel_textures.h
	intern/cycles/kernel/kernel_types.h
	intern/cycles/kernel/kernel_volume.h
	intern/cycles/kernel/kernels/cpu/kernel_avx.cpp
	intern/cycles/kernel/kernels/cpu/kernel_avx2.cpp
	intern/cycles/kernel/kernels/opencl/kernel.cl
	intern/cycles/kernel/split/kernel_background_buffer_update.h
	intern/cycles/kernel/split/kernel_data_init.h
	intern/cycles/kernel/split/kernel_direct_lighting.h
	intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
	intern/cycles/kernel/split/kernel_next_iteration_setup.h
	intern/cycles/kernel/split/kernel_scene_intersect.h
	intern/cycles/kernel/split/kernel_split_common.h
	intern/cycles/kernel/svm/svm_displace.h
	intern/cycles/kernel/svm/svm_image.h
	intern/cycles/kernel/svm/svm_tex_coord.h
	intern/cycles/render/buffers.cpp
	intern/cycles/render/graph.cpp
	intern/cycles/render/graph.h
	intern/cycles/render/image.cpp
	intern/cycles/render/image.h
	intern/cycles/render/mesh_subdivision.cpp
	intern/cycles/render/osl.cpp
	intern/cycles/render/session.cpp
	intern/cycles/render/session.h
	intern/cycles/render/svm.cpp
	intern/cycles/render/svm.h
	intern/cycles/render/tile.cpp
	intern/cycles/render/tile.h
	intern/cycles/util/util_atomic.h
	intern/cycles/util/util_boundbox.h
	intern/cycles/util/util_half.h
	intern/cycles/util/util_image.h
	intern/cycles/util/util_image_impl.h
	intern/cycles/util/util_math.h
	intern/cycles/util/util_path.cpp
	intern/cycles/util/util_progress.h
	intern/cycles/util/util_simd.h
	intern/cycles/util/util_task.cpp
	intern/cycles/util/util_types.h
	intern/ghost/intern/GHOST_SystemCocoa.mm
	make.bat
	release/datafiles/locale
	release/scripts/addons
	release/scripts/presets/interface_theme/24x_blues.xml
	release/scripts/presets/interface_theme/flatty_light.xml
	release/scripts/startup/bl_operators/wm.py
	release/scripts/startup/bl_ui/space_userpref.py
	source/blender/blenkernel/BKE_library_query.h
	source/blender/blenkernel/BKE_sca.h
	source/blender/blenkernel/intern/DerivedMesh.c
	source/blender/blenkernel/intern/armature.c
	source/blender/blenkernel/intern/library.c
	source/blender/blenkernel/intern/library_query.c
	source/blender/blenkernel/intern/mesh.c
	source/blender/blenkernel/intern/rigidbody.c
	source/blender/blenkernel/intern/sca.c
	source/blender/blenkernel/intern/subsurf_ccg.c
	source/blender/blenlib/intern/task.c
	source/blender/blenloader/intern/readfile.c
	source/blender/blenloader/intern/versioning_270.c
	source/blender/blenloader/intern/writefile.c
	source/blender/collada/ArmatureImporter.cpp
	source/blender/depsgraph/DEG_depsgraph_build.h
	source/blender/depsgraph/intern/builder/deg_builder.cc
	source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
	source/blender/depsgraph/intern/builder/deg_builder_nodes.h
	source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
	source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
	source/blender/depsgraph/intern/builder/deg_builder_relations.h
	source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc
	source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
	source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
	source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
	source/blender/depsgraph/intern/depsgraph.h
	source/blender/depsgraph/intern/depsgraph_build.cc
	source/blender/depsgraph/intern/depsgraph_eval.cc
	source/blender/depsgraph/intern/eval/deg_eval.cc
	source/blender/depsgraph/intern/eval/deg_eval_debug.cc
	source/blender/depsgraph/intern/nodes/deg_node.cc
	source/blender/depsgraph/intern/nodes/deg_node.h
	source/blender/depsgraph/intern/nodes/deg_node_component.cc
	source/blender/depsgraph/intern/nodes/deg_node_component.h
	source/blender/depsgraph/intern/nodes/deg_node_operation.cc
	source/blender/depsgraph/util/deg_util_foreach.h
	source/blender/editors/animation/anim_channels_defines.c
	source/blender/editors/animation/anim_draw.c
	source/blender/editors/armature/pose_transform.c
	source/blender/editors/interface/interface_layout.c
	source/blender/editors/object/object_modifier.c
	source/blender/editors/space_outliner/outliner_edit.c
	source/blender/editors/transform/transform_snap_object.c
	source/blender/gpu/shaders/gpu_shader_material.glsl
	source/blender/makesdna/DNA_ID.h
	source/blender/makesdna/DNA_modifier_types.h
	source/blender/makesdna/DNA_rigidbody_types.h
	source/blender/makesdna/DNA_userdef_types.h
	source/blender/makesrna/intern/rna_ID.c
	source/blender/makesrna/intern/rna_main.c
	source/blender/makesrna/intern/rna_main_api.c
	source/blender/makesrna/intern/rna_mesh_api.c
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/makesrna/intern/rna_render.c
	source/blender/makesrna/intern/rna_rigidbody.c
	source/blender/makesrna/intern/rna_userdef.c
	source/blender/makesrna/intern/rna_wm_api.c
	source/blender/modifiers/MOD_modifiertypes.h
	source/blender/modifiers/intern/MOD_boolean.c
	source/blender/modifiers/intern/MOD_normal_edit.c
	source/blender/modifiers/intern/MOD_util.c
	source/blender/nodes/shader/nodes/node_shader_tex_brick.c
	source/blender/python/intern/bpy_rna_id_collection.c
	source/blender/render/extern/include/RE_pipeline.h
	source/blender/render/intern/source/render_result.c
	source/creator/CMakeLists.txt
	tests/gtests/CMakeLists.txt
	tests/gtests/blenlib/BLI_string_test.cc
	tests/python/CMakeLists.txt
2017-08-12 22:48:17 +02:00
5c9626721b reordered all FM related functions to the end of file 2017-08-12 16:28:18 +02:00
474ae3e5f9 renamed "Anti-Trigger" to "Stop Trigger" in python and UI now 2017-08-10 19:21:35 +02:00
3bdb65f5ed performance regression fix which reduces some static-static collision checking 2017-08-10 18:55:07 +02:00
39330a3e62 reworked the trigger system to work in narrowphase of bullet (more exact shapes) 2017-08-09 22:18:03 +02:00
0e7fb6d0bd support for "anti-triggers" which stop movement of active rigidbody shards 2017-08-09 15:30:00 +02:00
1d57779c20 using quaternions and correction of quaternion sign flips for convert to keyframes now 2017-08-08 01:26:25 +02:00
a4c953bf04 attempt to reduce memory usage with dynamic fracture
but somewhere a memory leak is still present there
2017-08-07 17:58:04 +02:00
be6e39da29 minor fix: forgot to update frame in display when converting to keyframes 2017-08-05 20:05:36 +02:00
91f02a80f5 fix for wrong centroid calculation when re-using existing mesh-islands
this affected the physics mesh and the convert to keyframes function, which created incorrect results.
2017-08-05 19:22:13 +02:00
5e9132b3b7 2.79 release: point submodules to correct branches and versions. 2017-08-01 19:31:37 +02:00
8e21378e05 take position for constraint between both rigidbodies for fixed constraints now, too 2017-06-21 14:48:34 +02:00
04896acd69 skip exceeded verts in average coord calculation in keep distort mode now too 2017-06-20 22:24:33 +02:00
5909d32aec allow a bit "cleaner" cut edges when keep distort is not set, else they keep jaggy 2017-06-20 16:59:01 +02:00
a8510408b9 added deform weakening factor
the threshold is multiplied with 1.0-fac per deform iteration, so it can automatically break at some point.
2017-06-18 19:25:57 +02:00
256aeb213a added additional distances and angles settings in order to control plastic deform better 2017-06-18 17:20:38 +02:00
e3cdc36429 refinement for plastic deformation 2017-06-18 13:41:38 +02:00
3294959446 attempt to have "plastic" constraint deform by re-constraining via angle, distance
deformation mode happens when breakable is set to false, but angle or distance is set
2017-06-18 11:08:21 +02:00
dfbcbaf7eb fix attempt for memory leak after loading FM blends in prefractured mode
note: works only with newly saved FM files, older still have unnecessary data in them which wont be automatically cleaned
2017-06-17 21:08:54 +02:00
00054e28a4 do not check constraint islands in case constraint collision is activated (allow self collision) 2017-06-16 23:00:05 +02:00
b025e3b36a check for availability of "constraint_type" in DNA struct, if not there set default value "fixed" 2017-06-16 22:00:37 +02:00
e1ea9a4afd added constraint type setting for FM constraints
previously there was only a cluster constraint setting
2017-06-16 18:43:15 +02:00
64ada2985f added Dissolve plastic constraints option, only relevant for external mode 2017-06-16 12:21:02 +02:00
c802ddb2a4 allow triggering in external mode too 2017-06-15 17:05:37 +02:00
8dc440e900 fix for distortion, should avoid snapping back of geometry 2017-06-14 22:51:13 +02:00
5caefc95a7 refactor of automerge shared vertex handling function 2017-06-14 20:55:26 +02:00
55aa21bb16 fix attempt for uncontrolled "snapping" when using keep distort 2017-06-14 19:33:30 +02:00
dce6a36932 crash fix for linking FM scene as background scene with automerge 2017-06-14 12:48:27 +02:00
afa2287ea3 fix, do not recalculate autohide when only changing automerge dist 2017-06-14 12:23:56 +02:00
d5213d70b7 performance improvement for packing many islands, avoided unnecessary listbase findlink 2017-06-14 00:02:15 +02:00
a99e840151 crash fix and minor tweaks for external mode (setting expected defaults) 2017-06-13 23:28:24 +02:00
4b560f14d7 further fixes for external mode 2017-06-13 22:37:36 +02:00
c3c488e475 fix for handling of uvs when packing objects into fracture modifier 2017-06-13 19:26:03 +02:00
2df9e4909c reset automerge (distortion, exceeded) in external mode now too on startframe 2017-06-12 12:16:55 +02:00
1941be005d more tweaks for automerge 2017-06-12 11:29:27 +02:00
2b63854ec1 allow autohide / automerge for external mode too, and some tweaks for shared vert group optimization 2017-06-12 01:40:00 +02:00
9ae6823841 disabled "optimization attempt" for automerge again, did not bring much performance and caused visual errors 2017-06-11 18:43:36 +02:00
b8cb539f2c fix for old dynamic external mode 2017-06-11 18:16:19 +02:00
83144efb4d further automerge speed optimization attempts 2017-06-11 17:48:45 +02:00
4670d18474 use separate storage for packed geometry, allows mode switching and re-use of it 2017-06-11 11:49:50 +02:00
8fe651325c recalc normals when merging (distance>0) and not using fix normals 2017-06-10 21:58:25 +02:00
9c2ca73575 clamped distortion and keep shared groups with autohide distance = 0 as well 2017-06-10 21:40:53 +02:00
170007cc4f fix for automerge, with bisect / fast bisect recalc normals on merge, also no redundant shared groups any more 2017-06-10 19:49:45 +02:00
03c11e58a9 crash fix when using ob->derivedFinal for a bbox calculation, needed to check its validity better 2017-06-08 16:50:23 +02:00
fcff61a1bd made do_merge and keep_distort optional 2017-06-08 15:40:20 +02:00
bb9f2e4037 keep distorted shape after tearing, todo, make this optional ? 2017-06-08 14:25:34 +02:00
1b19fea008 tweak for inner crease, only appear on torn edges 2017-06-08 13:19:39 +02:00
b1d786de2c fix for automerge, do not snap together after exceeding threshold, and adding optionally crease to edges, too 2017-06-08 13:00:47 +02:00
4d8b238e4b first attempt for better automerging 2017-06-08 01:15:16 +02:00
e041ca68e1 fix for packing materials, material index start value could overflow due to being a short instead of int 2017-06-07 18:08:43 +02:00
51a088cbea also store material index in shards, so it can be loaded from blend later 2017-06-07 16:15:39 +02:00
05e4103ba4 fix for material assignment when converting back to objects 2017-06-07 16:08:55 +02:00
0812e32572 prefer vector handle on adaptive keyframe in convert to keyframed objects 2017-06-04 19:59:32 +02:00
76e114180d fix attempt for particle systems supporting dynamicly changing vertexgroups 2017-06-04 19:35:26 +02:00
948ad8e88b crash fix and attempt to reduce unnecessary memory usage 2017-06-04 00:55:19 +02:00
b25edc6352 set allowed smoke timescale from 0.0 to 2.0, thus allow static and a bit faster smoke as well 2017-06-03 19:58:00 +02:00
15b3b2bdcd minor tweak, just activate clusters and keep inter-cluster constraints intact in that case 2017-06-02 15:41:03 +02:00
56f42dacd2 fix for cluster percentage, was incorrectly calculated before and only used if regular percentage was set 2017-06-02 10:02:50 +02:00
a293d028b9 new "Handle" option for convert to keyframes, if set calculates handles to be auto or vector(adaptive), but can be slower 2017-06-01 12:42:32 +02:00
899c2b921c further optimization attempts with convert to keyframed objects 2017-05-31 20:43:47 +02:00
b7327017a0 fix for convert to keyframes, needs no bake and should be initialized properly after refracture 2017-05-31 13:41:18 +02:00
fe95515de0 performance improvement with convert to keyframes and new adaptive keyframe option (threshold of changes) 2017-05-30 17:44:18 +02:00
b7f7879ad2 added step option to convert to keyframes, new parameter popup dialog, also backported fseek fix to meshcache modifier 2017-05-29 21:33:40 +02:00
f6924b23bf fix for loading bakes from official build (single objects)
also reverted from exact volume calculation of shards to bbox (faster)
removed some development printouts
2017-05-22 19:28:30 +02:00
2f6f36ef5a added rectangular alignment feature for fast bisect (works with uniform only)
the closer the factor is to 1, the more rectangular-ish the shards will look like. default is 0 which means any rotation is allowed.
2017-05-12 17:48:34 +02:00
ad99d53b8a fix for jumps in rotation when converting to keyframed objects 2017-04-21 13:14:08 +02:00
a9e14e1018 crash fix for physical rough edges (corrupted memory) 2017-03-29 20:55:48 +02:00
0decb16563 do not execute refresh operator in running sim any more 2017-03-28 21:38:59 +02:00
6806065c38 apparently fixed the cuttergroup bug (was an incorrect bbox test) + silenced 2 warnings 2017-03-28 18:35:27 +02:00
e8f0228977 fix attempt for numerical instabilty with cuttergroups + a couple of minor fixes
as workaround you could use particlehelper and uniform together with cuttergroups
2017-03-28 17:41:49 +02:00
65c86fc66b load crash fix if FM is there but hasnt been executed prior to save 2017-03-15 20:55:42 +01:00
5bac7e5ac7 fix for loading cutter group fractures and allow all algorithms now in combination with cuttergroup 2017-03-15 17:36:25 +01:00
5f56257713 added basic material handling and outputting vertexgroups for intersect/difference shards with cuttergroups 2017-03-12 13:11:52 +01:00
e63c6cd345 fix attempt for passive fakeparenting with dynamic/external, and first version of combined cuttergroup and procedural (boolean only) fracture 2017-03-11 18:52:01 +01:00
30acaddb6c fixes for constraint behavior in dynamic_external mode 2017-03-07 21:34:12 +01:00
3b0646b3ac dissolve constraint now only dissolves constraints between different clusters if clusters are used
additionally added a python-settable variable to indicate whether the dynamic fracture data has been loaded externally or not (just set it from the handler)
2017-03-07 16:41:09 +01:00
cd6e18db8a added handlers which are triggered after freeing shards and before rebuilding constraints
this is supposed to keep externally loaded data in place when changing over to dynamic fracture, the handler triggers a python script which populates the meshislands and another to populate the constraints via the FM python API.
Additionally a couple of minor fixes for dynamic fracturing.
2017-03-06 19:24:55 +01:00
57a1e434e5 fix for hair particle system, was wrong hair distribution and render error
suppressed "dynamic" particle redistribution for hair now too
2017-03-03 13:19:57 +01:00
a34e295b68 fix, forgot to copy splinter axis when duplicating FM object 2017-02-26 21:18:45 +01:00
c073d3e8a4 Merge remote-tracking branch 'refs/remotes/origin/blender-v2.78c-release' into fracture_modifier 2017-02-25 15:44:10 +01:00
bc27652e57 tests: Update hash for OBJ
Was a recent update of UV precision.
2017-02-23 18:04:00 +01:00
27167ee3a4 Cycles: Fix compilation error on 32bit Linux 2017-02-23 17:30:54 +01:00
551265424b Fix T50243: libmv_panography_test is broken
There was fully wrong logic in comparison: was actually accessing memory
past the array boundary. Run test manually and the figure seems correct
to me now.

Spotted by @LazyDodo, thanks!
2017-02-23 17:18:03 +01:00
15fb1fdb99 [msvc] Set proper OpenSubdiv flags when not using find_package to find opensubdiv. Fixes T50548 2017-02-23 16:21:16 +01:00
7d77dcd190 Blender 2.78c: Officially move to 'c' 2017-02-23 16:07:47 +01:00
909c8ec07a Cycles: Fix wrong render results with texture limit and half-float textures 2017-02-23 15:07:45 +01:00
b95645c1ae Fix T50748: Render Time incorrect when refreshing rendered preview in GPU mode 2017-02-23 15:07:02 +01:00
67169e70d6 Fix T50687: Cycles baking time estimate and progress bar doesn't work / progress when baking with high samples 2017-02-22 16:58:37 +01:00
e89145efd3 Fix T50512: Linked Backround scene with animation not updating with new depsgraph
Was missing relations for the set scenes.

Perhaps not ideal solution, but should be good enough for now.
2017-02-22 16:48:48 +01:00
dd2e33b24d Blender 2.78c: Fix crash with material preview and image sequences
Don't use built-in API for image sequences since it's not really
finished in RNA API.

Fixes issue reported in T50616.
2017-02-22 16:46:00 +01:00
99abd1f79e Blender 2.78c: Fix wrong render result with pointiness
The issue was caused by pointiness being calculated after
faces split now. Ported all fixes we did here.

Should be safe, pointiness is used all over the barbershop.
2017-02-22 16:34:10 +01:00
92e75a54f4 Cleanup 2017-02-22 15:57:41 +01:00
8ba1dab3a2 Blender 2.78c: Fix Brick Texture GLSL, broken after Mortar Smooth addition. 2017-02-22 15:33:30 +01:00
9215848c38 Fix T50550: GPUShader: compile error - Background image not showing in
viewport.

Caused by rBd6cf28c5e15739f864fbf04614c2a50708b4b152, which forgot to
update the GLSL code for the "Light Path" node.
2017-02-22 15:25:28 +01:00
b3b4084073 Blender 2.78c: Fix wrong cycles hair render results when using BVH motion steps
This commit contains all commits required to get proper hair rendering
with BVH motion steps enabled.

The issue here was mainly coming from minimal pixel width feature
which is quite commonly enabled in production shots.

This feature will use some probabilistic heuristic in the curve
intersection function to check whether we need to return intersection
or not. This probability is calculated for every intersection check.
Now, when we use multiple BVH nodes for curve primitives we increase
probability of that primitive to be considered a good intersection
for us. This is similar to increasing minimal width of curve.

What is worst here is that change in the intersection probability
fully depends on exact layout of BVH, meaning probability might
change differently depending on a view angle, the way how builder
binned the primitives and such. This makes it impossible to do
simple check like dividing probability by number of BVH steps.

Other solution might have been to split BVH into fully independent
trees, but that will increase memory usage of all the static
objects in the scenes, which is also not something desirable.

For now used most simple but robust approach: store BVH primitives
time and test it in curve intersection functions. This solves the
regression, but has two downsides:

- Uses more memory.

  which isn't surprising, and ANY solution to this problem will
  use more memory.

  What we still have to do is to avoid this memory increase for
  cases when we don't use BVH motion steps.

- Reduces number of maximum available textures on pre-kepler cards.

  There is not much we can do here, hardware gets old but we need
  to move forward on more modern hardware..
2017-02-22 15:08:56 +01:00
c6e4a81dfb Blender 2.78c: Port all commits related on new Cycles regression tests 2017-02-22 15:07:18 +01:00
3c043732d3 Blender 2.78b: Point addons to an updated revision 2017-02-08 14:50:08 +01:00
cc6cf0cdce fix, keep bake until convert to keyframe has been finished, and delete then
Deleting the bake after changing the rigidbody count still is necessary, else the shard order and the mesh appearance of fracture modifier objects will be messed up.
Furthermore, decreased the convert to keyframe default threshold from 0.05 to 0.005, reconverting by re-using
the operator again still is somewhat broken
2017-02-05 17:24:44 +01:00
9cb21a1400 Blender release: We are officially 'b' now 2017-02-03 17:54:29 +01:00
a3e746733d [msvc] cmake fixes to support the recent for oiio/ffmpeg/numpy version changes. 2017-02-03 09:47:54 -07:00
8fa3801c49 Fix fluid sim build error with MSVC. 2017-02-03 15:48:09 +01:00
34b09852fd Fluids: improve multithreaded CPU usage.
Fixes for clamp-omp, fewer shared variables, fix some cases of threads writing
to the same memory location. Issue found by Jens Verwiebe, who reports 30%
speedup with 16 core CPU, when using this with a recent clang-omp version.
2017-02-03 15:48:06 +01:00
f6d2981ffb Cycles tests: Allow python auto-exec 2017-02-03 10:46:56 +01:00
9f6cfa3ead Cycles: Fix rng_state initialization when using resumable rendering 2017-02-01 11:48:50 +01:00
9529a96fd0 fix attempt for disappearing fm debris particles after baking 2017-01-29 19:08:38 +01:00
3c518ab4a4 crash fix, do not update tessface data while loading, only ensure it (saved fracture might have been invalid mesh) 2017-01-29 19:07:33 +01:00
7314ede784 Fix compilation error with latest OIIO 1.7.8
There are some changes in OIIO includes so now need to do some
things differently.
2017-01-26 11:27:44 +01:00
8ceed387c9 Return correct alpha for environment map in GLSL 2017-01-26 11:19:12 +01:00
672fbbfb4e Fix T49405: Crash when baking with adaptive subdivision
Blenders baking system currently doesn't support the topology used by
adaptive subdivision and primitive ids will be wrong or out of range
leading to crashes. Updating the baking system to support other
topologies would be a bit involved, so for now we simply disable
subdivision while baking to avoid crashes.
2017-01-26 11:16:34 +01:00
59c224ebc7 Cycles: Don't rely on indirectly included algorithm 2017-01-26 11:16:24 +01:00
7a9f8d0c77 Cycles: Fix typo in the panel name
No user visible changes, it was a typo in the name of the class.

Spotted by povmaniac in IRC, thanks!
2017-01-26 11:15:35 +01:00
2a757450f5 Cycles: Update current Cycles version 2017-01-26 11:15:25 +01:00
82e0127065 Fix T50491: Cycles UI breaks when pushing F8.
Cycles add-on did not actually support reloading correctly.

When you want to correctly reload sub-modules (i.e. modules of an add-on
which is a package), you need to use importlib, a mere import will do
nothing with already loaded modules (RNA classes are sort of
pre-registered when they are evaluated, through the meta-class system).
2017-01-26 11:15:18 +01:00
bfd209007d Cycles: Use more const qualifiers to avoid possible issues 2017-01-26 11:15:06 +01:00
db26c6f66c Cycles: Cleanup, split one gigantic function into two smaller ones 2017-01-26 11:15:00 +01:00
a65a988592 Cycles: Store time in BVH nodes
This way we can stop traversing BVH node early on.

Gives about 2-2.5x times render time improvement with 3 BVH steps.
Hopefully this gives no measurable performance loss for scenes with
single BVH step.

Traversal is currently only implemented for QBVH, meaning old CPUs
and GPU do not benefit from this change.
2017-01-26 11:14:51 +01:00
91fe6bdcb6 Cycles: Add option to split triangle motion primitives by time steps
Similar to the previous commit, the statistics goes as:

BVH Steps     Render time (sec)       Memory usage (MB)
    0                46                    260
    1                27                    373
    2                18                    598
    3                15                    826

Scene used for the tests is the agent's body from one of the barber
shop scenes (no textures or anything, just a diffuse material).

Once again this is limited to regular (non-spatial split) BVH,
Support of spatial split to this feature will come later.
2017-01-26 11:14:42 +01:00
9bf3b4679e Cycles: Add option to split curve motion primitives by time steps
The idea is to create several smaller BVH nodes for each of the motion
curve primitives. This acts as a forced spatial split for the single
primitive.

This gives up render time speedup of motion blurred hair in the cost
of extra memory usage. The numbers goes as:

BVH Steps     Render time (sec)       Memory usage (MB)
    0               258                    191
    1               123                    278
    2                69                    453
    3                43                    627

Scene used for the tests is the agent's hair from one of the barber
shop scenes.

Currently it's only limited to scenes without spatial split enabled,
since the spatial split builder requires some changes to work properly
with motion steps coordinates.
2017-01-26 11:14:36 +01:00
be431c7cdc Cycles: Add utility function to calculate curve boundbox from given 4 keys
Also fixed some issues with motion keys calculation:

- Clamp lower and upper limits of curves so we can safely call those
  functions for the very first and very last curve segment.
- Fixed wrong indexing for the curve radius array.
- Fixed wrong motion attribute offset calculation.
2017-01-26 11:14:28 +01:00
d87caabf29 Cycles: Cleanup, trailing whitespace 2017-01-26 11:14:20 +01:00
f6742d36cd Cycles: Split motion triangle file once again, avoids annoying forward declarations 2017-01-26 11:14:12 +01:00
acbba822f7 Cycles: Move motion triangle intersection functions to own file
Mimics how regular triangles are working and makes it more clear where
the stuff is located in the kernel.

Needed to have some forward declarations because of the current placement
of things in the kernel.
2017-01-26 11:14:02 +01:00
69357d9db0 Cycles: Cleanup, better variable name 2017-01-26 11:13:54 +01:00
5a5b45374b Cycles: Add utility function to fetch motion keys while on CPU side 2017-01-26 11:13:48 +01:00
93c5388e34 Cycles: Cleanup, comments 2017-01-26 11:13:40 +01:00
df3511c96f Cycles: Add utility function to fetch motion triangle when on CPU side 2017-01-26 11:13:34 +01:00
eabb8f1d12 Cycles: Cleanup, delete trailing whitespace 2017-01-26 11:13:28 +01:00
5283a7e518 Fix T50460. Greying out issue with Cycles culling options. 2017-01-26 11:13:06 +01:00
c727bc7743 Fix T50517: Rendering expecting time is negative 2017-01-25 11:22:14 +01:00
feb2f0ae30 FIX T49899: Add EIGEN_MAKE_ALIGNED_OPERATOR_NEW to classes that use eigen's data types , to force aligned on 16 byte boundaries. 2017-01-24 11:54:39 +01:00
44ffbcd254 Fix T49857: Blender crashes after adding texture node to compositing tree 2017-01-24 11:54:39 +01:00
f8a3b9b50c Cycles: Fix compilation error on with older GCC
Hopefully it works on all platforms now.
2017-01-20 12:17:11 +01:00
faaf41b330 Depsgraph: Bone parent should also include armature transform relation
It is required to have world-space bone position, which consists of armature
object transform and local bone transform.
2017-01-20 11:37:00 +01:00
8a0e91366c Depsgraph: Only re-schedule objects which are on visible layers
Otherwise it's possible to cause infinite update loop in Cycles viewport.

Gets a bit messy logic, need to revisit this..
2017-01-20 11:37:00 +01:00
85c7ecce27 Depsgraph: Use HIGH priority for scheduled tasks
This kind of keeps threads "warmer" and should in theory give better
cache coherency bringing some %% of speedup. It was already tested
few months ago and it gave few % speedup in barber shop, but was
reverted due to some bone popping. The popping is now fixed so it
should be fine to use new scheduling policy.
2017-01-20 11:37:00 +01:00
e3ede8294a Depsgraph: avoid more transitive relations for rigid body simulation 2017-01-20 11:37:00 +01:00
bff566215e Depsgraph: Rigid body simulation doesn't need explicit time relation
It'll be dependent on time via Time Source -> Rebuild RB World chain.
2017-01-20 11:36:59 +01:00
10ce1eea3f Depsgraph: Avoid transitive relation from local transform to final
There is always an uber eval node on the way. so we can avoid creating
some relations here in order to speed up both construction time and
evaluation.
2017-01-20 11:36:59 +01:00
5c4c2bebaa Fix depsgraph: hair collision is actually enabled, so add the relations. 2017-01-20 11:36:59 +01:00
85ec0446e1 Depsgraph: Fix matrix_world driver source
Reported by Dalai in IRC, thanks!
2017-01-20 11:36:59 +01:00
4a4959a647 Fix T49981: New Depsgraph - When camera is on inactive layer, it does not evaluate constraints 2017-01-20 11:36:59 +01:00
a3f66a868e Depsgraph: Fix infinite viewport object update in CYcles render mode
The issue was caused by wrong object re-tag needed to have proper dependnecies
update for OpenSubdiv.
2017-01-20 11:36:58 +01:00
8e908ae321 Depsgraph: use more explicit parenthesis 2017-01-20 11:36:58 +01:00
82cee9cb89 Depsgraph: Fix residue of debug-only code 2017-01-20 11:36:58 +01:00
b5b0354b7c Fix copy/paste typo in new depsgraph object geometry builder (found by coverity). 2017-01-20 11:36:58 +01:00
5708ec2a01 Depsgrpah: Fix missing animation update in movie clips 2017-01-20 11:36:58 +01:00
317431461f Depsgraph: Move scene builder function to own file
This way it's much easier to grasp what the graph actually contains.
2017-01-20 11:36:57 +01:00
48a8a20e2a Fix T50060: New depsgraph does not update mask animation 2017-01-20 11:36:57 +01:00
cf60343b06 Depsgraph: Use utility macro to iterate over linked list
This will be compiled into same exact code, just saves us from
doing annoying type casts all over the place.
2017-01-20 11:36:57 +01:00
c02ba89d6a Depsgraph: Move rig builder functions to own files
Those routines are rather big and started to be annoying to have
one big file.

Should be no functional changes.
2017-01-20 11:36:57 +01:00
3d2a6e7db3 Depsgraph: Fix typo in previous optimization commit
Was a residue from another experiment, caused infinite loop when
reporting dependency cycles.
2017-01-20 11:36:57 +01:00
6d6c333ee9 Atomics: Make naming more obvious about which value is being returned 2017-01-20 11:36:56 +01:00
fb2d5a9853 Fix T49994: Setting dupligroup which uses indirect relation will crash
Did similar trick to old dependency graph: tag invisible relations for update.

Might need some re-consideration, see the comment.

This should solve our issues with powerlib addon here in the studio.
2017-01-20 11:36:56 +01:00
8ddc85ab59 Depsgraph: Add missing NULL pointer check 2017-01-20 11:36:56 +01:00
d3963e2bb0 Depsgraph: Fix missing DONE flag in relations builder
Was causing relations be build twice in certain cases.
2017-01-20 11:36:56 +01:00
c0c6af2cdd Fix T49993: Indirectly used taper/bevel crashes new dependency graph
New dependency graph expects strict separation between nodes and relations builder,
meaning, if we try to create relation with an object which is not in the graph yet
we'll have an error in depsgraph.

Now, so far object nodes were created from bases of the current scene, which caused
missing objects in graph in certain cases.

Didn't find better approach than to simply ensure object nodes exists when we know
they'll be used by relation builder.
2017-01-20 11:36:56 +01:00
88d02e5433 Depsgraph: Fix typo in text on curve relation builder 2017-01-20 11:36:56 +01:00
9d2a7961fc Depsgraph: Fix missing ID node tag
Might have caused nodes created multiple times for the same object.
2017-01-20 11:36:55 +01:00
a45d648485 Depsgraph: Add some data builder logic to corresponding function 2017-01-20 11:36:55 +01:00
ad01f0d19b Depsgraph: cleanup, no functional changes 2017-01-20 11:36:55 +01:00
29ef143ef9 Depsgraph: Fix another issue which seems to be a bug
Similar to a previous commit.

Doing separately for an easy of bisect.
2017-01-20 11:36:55 +01:00
5393e78367 Depsgraph: Fix wrong relation from IK solver to pole target
Copy paste error...

How to avoid those?
2017-01-20 11:36:55 +01:00
f737bc673b Depsgraph: Disable timing profile 2017-01-20 11:36:55 +01:00
Martijn Berger
3d75a7d0dc fix building depsgraph after recent changes 2017-01-20 11:36:54 +01:00
faa8b12714 Depsgraph: Do not rely on indirectly included cstring
Also add comment why exactly cstring is needed.
2017-01-20 11:36:54 +01:00
1c5502def8 Despgraph: Optimize cycles detection algorithm
The idea is simple: when falling back to one of the nodes which was partially
handled we "resume" checking outgoing relations from the index which we stopped.

This gives about 15-20% depsgraph construction time save.
2017-01-20 11:36:54 +01:00
34199e82fc Depsgraph: Speedup initial rig build time
We don't need to sort bone channels, it's all taken care about
by the depsgraph itself.

Gives up to 30% initial rig construction time speedup.
2017-01-20 11:36:54 +01:00
b15d218db5 Depsgraph: Move key implementation from header to dedicated file 2017-01-20 11:36:54 +01:00
93783cb176 Depsgraph: Move class implementation from header to implementation files
This is more proper way to go:

- Avoids re-compilation of all dependent files when implementation changes
  without changed API,

- Linker should have much simpler time now de-duplicating and getting rid
  of redundant implementations.
2017-01-20 11:36:54 +01:00
06c202002b Depsgraph: Fully switch from string to const char*
This brings up to 10-20% depsgraph build time improvement in the layout
files from the studio repository.
2017-01-20 11:36:53 +01:00
570c072020 Depsgraph: Add extra name tag for operation nodes
The idea here is to address issue that name on it's own is not
always unique: for example, when adding driver operations the
name used for nodes is the RNA path (and multiple drivers can
write to different array indices of the path). Basically, now
it's possible to pass extra integer value to distinguish
operations in such cases.

So now we've already switched from sprintf() to construct unique
operation name to pass RNA path and array index.

There should be no functional changes yet, but this work is
required for further work about replacing string with const
char*.
2017-01-20 11:36:53 +01:00
1d5833caf5 Depsgraph: Cleanup, operation has name, not description
Hopefully should make things more clear here.
2017-01-20 11:36:53 +01:00
507599270f Depsgraph: Remove unused function
A residue from times where we thought to do partial graph updates,
which we are not committing any time soon.
2017-01-20 11:36:53 +01:00
c520c4955f Depsgraph: Use const char for component API 2017-01-20 11:36:53 +01:00
c8f942574d Depsgraph: Remove some includes which seems unused 2017-01-20 11:36:52 +01:00
4939ec8a13 Depsgraph: Use const char instead of string in part of drivers construction 2017-01-20 11:36:52 +01:00
f7f44da43d Depsgraph: Switch away form string to const char* for node names
There is no real reason to have nodes storing heap-allocated name
and description. Doing this increases amount of allocations during
dependency graph building, which usually means somewhat slowness.

We're temporarily loosing some eyecandy in the graphviz visualizer,
but those we can bring back as a part of graphiz dump (which happens
much less often than depsgraph build).

This will happen in multiple commits for the ease of bisect in the
future just in case this causes any regression. This commit contains
ID creation API changes.
2017-01-20 11:36:52 +01:00
fe53bdf893 Depsgraph: Remove prototype of unused and non-implemented method 2017-01-20 11:36:52 +01:00
f7c0b01c2d Depsgraph: Add code for timing despgraph builder 2017-01-20 11:36:52 +01:00
71d48a44a5 Fix T49826: NEW-DEPSGRAPH - Texture is not updated after changing its space color
The issue was caused by image ID nodes not being in the depsgraph.

Now, tricky part: we only add nodes but do not add relations yet. Reasoning:

- It's currently important to only call editor's ID update callback to solve
  the issue, without need to flush changes somewhere deeper.

- Adding relations might cause some unwanted updates, so will leave that for
  a later investigation.
2017-01-20 11:36:52 +01:00
7d9be2f44e Depsgraph: Fix wrong comparison of ID type vs. node type 2017-01-20 11:36:51 +01:00
6514cbae6b Depsgraph: Fix race condition writing drivers to array property
Animation system has separate fcurves for each of array elements and
dependency graph creates separate nodes for each of fcurve, This is
needed to keep granularity of updates, but causes issues because
animation system will actually write the whole array to property when
modifying single value (this is a limitation of RNA API).

Worked around by adding operation relation between array drivers
so we never write same array form multiple threads.
2017-01-20 11:36:51 +01:00
e4164f31fc Depsgraph: Fix some errors printed to the console
They were not real issues, it's just some areas of code tried to create
relations between non-existing nodes without checking whether such
relations are really needed.

Now it should be easier to see real bugs printed.

Hopefully should be no regressions here.
2017-01-20 11:36:51 +01:00
8b192ade96 Partial fix for T49836: Camera DOF properties not updating via graph editor
Do this for the new dependency graph: was missing handle of OB_UPDATE_TIME in tag update.

Hopefully it's all correct still.

Old dependency graph needs work, but i'm tempting to call it unsupported and move on
to 2.8 branch.
2017-01-20 11:36:51 +01:00
1c29fbed65 Depsgraph: Report proper error when modifier fails to create relation link 2017-01-20 11:36:51 +01:00
085ce77b64 Depsgraph: Avoid some false-positive time dependencies of scripted drivers
This was quite weak to consider all scripted expression to be time-dependent.
Current solution is somewhat better but still crappy. Not sure how can we make
it really nice.
2017-01-20 11:36:51 +01:00
4ad131f9f1 Solve threading conflict when calculating smooth normals
It was possible to have synchronization issues whe naccumulating smooth
normal to a vertex, causing shading artifacts during playback.

Bug found by Dalai, thanks!
2017-01-20 11:36:50 +01:00
05fd3b586f RNA: Expose autosmooth face splitting
This way render engine can request mesh to be auto-split and not
worry about implementing this functionality on it's own.

Please note that this split is to be performed prior to tessellation.
2017-01-20 11:29:02 +01:00
7e5a0c146e Fix compile error (-Werror=float-conversion). 2017-01-20 11:26:25 +01:00
4564b014be Cycles: Expose diffuse and glossy depth to Light Path node
Was a bit confusing to have transparent and translucent depth
exposed but no diffuse or glossy.

Reviewers: brecht

Subscribers: eyecandy

Differential Revision: https://developer.blender.org/D2399
2017-01-20 11:26:24 +01:00
5f2ed8ccf1 Cycles: Don't use fast math for the host code
This is important for the reliable behavior or isnan/isfinite/min/max
functions to work with nan and non-finite values. Some of the issues
with fast math are possible to work around, but didn't find a way to
have reliable min/max implementation yet.
2017-01-20 11:26:24 +01:00
a1570562f3 Cycles: Add fast-math safe isnan and isfinite
Currently unused, but might become really handy in the future.
2017-01-20 11:26:24 +01:00
46926b4b11 Cycles: Remove using namespace hell
Please NEVER EVER use such a statement, it's only causing HUGE
issues. What is even worse: it's not always possible to immediately
see that the hell is coming from such a statement.

There is still some statements in the existing code, will leave
those for a later cleanup.
2017-01-20 11:26:24 +01:00
83d7c64bc9 Cycles: Fix amount of rendered samples not being shown while rendering the last tile on CPU 2017-01-20 11:26:24 +01:00
1f390081c2 Cycles: Cleanup, spelling 2017-01-20 11:26:23 +01:00
d28035aff3 Cycles: Cleanup, avoid shadowing 2017-01-20 11:26:23 +01:00
618177640f Cycles: Fix wrong transparent shadows for motion blur hair
This was a missing bit from b53ce9a.
2017-01-20 11:26:23 +01:00
3f3463700e Cycles: Cleanup, style 2017-01-20 11:26:23 +01:00
3b454eb92c Cycles: Simplify some code in Curve BVH reference fill
makes code slightly shorter and uses idea of const qualifiers.
2017-01-20 11:26:23 +01:00
bd302ecf73 Cycles: Avoid shadowing in BVH code
Run into some nasty bugs while trying various things here.

Wouldn't mind enabling -Wshadow for Cycles actually..
2017-01-20 11:26:23 +01:00
a503e7626a Cycles: Allow up to 4 motion curve primitives per BVH node
This avoids intersection AABB of different curve primitives
which makes it less ray-to-primitive intersections.

This gives about 30% speedup of hair rendering in the barber
shop scenes here. There is still some work to be done on those
files to solve major speed issues on certain frames.
2017-01-20 11:26:22 +01:00
fb6a94170f Cycles: Prepare BVH traversal code to work with multiple curve primitives per node 2017-01-20 11:26:22 +01:00
0f5db226cf Cycles: Correct assert() for cases when there are multiple curves per BVH node 2017-01-20 11:26:22 +01:00
a1f0e53498 Cycles: Use separate limit for motion primitives for BVH node limits
This way we can have different limits for regular and motion curves
which we'll do in one of the upcoming commits in order to gain some
percents of speedup.

The reasoning here is that motion curves are usually intersecting
lots of others bounding boxes, which makes it inefficient to have
single primitive in the leaf node.
2017-01-20 11:26:22 +01:00
d3e6fe0506 Cycles: Change confusing logic of max leaf size check
Maximal number of elements is supposed to be inclusive. That is what
it was always meant in this file and what @brecht considered still
the case in 6974b69c61.

In fact, the commit message to that change mentions that we allowed
up to 2 curve primitives per leaf while in fact it was doing up to 1
curve primitive.

Making it real 2 primitives at a max gives about 5% slowdown for the
koro.blend scene. This is a reason why BVHParams.max_curve_leaf_size
was changed to 1 by this change.
2017-01-20 11:26:22 +01:00
fa1988a34f Cycles: Cleanup, space prior to semicolon
We don't have that in Blender style, no reason to violate it here.
2017-01-20 11:26:22 +01:00
e92e265559 Cycles: Cleanup, make curve functions private
Not only they don't really follow naming convention (we don't use
camel case) but also was not necessary to keep them in the global
symbol table.
2017-01-20 11:26:21 +01:00
10cef4e86f Cycles: Make it more clear message why curve motion attribute was removed 2017-01-20 11:26:21 +01:00
086390dce7 Cycles: Use dedicated debug passes for traversed nodes and intersection tests
This way it's more clear whether some issue is caused by lots of geometry in
the node or by lots of "transparent" BVH nodes.
2017-01-20 11:26:21 +01:00
e15639f1cd Cycles: Remove more duplicated code in debug passes logic 2017-01-20 11:26:21 +01:00
41ed782350 Cycles: Fix wrong scaling of traversed instances debug pass 2017-01-20 11:26:21 +01:00
3cb1398899 Cycles: Cleanup, remove duplicated code 2017-01-20 11:26:20 +01:00
0fdb16ec4d Cycles: Cleanup, indentation within preprocessor 2017-01-20 11:26:20 +01:00
e9e1c95e64 Cycles: Cleanup, use switch() instead of if-else chain
About to add extra debug passes, which will be more clear to use switch().
2017-01-20 11:26:20 +01:00
39bc6172a4 Cycles: move hair particle settings to scene context
Since the beginning of times hair settings in cycles were global for
the whole scene but were located in the particle context. This causes
quite some trickery to get shots set up for the movies here in the
studio by forcing artists to create dummy particle system to change
settings of hair on the shot.

While ideally this settings should be properly become per-particle
system for the time being it will save sweat and blood to move the
settings to scene context.

Reviewers: brecht

Subscribers: jtheninja, eyecandy, venomgfx, Blendify

Differential Revision: https://developer.blender.org/D2287
2017-01-20 11:26:20 +01:00
8e372da1b5 Cycles: Fix wrong motion blur when combining deformation motion blur with autosplit
The issue was that we used to compare number of vertices for mesh after the auto
smooth was applied (at the center of the shutter time) with number of vertices
prior to the auto smooth applied. This caused false-positive consideration of a
mesh as changing topology.

Now we do autosplit as early as possible and do it from blender side, so Cycles
does not need to re-implement splitting on it's side.
2017-01-20 11:26:20 +01:00
aeece53491 Cycles: Pass explicit subdivision type to object_to_mesh
This allows us to do some extra logic checks there based on particular
subdivision type.

Additionally avoids implicit cast of enum to bool.
2017-01-20 11:26:20 +01:00
f0d866d143 Cycles: Cleanup, whitespace around operator 2017-01-20 11:26:20 +01:00
fa73db47e8 Cycles: Improve logging of cases when motion blur is disabled
Next logical step is to expose this somehow to the interface.
2017-01-20 11:26:19 +01:00
f071e48dcf Cycles: Fix uninitialized variable issue after recent changes 2017-01-20 11:26:19 +01:00
d8a8f69c98 Cycles: Move object culling helper to own files
This is a stand-alone logic, which becomes quite comprehensive now.
2017-01-20 11:26:19 +01:00
893aa1cae3 Cycles: Fix indendation 2017-01-20 11:26:19 +01:00
166b6c9240 Cycles: Consider GGX/Beckmann/Ashikhmin of 0 roughness a singular ray
This matches behavior of Multiscatter GGX and could become handy later on
when/if we decide it would be beneficial to replace on closure with another.

Reviewers: lukasstockner97, brecht

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2413
2017-01-20 11:26:19 +01:00
14e7ac956f Cycles: Tweak curve segment (un)pack to handle more curve segments
There was 16 bits reserved for primitive type, while we only need 4.

Reviewers: brecht

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2401
2017-01-20 11:26:18 +01:00
5030854a66 Cycles: Cleanup, variable names
Use underscore again and also solve confusing part then in BVH smae
thing is called prim_addr but in intersection funcitons it was called
triAddr.
2017-01-20 11:26:18 +01:00
b8fc22fde1 Cycles: Cleanup, variables names
Use underscore instead of camel case.
2017-01-20 11:26:18 +01:00
5edef96d77 Land D2339 by bliblu bli 2017-01-20 11:26:18 +01:00
d546f66efc Fix emissive volumes generates unexpected fireflies around intersections
Discard the whole volume stack on the last bounce (but keep
world volume if present).

Volumes are expected to be closed manifol meshes, meaning if
ray entered the volume there should be an intersection event
of ray exisintg the volume. Case when ray hit nothing and
there are still non-world volumes in the stack can happen in
either of cases.

1. Mesh is not closed manifold.

Such configurations are not really supported anyway and should
not be used.

Previous code would have consider the infinite length of the
ray to sample across, so render result wasn't really correct
anyway.

2. Exit intersection is more far away than the camera far
   clip distance.

This case also will behave differently now, but previously it
wasn't really correct either, so it's not like we're breaking
something which was working as expected.

3. We missed exit event due to intersection precision issues.

This is exact the case which this patch fixes and avoid
fireflies.

4. Volume has Camera only visibility (all the rest visibility
is set to off)

This is what could be considered a regression but could be
solved quite easily by checking volume stack's objects flags
and keep entries which doesn't have Volume Scatter visibility
(or even better: ensure Volume Scatter visibility for objects
with volume closure),

Fixes T46108: Cycles - Overlapping emissive volumes generates unexpected bright hotspots around the intersection
Also fixes fireflies appearing on the edges of cube with
emissive volue.

Reviewers: juicyfruit, brecht

Reviewed By: brecht

Maniphest Tasks: T46108

Differential Revision: https://developer.blender.org/D2212
2017-01-20 11:26:18 +01:00
e4b67e7e5e Cycles :Cleanup, indentation 2017-01-20 11:26:18 +01:00
dd156f743c Cycles: Refactor Progress system to provide better estimates
The Progress system in Cycles had two limitations so far:
 - It just counted tiles, but ignored their size. For example, when rendering a 600x500 image with 512x512 tiles, the right 88x500 tile would count for 50% of the progress, although it only covers 15% of the image.
 - Scene update time was incorrectly counted as rendering time - therefore, the remaining time started very long and gradually decreased.

This patch fixes both problems:
First of all, the Progress now has a function to ignore time spans, and that is used to ignore scene update time.
The larger change is the tile size: Instead of counting samples per tile, so that the final value is num_samples*num_tiles, the code now counts every sample for every pixel, so that the final value is num_samples*num_pixels.

Along with that, some unused variables were removed from the Progress and Session classes.

Reviewers: brecht, sergey, #cycles

Subscribers: brecht, candreacchio, sergey

Differential Revision: https://developer.blender.org/D2214
2017-01-20 11:26:17 +01:00
f2677a58a5 Cycles: Implement AVX2 path for curve intersection functions
Gives little performance improvement on Linux and gives up to 2%
speedup on koro.blend on Windows.

Inspired by Maxym Dmytrychenko, thanks!
2017-01-20 11:26:17 +01:00
7e5af7aefd Cycles: Add AVX intrinsics helpers
They are defined for MSVC but seems to be missing in GCC and CLang-3.8.

Maybe some further tweaks to policy when to define those functions is
needed, but should be fine for now.
2017-01-20 11:26:17 +01:00
6df6f8c982 Cycles: Disable AVX2 crash workarounds
I can no longer reproduce crash with neither of the files where
the crash was originally visible. This is something where other
changes (light threshold, sampling) had an effect and made code
to work as it is supposed to. Could have been optimizator issue
or something like that.

Let's see if we hit same issue again.
2017-01-20 11:26:17 +01:00
a3ef4c1470 Fix T50116: Light threshold broke branched path tracer
In fact, the issue was caused by light threshold being too high for
certain scenes. Lowered it down to 0.01.
2017-01-20 11:26:17 +01:00
5aede15fea Cycles: Fix correlation issues in certain cases
There were two cases where correlation issues were obvious:

- File from T38710 was giving issues in 2.78a again
- File from T50116 was having totally different shadow between
  sample 1 and sample 32.

Use some more simplified version of CMJ hash which seems to give
nice randomized value which solves the correlation.

This commit will break all unit test files, but it's a bug fix
so perhaps OK to commit this.

This also fixes T41143: Sobol gives nonuniform noise

Proper science paper about hash function is coming.

Reviewers: brecht

Reviewed By: brecht

Subscribers: lukasstockner97

Differential Revision: https://developer.blender.org/D2385
2017-01-20 11:26:17 +01:00
5596f970be Fix T50075: Assert during debug render of hair_geom_transmission.blend 2017-01-20 11:26:16 +01:00
921e45d82b Cycles: Pass extra array size argument to builtin image pixels functions
This is a way to avoid possible memory corruption when render threads works
in parallel with UI thread.

Not guarantees complete safe, but makes things easier to check anyway.
2017-01-20 11:26:16 +01:00
d2affb1049 Fix T50104, Race condition in SVMShaderManager::device_update_shader 2017-01-20 11:26:16 +01:00
c3fd2b98ce Cycles: Avoid divisions by zero in volume sampling code
Was giving huge artifacts in the barber shop file here in the studio,

Maybe not fully optimal solution, but committing it for now to have
closer look later.
2017-01-20 11:26:16 +01:00
c61e68f289 Fix T50100: Cycles SeparateRGBNode Red socket defined wrong
Spotted by David (bocs), thanks!
2017-01-20 11:26:16 +01:00
b66d4f5eed Cycles: Fix strict compilation warnings 2017-01-20 11:26:16 +01:00
df6256a6ea Fix Cycles device backwards compatibility error if device type is unavailable. 2017-01-20 11:26:15 +01:00
ef28892654 Fix spelling in Cycles distance culling description. 2017-01-20 11:26:15 +01:00
1e57f6f957 Cycles: Fix strict compilation warnings
Should be no functional changes.
2017-01-20 11:26:15 +01:00
c1080ff73e Fix T50034: Blender changes processor affinity unauthorized 2017-01-20 11:26:15 +01:00
4ace7e1ebf Cycles: Fix re-definition of some functions on x32 arch 2017-01-20 11:26:15 +01:00
567c42bd22 Cycles: Another attempt to fix compilation on 32bit Linux 2017-01-20 11:26:15 +01:00
f4cd05082c Cycles: Attempt to fix 32bit buildbot builds after recent commit 2017-01-20 11:26:14 +01:00
4b7b9ded91 Cycles: Implement texture size limit simplify option
Main intention is to give some quick way to control scene's memory
usage by clamping textures which are too big. This is really handy
on the early production stages when you first create really nice
looking hi-res textures and only when it all works and approved
start investing time on optimizing your scene.

This is a new option in Scene Simplify panel and it acts as
following: when texture size is bigger than the given value it'll
be scaled down by half for until it fits into given limit.

There are various possible improvements, such as:

- Use threaded scaling using our own task manager.

  This is actually one of the main reasons why image resize is
  manually-implemented instead of using OIIO's resize. Other
  reason here is that API seems limited to construct 3D texture
  description easily.

- Vectorization of uchar4/float4/half4 textures.

- Use something smarter than box filter.

  Was playing with some other filters, but not sure they are
  really better: they kind of causes more fuzzy edges.

Even with such a TODOs in the code the option is already quite
useful.

Reviewers: brecht

Reviewed By: brecht

Subscribers: jtheninja, Blendify, gregzaal, venomgfx

Differential Revision: https://developer.blender.org/D2362
2017-01-20 11:26:14 +01:00
d77dcd5896 Cycles: Attempt to fix compilation error on ppc64el
There is some define conflict between system headers and clew,
so delay include of clew.h as much as possible.]

This is something which needed to be done in the code before
the refactor, hopefully such change will still work.
2017-01-20 11:26:14 +01:00
897261c01e Cycles: Don't shadow loop variable 2017-01-20 11:26:14 +01:00
0c4b812d2d Cycles: add basic backwards compatibility for device selection, move to System tab.
For the multi-GPU case users still have to reconfigure the devices they want to use.

Based on patch from Lukas Stockner.

Differential Revision: https://developer.blender.org/D2347
2017-01-20 11:26:14 +01:00
555e21d996 Cycles: refactor culling code into utility class. 2017-01-20 11:26:13 +01:00
59af4562dd Cycles: distance culling for objects.
This can be used together with camera culling to keep nearby objects visible in
reflections, using a minimum distance within which objects are visible. It is
also useful to cull small objects far from the camera.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2332
2017-01-20 11:26:13 +01:00
Dalai Felinto
a38a8497ef Cycles: Different noise seed for stereoscopic rendering (Fix #T50024)
Patch by Sergey Sharybin.
2017-01-20 11:26:13 +01:00
fcde51fd5d Fix T50001: auto tile size addon broken after Cycles GPU device changes.
Adds a get_num_gpu_devices() utility function for the addon to use.
2017-01-20 11:26:13 +01:00
bca4af7610 Cycles: Fix different noise pattern from fix in T49838:
No need to hash subframe == 0.
2017-01-20 11:26:13 +01:00
44e996745b Atomics: Make naming more obvious about which value is being returned 2017-01-20 11:26:11 +01:00
f24d420f16 Cycles: De-duplicate image loading functions
The code was templated already, so don't see big reason to have
3 versions of templated functions. It was giving some extra code
to maintain and in fact already had divergency for support of huge
image resolution (missing size_t cast in byte image loading).

There should be no changes visible by artists.
2017-01-20 11:25:53 +01:00
6832a18198 Fix T49904: Cycles standalone missing default generated texture coordinates. 2017-01-20 11:25:53 +01:00
feff2bfce4 Fix Cycles OSL compilation based on modified time not working. 2017-01-20 11:25:53 +01:00
a684d9375a Fix Cycles standalone not finding CPU device after recent changes. 2017-01-20 11:25:52 +01:00
78c855a370 Fix T49985: cycles standalone XML missing distant lights. 2017-01-20 11:25:52 +01:00
ff1b925ab3 Fix T49985: cycles standalone using wrong socket names for XML reading. 2017-01-20 11:25:52 +01:00
c40c888a52 Cycles: Add comments to endif directives
`kernel_path.h` and `kernel_path_branched.h` have a lot of conditional code and
it was kind of hard to tell what code belonged to which directive. Should be
easier to read now.
2017-01-20 11:25:52 +01:00
4b98b86654 Fix T49838: Noise randomization for frame should be done per interframes as well
Add subframe to the animated seed hash calculation.

Should be no difference for the regular files, only for cases when scene is
rendered from sequencer with a speed effect, which is not really a common thing.
2017-01-20 11:25:52 +01:00
0e9eeccf2e Cycles: Only use new light sample threshold for new files
This is a late follow-up commit to the light sample threshold changes which
caused difference in rendering all existing .blend files which is not something
we are happy about: it is fine to use new optimized defaults for new files, but
existing ones should always be rendering in the same way as they used to be.

Sorry for the inconveniece, but such thing should have been done to begin with.
If this setting was modified it will not be reset to zero.

Now all render tests should be passing again.

P.S. Also really annoying to bump subversion for such reasons, but currently we
don't have better way to achieve what we want.
2017-01-20 11:25:51 +01:00
f6926ea3f8 Fix compilation error when CUDA toolkit is not installed
After CUDA dynload changes having CUDA toolkit became required
in order to compile Cycles. This only happened due to wrong
default value to the option.
2017-01-20 11:25:29 +01:00
4a459704c0 Cycles: Remove device settings from performance tab
This was included in the commit by accident, it doesn't belong there.
2017-01-20 11:25:29 +01:00
f840239ee0 Cycles: Refactor Device selection to allow individual GPU compute device selection
Previously, it was only possible to choose a single GPU or all of that type (CUDA or OpenCL).
Now, a toggle button is displayed for every device.
These settings are tied to the PCI Bus ID of the devices, so they're consistent across hardware addition and removal (but not when swapping/moving cards).

From the code perspective, the more important change is that now, the compute device properties are stored in the Addon preferences of the Cycles addon, instead of directly in the User Preferences.
This allows for a cleaner implementation, removing the Cycles C API functions that were called by the RNA code to specify the enum items.

Note that this change is neither backwards- nor forwards-compatible, but since it's only a User Preference no existing files are broken.

Reviewers: #cycles, brecht

Reviewed By: #cycles, brecht

Subscribers: brecht, juicyfruit, mib2berlin, Blendify

Differential Revision: https://developer.blender.org/D2338
2017-01-20 11:25:29 +01:00
c89d8dd6cb Cycles: Fix T49952: Bad MIS sampling of backgrounds with single bright pixels
With this fix, using a MIS map resolution equal to the image size for closest imterpolation or twice the size for linear interpolation gets rid of all fireflies.
Previously, a much higher resolution was needed to get acceptable noise levels.
2017-01-20 11:25:29 +01:00
Martijn Berger
259d296918 cycles, cuDeviceComputeCapability is deprecated as of cuda 5.0 2017-01-20 11:25:28 +01:00
d812d54812 Cycles: Fix missing underscore in geom_object.h 2017-01-20 11:25:28 +01:00
73753072c2 Cycles: Fix OpenCL build error caused by light termination commit 2017-01-20 11:25:28 +01:00
e961684de5 Cycles: Fix T49901: OpenCL build error after recent light texture coordinate commit
Basically, the problem here was that the transform that's used to bring texture coordinates
to world space is either fetched while setting up the shader (with Object Motion is enabled) or
fetched when needed (otherwise). That helps to save ShaderData memory on OpenCL when Object Motion isn't needed.

Now, if OM is enabled, the Lamp transform can just be stored inside the ShaderData as well. The original commit just assumed it is.
However, when it's not (on OpenCL by default, for example), there is no easy way to fetch it when needed, since the ShaderData doesn't
store the Lamp index.

So, for now the lamps just don't support local texture coordinates anymore when Object Motion is disabled.
To fix and support this properly, one of the following could be done:
- Just always pre-fetch the transform. Downside: Memory Usage increases when not using OM on OpenCL
- Add a variable to ShaderData that stores the Lamp ID to allow fetching it when needed
- Store the Lamp ID inside prim or object. Problem: Cycles currently checks these for whether an object was hit - these checks would need to be changed.
- Enable OM whenever a Texture Coordinate's Normal output is used. Downside: Might not actually be needed.
2017-01-20 11:25:28 +01:00
Martijn Berger
74dc4ef556 Cycles standalone, compile fix UINT_MAX is not defined in device_cuda.cpp 2017-01-20 11:25:28 +01:00
8f8800bbbc Cycles: Deduplicate AO calculation
No functional changes.
2017-01-20 11:25:28 +01:00
927f84af07 Cycles: Fix OpenCL compilation with the new brick texture 2017-01-20 11:25:28 +01:00
44197cafaf Cycles: Style Fix: Light sampling threshold description 2017-01-20 11:25:28 +01:00
e5a86361af Cycles: Initialize the RNG state from the kernel instead of the host
This allows to save a memory copy, which will be particularly useful for network rendering.

Reviewers: sergey, brecht, dingto, juicyfruit, maiself

Differential Revision: https://developer.blender.org/D2323
2017-01-20 11:25:27 +01:00
feb4822346 Cycles: Add optional probabilistic termination of light samples based on their expected contribution
In scenes with many lights, some of them might have a very small contribution to some pixels, but the shadow rays are traced anyways.
To avoid that, this patch adds probabilistic termination to light samples - if the contribution before checking for shadowing is below a user-defined threshold, the sample will be discarded with probability (1 - (contribution / threshold)) and otherwise kept, but weighted more to remain unbiased.
This is the same approach that's also used in path termination based on length.

Note that the rendering remains unbiased with this option, it just adds a bit of noise - but if the setting is used moderately, the speedup gained easily outweighs the additional noise.

Reviewers: #cycles

Subscribers: sergey, brecht

Differential Revision: https://developer.blender.org/D2217
2017-01-20 11:25:27 +01:00
199d7dc70d Cycles: Add smoothing option to the Brick Texture
This option allows to create a smoother transition between Bricks and Mortar - 0 applies no smoothing, and 1 smooths across the whole mortar width.
Mainly useful for displacement textures.

The new default value for the smoothing option is 0.1 to give some smoothing that helps with antialiasing, but existing nodes are loaded with smoothing 0 to preserve compatibility.

Reviewers: sergey, dingto, juicyfruit, brecht

Reviewed By: brecht

Subscribers: Blendify, nutel

Differential Revision: https://developer.blender.org/D2230
2017-01-20 11:25:27 +01:00
e9211860b9 Fix T49846: OpenCL rendering compilation failure 2017-01-20 11:25:27 +01:00
5306621998 Cycles: Implement texture coordinates for Point, Spot and Area Lamps
When using the Normal output of the Texture Coordinate node on Point and Spot lamps, the coordinates now depend on the rotation of the lamp.
On Area lamps, the Parametric output of the Geometry node now returns UV coordinates on the area lamp.

Credit for the Area lamp part goes to Stefan Werner (from D1995).
2017-01-20 11:25:27 +01:00
468022403a Cycles: More workarounds for weird crashes on AVX2
Oh man, is it a compiler bug? Is it something we do stupid?

For now more crap to prevent crashes. During the conference will talk to
Maxyn about how can we troubleshoot such weird issues.
2017-01-20 11:25:27 +01:00
2768e623a9 Cycles: Another attempt to fix crashes on AVX2 processors
Basically don't use rcp() in areas which seems to be critical after
second look. Also disabled some multiplication operators, not sure
yet why they might be a problem.

Tomorrow will be setting up a full test with all cases which were
buggy in our farm to see if this fix is complete.
2017-01-20 11:25:26 +01:00
2b87d3b6cc Cycles: Fix compilation error of AVX2 kernel without SSE math 2017-01-20 11:25:26 +01:00
d00172217b Cycles: Completely disable transform SSE for now
Was causing issues on another frame.

On a tight schedule, disabling for now so artists are happy.

Still looking into root of the issue!
2017-01-20 11:25:26 +01:00
d6e01042b9 Cycles: Fix crashes after recent optimization commits
There is some precision issues for big magnitude coordinates which started
to give weird behavior of release builds. Some weird memory usage in BVH
which is tricky to nail down because only happens in release builds and GDB
reports all variables as optimized out when trying to use RelWithDebInfo.

There are two things in this commit:

- Attempt to make vectorized code closer to original one, hoping that it'll
  eliminate precision issue.
  This seems to work for transform_point().
- Similar trick did not work for transform_direction() even tho absolute
  error here is much smaller. For now disabled that function, need a more
  careful look here.
2017-01-20 11:25:26 +01:00
2956203221 Cycles: Fix for fix (tm)
Sorry guys, for some reason read the expression back-to-front
and did wrong fix :S
2017-01-20 11:25:26 +01:00
c1d25de806 Cycles: Fix typo in previous commit for BVH improvements 2017-01-20 11:25:26 +01:00
98bdc56e4e Cycles: Enable SSE math optimization for AVX kernels
This gives about 5% speedup for AVX processors.

Benefit of such optimization on other microarchitectures is still
under investigation.
2017-01-20 11:25:25 +01:00
cdf556d974 Cycles: Use new SSE version of offset calculation for all QBVH flavors
Gives up to ~1% speedup again.

While it seems to be small, still nice since the code now is actually more
clean that it used to be before.
2017-01-20 11:25:25 +01:00
8ea5cbd89b Cycles: Move QBVH near/far offset calculation to an utility function
Just preparing for new optimization to be used in all traversal implementation.

Should be no measurable difference.
2017-01-20 11:25:25 +01:00
612604f23a Cycles: BVH-related SSE optimization
Several ideas here:

- Optimize calculation of near_{x,y,z} in a way that does not require
  3 if() statements per update, which avoids negative effect of wrong
  branch prediction.

- Optimization of direction clamping for BVH.

- Optimization of point/direction transform.

Brings ~1.5% speedup again depending on a scene (unfortunately, this
speedup can't be sum across all previous commits because speedup of
each of the changes varies from scene to scene, but it still seems to
be nice solid speedup of few percent on Linux and bigger speedup was
reported on Windows).

Once again ,thanks Maxym for inspiration!

Still TODO: We have multiple places where we need to calculate near
x,y,z indices in BVH, for now it's only done for main BVH traversal.
Will try to move this calculation to an utility function and see if
that can be easily re-used across all the BVH flavors.
2017-01-20 11:25:25 +01:00
4db44cee9f Cycles: Avoid branching in SSE version of intersection pre-calculation
Similar to the previous commit, avoid negative effect of bad branch prediction.

Gives measurable performance up to ~2% in tests here.

Once again, thanks to Maxym Dmytrychenko!
2017-01-20 11:25:25 +01:00
c5f4837603 Cycles: Implement SSE-optimized path of util_max_axis()
The idea here is to avoid if statements which could cause wrong
branch prediction.

Gives a bit of measurable speedup up to ~1%. Still nice :)

Inspired by Maxym Dmytrychenko, thanks!
2017-01-20 11:25:25 +01:00
10e583533b Cycles: Add AVX2 path to subsurface triangle intersection
Similar to regular triangle intersection case. Gives about 3% speedup rendering
SSS object on my desktop,

Question: how to avoid such a code duplication in a nice way without speed loss?
2017-01-20 11:25:24 +01:00
3a142ec55a Cycles: Cleanup, style 2017-01-20 11:25:23 +01:00
Hristo Gueorguiev
e2dd5f15d9 Cycles: OpenCL 3d textures support.
Note that volume rendering is not supported yet, this is a step towards that.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2299
2017-01-20 11:25:03 +01:00
7bddb79f49 Cycles: Fix another OpenCL logging issue
Previously an error message would be printed whenever the OpenCL build produced output.
However, some frameworks seem to print extra information even if the build succeeded, so now the actual returned error is checked as well.
When --debug-cycles is activated, the build output will always be printed, otherwise it only gets printed if there was an error.
2017-01-20 11:25:03 +01:00
3778475c61 Fix T49630: Cycles: Swapped shader and bake kernels
The problem here was, as the title says, that the two kernels were swapped.
Since shader evaluation is only used for building the samling map when World MIS is enabled, rendering without it would still work fine, although baking also was broken.
2017-01-20 11:25:03 +01:00
edac0e7b17 Cycles: Improve OpenCL kernel compilation logging
The previous refactor changed the code to use a separate logging mechanism to support multithreaded compilation.
However, since that's not supported by any frameworks yes, it just resulted in bad logging behaviour.
So, this commit changes the logging to go diectly to stdout/stderr once again by default.
2017-01-20 11:25:03 +01:00
290e37dce1 Cycles: Disable optimization of operator / for float3
This was giving some speedup but made intersection tests to fail
from watertight point of view.

Needs deeper investigation, but need to quickly get it fixed for
the studio.
2017-01-20 11:25:03 +01:00
f9b0c10d04 Fix build error with WITH_CYCLES_NATIVE_ONLY and recent AVX2 changes. 2017-01-20 11:25:03 +01:00
87ca259433 Cycles: Use const reference for register variables in non-OpenCL code
This is something tested by @LazyDodo and suggested by Maxym to make
MSVC happier.
2017-01-20 11:25:03 +01:00
73bae90620 Cycles: Use more SSE intrinsics for float3 type
This gives about 5% speedup on AVX2 kernels (other kernels still
have SSE disabled for math operations) and this solves the slowdown
of koro scene mention in the previous commit.

The title says it all actually. This commit also contains
changes to pass float3 as const reference in affected functions.

This should make MSVC happier without breaking OpenCL because it's
only done in areas which are ifdef-ed for non-OpenCL.

Another patch based on inspiration from Maxym Dmytrychenko, thanks!
2017-01-20 11:25:02 +01:00
c01d7c8a8f Cycles: Implement AVX2 version of triangle_intersect
This commit basically vectorizes existing code using AVX2 instructions
(without modifying algorithm itself). This gives quite nice speedups:

  BMW:        -8%
  Classroom:  -5%
  Cat:        -5%
  Koro:       +1%
  Barcelona:  -8%

That's on Linux machine, reported performance improvement on Windows
goes up to 20%.

Not currently sure why Koro is somewhat slower because it mainly uses
curve intersection tests, could be a time noise? Or osmething with the
cache utilization perhaps? In any case speedup in other scenes makes
me thinking that current state is acceptable for initial implementation.

This is again inspired by Maxym Dmytrychenko.
2017-01-20 11:25:02 +01:00
804d4719c6 Cycles: Add new avxf vectorized data type
Based on existing ssef data type and to my knowledge it's also what happens in
Embree nowadays.

Inspired by Maxym Dmytrychenko and required for the upcoming triangle
intersection commit.

Hopefully the copyright message is correct.
2017-01-20 11:25:02 +01:00
19203b42ed Cycles: Enable SSE options of math module for AVX2 kernels
Currently this does not give measurable difference, but is required
ground work for some upcoming further optimization of AVX2 kernels.
2017-01-20 11:25:02 +01:00
dff65a0e6f Cycles: Cleanup, style 2017-01-20 11:25:02 +01:00
3d7eb44707 Cycles: Split device_opencl.cpp into multiple files for easier maintenance
There are no user-visible changes, just some internal restructuring.

Differential Revision: https://developer.blender.org/D2231
2017-01-20 11:25:02 +01:00
acd02c7848 [Windows/Cycles/Clang] Fix compilation error with clang-cl on windows 2017-01-20 11:25:02 +01:00
2482bb1d72 Cycles: implement partial constant folding for exponentiation.
This is also an important mathematical operation that can be folded
if it is known that one argument is a certain constant. For colors
the operation is provided as a Gamma node.

The SVM Gamma node needs a small fix to make it follow the 0 ^ 0 == 1
rule, same as the Power node, or the Gamma node itself in OSL mode.

Reviewers: #cycles

Differential Revision: https://developer.blender.org/D2263
2017-01-20 11:25:01 +01:00
7ef3dfef6e Cycles: Cleanup, indentation 2017-01-20 11:25:01 +01:00
e716f10ba9 Cycles: Use correct light sampling PDF for MIS calculation with Branched Path Tracing
The light sampling functions calculate light sampling PDF for the case that the light has been randomly selected out of all lights.
However, since BPT handles lamps and meshlights separately, this isn't the case. So, to avoid a wrong result, the code just included the 0.5 factor in the throughput.

In theory, however, the correction should be made to the sampling probability, which needs to be doubled. Now, for the regular calculation, that's no real difference since the throughput is divided by the pdf.
However, it does matter for the MIS calculation - it's unbiased both ways, but including the factor in the PDF instead of the throughput should give slightly better results.

Reviewers: sergey, brecht, dingto, juicyfruit

Differential Revision: https://developer.blender.org/D2258
2017-01-20 11:25:01 +01:00
e04cc46b83 Cycles: Cleanup, whitespace 2017-01-20 11:25:01 +01:00
35346dc8e7 Cycles: Make code more uniform across two versions of shadow_blocked()
Just to make it easier to research ways of possible code de-duplication.
2017-01-20 11:25:01 +01:00
3f4bac1fe1 Cycles: Remove out of date comment 2017-01-20 11:25:01 +01:00
a27dd4bf85 Cycles: Make regular bvh traversal functions close to each other 2017-01-20 11:25:00 +01:00
2f2849fca8 Cycles: Re-group ifdef so we check for particular feature only once 2017-01-20 11:25:00 +01:00
1b9ea14782 Cycles: Avoid conversion from bool to uint 2017-01-20 11:25:00 +01:00
518f88efaa Cycles: Cleanup code style in split kernel 2017-01-20 11:25:00 +01:00
3cc7567607 Cycles: More tweaks to make specialized BVH traversal matching 2017-01-20 11:25:00 +01:00
a9b92fc29b Cycles: Avoid redundant intersection pre-calculation 2017-01-20 11:25:00 +01:00
c526932b31 Cycles: Cleanup, sync some comments across different traversal 2017-01-20 11:24:59 +01:00
85225c56b5 Cycles: Cleanup, always use parenthesis
Makes it simpler to compare different traversal algorithms.
2017-01-20 11:24:59 +01:00
92e70d7d8f Revert "Cycles: Tweak empty boundbox children"
This reverts commit ecbfa31caa.

Original commit broke logic in nodes re-fitting. That area can
access non-existing children momentarely. Not sure what would
be best solution here, for now simply reverting the change/
2017-01-20 11:24:59 +01:00
9c15fad5c5 Cycles: Deduplicate light pass code 2017-01-20 11:24:59 +01:00
9f4fe1df8d Cycles: Stop lamp sampling if the lamp isn't visible
Both spot and area light have large areas where they're not visible.
Therefore, this patch stops the light sampling code when one of these cases (outside of the spotlight cone or behind the area light) occurs, before the lamp shader is evaluated.
In the case of the area light, the solid angle sampling can also be skipped.

In a test scene with Sample All Lights and 18 Area lamps and 9 Spot lamps that all point away from the area that the camera sees, render time drops from 12sec to 5sec.

Reviewers: brecht, sergey, dingto, juicyfruit

Differential Revision: https://developer.blender.org/D2216
2017-01-20 11:24:59 +01:00
f1fe4eb3d1 Cycles: Also support the constant emission speedup for mesh lights
Reviewers: brecht, sergey, dingto, juicyfruit

Differential Revision: https://developer.blender.org/D2220
2017-01-20 11:24:59 +01:00
da234142b8 Cycles: Implement threaded SVM nodes compilation
The title says it all actually. From tests with barber shop scene here
gives 2-3x speedup for shader compilation on my oldie i7 machine. The
gain is mainly due to textures metadata query from jpeg files (which
seems to requite de-compression before metadata can be read). But in
theory could give nice improvements for scenes with huge node trees
as well (i'm talking about node trees of complexity of fractal which
we had reports about in the past).

Reviewers: juicyfruit, dingto, lukasstockner97, brecht

Reviewed By: brecht

Subscribers: monio, Blendify

Differential Revision: https://developer.blender.org/D2215
2017-01-20 11:24:58 +01:00
78b472bfa9 Cycles: Tweak empty boundbox children
The idea here is to make assert failure to fail sooner on an incorrect
node address rather than later with stack overflow.
2017-01-20 11:24:58 +01:00
a1c8b3e886 Cycles: Fix compilation error after recent commits 2017-01-20 11:24:58 +01:00
ad0d00e551 Cycles: Use XDG's .cache folder for cached kernels
Basically just moves cached kernels from ~/.config/blender/BLENDER_VERSION to
~/.cache/cycles/kernels. This has following benefits:

- Follows XDG specification more closely,
  not as if it's totally crucial or measurable by users, but still nice.

- Prevents unexpected sizes of config folder, makes disk space used in more
  predictable for users way.

- Allows to share kernels across multiple Blender versions,
  which makes it easier debugging at the times close to release.

- "Copy Previous Settings" operator will no longer be copying possibly
  gigabytes of cached kernels, which used to lead to really nast disk usage
  and annoying delays of copying settings.

- In the future we can have some smart logic to clear old unused cached
  kernels.

Currently only done for Linux and OSX. Windows still follows old "cache"
folder logic, but it's not really important for now because we don't
support kernel compilation on this platform yet.

Reviewers: dingto, juicyfruit, brecht

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2197
2017-01-20 11:24:58 +01:00
c9adc55801 Cycles: Add overall timing log to SVNShaderManager 2017-01-20 11:24:58 +01:00
6ba920dec1 Cycles: Deduplicate QBVH node packing across BVH build and refit 2017-01-20 11:24:58 +01:00
e439892b14 Cycles: Don't run full shader evaluation for constant emission lamps
Most of the time, Lamps in Cycles are just a constant emission closure, no texturing etc. Therefore, running a full shader evaluation is wasteful.
To avoid that, Cycles now detects these constant emission shaders and stores their value in the lamp data along with a flag in the shader.
Then, at runtime, if this flag is set, the lamp code just uses this value and only runs the full shader evaluation if it is neccessary.

In scenes with a lot of lamps and with "Sample all direct/indirect" enabled, this saves up to 20% of rendering time in my tests.

Reviewers: #cycles

Differential Revision: https://developer.blender.org/D2193
2017-01-20 11:24:57 +01:00
c9dd9fceaa Cycles: Revert cleanup commit, will make it easier to cherry-pick 2017-01-20 11:02:20 +01:00
d159161155 retain existing creases, added inner crease and interpolate edge data with carve now 2017-01-08 14:31:01 +01:00
0bc63068ce crash fix for particle grid emission, do not allow to re-distribute particles there... 2017-01-05 01:39:28 +01:00
32e56f5d55 fix when using inner vertexgroup, weights of other vgroups on the same mesh were deleted by accident then 2017-01-03 00:12:18 +01:00
039be9e3c9 fracture modifier RNA refactor, outsourced FM RNA code and python API code to separate files 2016-12-31 00:33:57 +01:00
cde4150d7b fix for crash with physical rough edges (via addon)
caused by not checking whether objects in rigidbody group are rigidbodies, actually.
2016-12-30 17:10:25 +01:00
cbdb75682d let weights fade out at breaking locations with dynamic fracture 2016-12-23 20:25:00 +01:00
809d1aa1e0 transfer all speeds with dynamic fracture now, not only those above the sleep threshold 2016-12-23 20:24:08 +01:00
4916e0b79b particles, only suppress unborn particles when density vgroup is empty / has zero weight 2016-12-23 20:23:28 +01:00
f16d7f481f fix for external FM mode, take object locations into account as centroids for physics shapes, too 2016-12-22 03:05:34 +01:00
420ea4423e particle system: allow changing vgroups over time, suppress emission on empty assigned density vgroups 2016-12-22 00:31:42 +01:00
229688fee1 fix attempt for avoiding unintentional dissolve of all constraints in dynamic fracture 2016-12-22 00:25:24 +01:00
90d644fca4 fix : inner vertexgroups created with fractal boolean now too 2016-12-22 00:24:32 +01:00
751d2354c2 crash fix with FM and forcefields 2016-12-19 22:34:49 +01:00
41ae74df12 added some random rotation for fast bisect, to reduce parallel cuts 2016-12-16 00:48:30 +01:00
025aae4413 support for keeping edge data in fracture modifier (like sharp edges) 2016-12-16 00:15:12 +01:00
a5047171b9 inter-objects constraint objects can now determine which shards (closest) will be connected to the other object 2016-12-15 18:34:50 +01:00
ae9d247ea5 small fix for compounds, new collision suppression is disabled for them now
it caused wrong behavior - one shard always fell off unintendedly.
2016-12-15 00:30:40 +01:00
e5fc4218c7 fix for constraint loop detection (meshislands indirectly connected by a loop should get the same constraint index now) 2016-12-14 01:40:05 +01:00
2984406082 limit the collision check to objects which are actually constrained (whether disabled or not)
additionally take value of "disable collisions flag" into account, omit check if constrainted objects shall collide
2016-12-14 00:27:47 +01:00
f39585c387 hrm forgot something in last commit 2016-12-13 23:49:04 +01:00
a0d52d8e02 further attempt to suppress "unnecessary" collisions when constraints are intact 2016-12-13 23:46:12 +01:00
be4bd5ee69 optimization attempt to suppress collisions among partially constrained objects 2016-12-13 17:10:10 +01:00
d74d156c96 fix for rotational and splinter (with splitshards) issues in dynamic fracture 2016-12-13 11:25:11 +01:00
ef78283dd3 fix attempt for getting better fractal details, using bbox center and a smaller fractal plane now 2016-12-12 22:11:27 +01:00
c01dc55212 crash fix for having less shards than connections in connected fractured objects 2016-12-12 22:08:52 +01:00
3d7b6b6b34 crash fix attempt for connected fm objects 2016-12-12 20:43:36 +01:00
30fc776a68 improvements for inter-object constraints and fix for dissolve constraint when not kinematic (needs to be triggered still) 2016-12-12 14:24:04 +01:00
88fc1dd846 first attempt of inter-object constraints with fracture modifier, via regular constraint / connect operator 2016-12-12 00:26:25 +01:00
0749338492 added new trigger settings: propagate trigger, dynamic trigger and constraint dissolve
propagate trigger allows to propagate impulses across different FM objects, dynamic trigger can start a dynamic fracture independent from force, and constraint dissolve means that all constraints of activated shards will be disabled immediately
2016-12-11 19:44:01 +01:00
10d2c861dd fix for constraint calculation, transform of meshisland centroid was calculated incorrectly 2016-12-07 22:53:59 +01:00
069be54c87 speed optimization for fractal boolean, about 10x (note, Inner UV might not work with fractal still)
before there was a regression, 10 shards with default settings ~ 7 secs, now 100 in same time (left uv boxpacking out)
2016-12-06 23:30:18 +01:00
da2e66e106 small typo fix for mousebased fracture, used wrong index variable name 2016-12-01 23:50:58 +01:00
4777b17ec5 fix for physics visualization in FM, strings for constraint identifiers were not displayed properly under windows 2016-12-01 11:32:02 +01:00
2b25fe3e1c fix for possibly different object / shard order after loading a baked simulation 2016-11-28 22:45:49 +01:00
77599a6be0 fix for crash of loading files with split shards or island detection in fracture 2016-11-28 00:52:46 +01:00
1eabe30d34 stability fix for dynamic fractal, use triangulated cutter planes now and ensure they go through the shard's centroid 2016-11-26 11:47:10 +01:00
672c7d72c2 fixes / cleanup after static analysis of code which showed some potential issues 2016-11-25 21:00:33 +01:00
5148fd7f14 typo fix 2016-11-25 19:04:08 +01:00
8dfff7d339 partial crash fix for dynamic fractal fracture, can still crash in carve and bullet (todo) 2016-11-25 18:19:27 +01:00
509ffe1002 fix for missing omp condition evaluation (should work for boolean now only, because it causes errors with other algorithms) 2016-11-24 19:42:47 +01:00
b472f86804 bugfix / performance fix and new option "constrained collison"
bugfix: switching from kinematic to simulated should work now, performance improvements with dynamic fracture,
new option just exposes the disable collision flag to FM (works inverted here, enable it to let constrained objects collide, disable for default behavior)
2016-11-20 16:35:24 +01:00
ed840c8efb fix, let the FM shards respond to animated gravity in scene 2016-11-07 21:26:59 +01:00
f5da9bc306 corrected centroid calculation by using exact center of mass centroid 2016-11-07 18:10:57 +01:00
d7651d65de fix for crash when appending node groups if Fracture Modifier is active and frame > 1 2016-11-02 20:40:31 +01:00
2d1c068048 argh, missed some default setting for FM for grease pencil edge mode, before this fix no fracture at all was performed, and added bmesh tool flag for grease pencil fracture, too 2016-11-02 19:44:14 +01:00
b674ffb6da Merge remote-tracking branch 'refs/remotes/origin/blender-v2.78-release' into fracture_modifier
Conflicts:
	source/blender/makesrna/intern/rna_modifier.c
2016-10-26 19:30:29 +02:00
e8299c8100 Cycles: Don't use guarded vector for statically initialized data
This will confuse hell of a guarded allocators because it is possible
to have allocation happened prior to Blender's guarded allocator is
fully initialized.

This was causing crashes and assert failures when running blender
with fully guarded memory allocator.
2016-10-24 14:20:27 +02:00
21bf863934 Cycles: Fix shadowing variable which also causes use of uninitialized variable
Was causing wrong aperture for panorama cameras.

Seems to be a regression in 371d357.
2016-10-24 14:05:55 +02:00
0b734f0b59 Fix: Grease Pencil palettes were missing a RNA path callback 2016-10-24 13:51:57 +02:00
759b5fb2a6 Fix Cycles address space OpenCL error after recent fix. 2016-10-24 13:46:45 +02:00
f0adb875cf Cycles: Fix static initialization order fiasco
Initialization order of global stats and node types was not strictly
defined and it was possible to have node types initialized first and
stats after that. This will zero out memory which was allocated from
the statistics causing assert failure when de-initializing node types.
2016-10-24 13:43:55 +02:00
f55221e0a1 Cycles: Fix uninitialized variable from the previous commit 2016-10-24 12:55:05 +02:00
59689bed7b Blender 2.78: Point submodules to a new hash 2016-10-24 12:40:14 +02:00
20e54c99d2 Cycles: Remove explicit std:: from types where possible
We have our own abstraction level on top of the STL's implementation.
This commit will guarantee our tweaks are used for all cases.
2016-10-24 12:39:15 +02:00
faaf033d36 Blender 2.78: Port style cleanup from Cycles
Kinda nice to have official release code to be really clean.
2016-10-24 12:38:33 +02:00
66ed7d7566 Fix T49818: Crash when rendering with motion blur
It was possible to have non-initialized unaligned BVH split
to be used when regular BVH split SAH was inf. Now we ensure
that unaligned splitter is only used when it's really initialized.

It's a regression and should be in 2.78a.
2016-10-24 12:34:02 +02:00
a80104fb31 Cycles: Cleanup, spaces 2016-10-24 12:34:02 +02:00
452d43b1c8 Fix T49827L Crash linking material while in Material viewport shading mode
Material linking might and does change the way how drawObject is calculated
but does not tag drawObject for recalculation in any way.

Now use dependency graph to tag draw object for reclaculation. Currently do
this using OB_RECALC_DATA taq since tagging is not very granular yet. In the
future we can introduce ore granular tagging in the new dependency graph
easily.

Simple and safe for 2.78a.
2016-10-24 12:34:02 +02:00
602b2dbd8c Fix mistake in BKE_mesh_new_from_object handling of materials in MetaBall case.
Typo, spoted by Coverity scan.

To be backported to 2.78a.
2016-10-24 12:34:01 +02:00
4c94e327a2 Fix T49750: Cycles wrong ray differentials for perspective and stereo cameras. 2016-10-24 12:34:01 +02:00
7b311c07ee Fix T49656: Crash when starting playback while using JACK audio with A/V sync
When ED_screen_animation_play is called from wm_event_do_handlers,ScrArea *sa = CTX_wm_area(C); is NULL in ED_screen_animation_timer.
Informing the audio system in CTX_data_main_set, that a new Main has been set.
2016-10-24 12:34:01 +02:00
1bcddea00e Fix T49764: Audio strips crackle when animating the volume
- Implemented linear interpolation for volume changes in the software
mixer.
- Using this in the software device.
2016-10-24 12:34:01 +02:00
e1cf002ee6 Fix T49789: Compositor mix node interpolation bug 2016-10-24 12:34:01 +02:00
dac53963a8 Fix T49797: Exception from scene update handler might leak external engine descriptors
This was causing memory leaks in Cycles.

Some more detailed information in the comment in the code.

Seems to be safe and nice enough for 2.78a.
2016-10-24 12:34:01 +02:00
53cbda0f7f Fix T49793 : Fix enabling SSE2 globally for msvc.
When feeding msvc both /arch:sse2 and /arch:sse it's not smart enough to pick the best option, just goes with the last option
2016-10-24 12:34:01 +02:00
Scott Wu
cb44a3e5d7 Cycles: use near clipping distance in panorama camera.
Reviewed By: sergey, brecht, dfelinto

Differential Revision: https://developer.blender.org/D1952
2016-10-24 12:34:01 +02:00
07c886e976 Blender 2.78a release: Use proper "a' on the splash 2016-10-19 16:56:44 +02:00
2e77ad7f99 Blender 2.78a release: Update addons submodule hash 2016-10-19 15:16:04 +02:00
3da4560143 Fix T49775: Appending data with internal dependency cycles prevents correct clearing of linked data-blocks.
This is not a simple fix, but imho still needs to be backported to 2.78a...
2016-10-19 14:53:52 +02:00
4d043db0db [windows] Create A Blender Desktop Shortcut in the msi installer , fixes T49522 2016-10-19 14:27:30 +02:00
44372d6441 Fix T49722: Appending Bug (Groups).
One day we'll have to reconsider why some many 'real' ID usages are not
refcounting... :(

To be backported to 2.78a.
2016-10-19 14:27:28 +02:00
50751d62e9 Fix T49738: Hair Add Brush doesn't work
the issue was caused by wrong default value for brush particle count
which was clamped on display from 0 to 1. This is technically a regression
but how to port this to 2.78a?
2016-10-19 14:27:08 +02:00
a6220f459b Fix T49746: crash loading user preferences with missing operators. 2016-10-19 14:26:42 +02:00
Chase Willden
8030c4832a Fix assert in the wrong place, should be moved earlier to do anything.
Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2304
2016-10-19 14:26:42 +02:00
Julian Eisel
00d08c909d Fix missing outliner redraw when adding VSE strip
Needed for outliner "Sequence" display mode.
2016-10-19 14:26:42 +02:00
d1f5c0fe48 Fix T49571: 2d stabilize keys not visible in the Graph Editor and Dope Sheet 2016-10-19 14:26:42 +02:00
dacb53ff71 Fix T49601: Material menu length problem.
Regression from rB69b66d549bcc8, was supposed to be non-functionnal
change, so not sure why search menu was reduced here? For now, restore
to 2.77 width.
2016-10-19 14:26:42 +02:00
e6d9b15ab3 Fix T49646: Switching from large to small image can get stuck zoom at max zoom distance.
Allow for zooming in at max zoom distance.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D2291
2016-10-19 14:26:42 +02:00
3fb0c1b8e7 Fix T49534: 2.78 Wrong texture scaling in material viewport
Seems to be a bug in original implementation of a830280: code was always
using tangent space instead of UV map because it had the same name. Now
prefer UVMap over tangent because this is how Cycles works. At least it's
closer to.

Not sure it the save+reload issue is still relevant after this fix, that
needs to be double-checked.

Thanks @dfelinto for looking into the report and simplifying the case.

Should be included into 2.78a.
2016-10-19 14:26:42 +02:00
fd9aa06440 Fix OLD pre-git links in the API, add missing factory-startup option to blender executions.
Reviewers: mont29

Reviewed By: mont29

Tags: #bf_blender, #python, #infrastructure:_websites

Differential Revision: https://developer.blender.org/D2290
2016-10-19 14:26:41 +02:00
03f935961a Fix T49635: column_flow Layout - last column is too small.
Column flow layout was abuse ui_item_fit in a weird way, which was
broken for last column items.

Now rather use own code, which basically spread available width as
equally as possible between all columns.
2016-10-19 14:26:41 +02:00
15134cf227 Cleanup: UI layout: remove unsed and confusing parameter.
Things are complicated enough like that, no need to add useless noise on
top of it!
2016-10-19 14:26:41 +02:00
106ff0df99 Normal edit modifier: Fix relation builder for the new dependency graph 2016-10-19 14:26:41 +02:00
7ab972fd63 Ammend to rB00dc0666b3fe: forgot to fix boid->ground of first particle.
This code is confusing, such dirty details should not sneak out of
particles' own private code. :(
2016-10-19 14:26:41 +02:00
97bba76e8c Fix T49631: radial control operators not using DPI properly. 2016-10-19 14:26:41 +02:00
10598c084e Fix T49640: Cycles constant folding incorrect for texture coordinates. 2016-10-19 14:26:41 +02:00
c9b5253cfc Fix T49636: material draw mode crash with displacement and missing group input node. 2016-10-19 14:26:41 +02:00
2002334813 Cycles: Get rid of ifdef-ed noinline policy 2016-10-19 14:26:41 +02:00
b42e4c3c40 Cycles: Fix use of uninitialized variable in SSS
When ray hits curve segment with SSS shader it was possible to have
uninitialized hit_P variable used for sampling.

Seems that was a reason of our headache of difference between AVX2
and SSE4 render results here, so now we can revert all the nasty
ifdef-ed inline policies.
2016-10-19 14:26:41 +02:00
9d4e3b0e63 Fix T49622: Grease pencil not rendering out of VSE 2016-10-19 14:26:40 +02:00
4736664da6 Fix T49502: file browser on OS X not highlighting external drives. 2016-10-19 14:26:40 +02:00
8ebc7565e7 Fix T49629: Graph editor normalize function doesn't work on f-curves with a constant key value
Technically it is a regression in behavior and should be 2.78a.
2016-10-19 14:26:40 +02:00
012bbce453 Make console message more clear for --scene argument 2016-10-19 14:26:40 +02:00
be254b52dc Fix T49623: Immediately crash trying to render attached file in Cycles
Original fix in this area was not really complete (but was the safest at
the release time). Now all the crazy configurations of slots going out
of sync should be handled here.
2016-10-19 14:26:40 +02:00
cdedd082f3 Fix viewport camera gets out of sync in certain cases
It was possible to have two viewports opened and start using Ctrl-0
to make different objects an active camera for the viewport. This
worked fine for viewports which had decoupled camera from the scene,
but if viewport was locked to scene camera it was possible to run into
situation when two different viewports are locked to scene camera but
had different v3d->camera pointers.
2016-10-19 14:26:40 +02:00
880ebfff58 Fix T49609: Point density textures: vertex colors are not properly averaged in BI
Nice to have in 2.78a, though not a regression.
2016-10-19 14:26:40 +02:00
29fdcbbf9f Fix T49608: runtime-only particle's boid->ground Object pointer was left dangling to invalid value in read code... 2016-10-19 14:26:40 +02:00
cb6c43b61c Fix a few compile errors with C++11 on macOS. 2016-10-19 14:26:40 +02:00
4dbcbf5ba9 BLI_task: fix case were some pool could work in more threads than allowed.
We were checking for number of tasks from given pool already active, and
then atomically increasing it if allowed - this is not correct, number
could be increased by another thread between check and atomic op!

Atomic primitives are nice, but you must be very careful with *how* you
use them... Now we atomically increase counter, check result, and if we
end up over max value, abort and decrease counter again.

Spotted by Sergey, thanks!
2016-10-19 14:26:40 +02:00
117329ae6d Cycles: Fix OpenCL split kernel compilation after recent CUDA 8 performance fix 2016-10-19 14:26:39 +02:00
6601b4cbdc Datablock management: remove 'proxy_from' pointer from 'is ID used' checks.
Pretty much same reason as for the 'from' pointer of shapekeys - runtime
data creating loops and 'ghost' dependencies between datablocks.

We need to handle them in cases like remapping, but whall not take them
into account to check dependencies between datablocks... :/
2016-10-19 14:26:39 +02:00
02eec191fb Fix T49595: bpy - negative skin_vertices radius crashes Blender
This is unsigned value (negative radius does not have much sense anyway!).
2016-10-19 14:26:39 +02:00
Julian Eisel
2525c4e129 Fix wrong separator line width after drawing vec icon
Was visible in Dynamic Context Menu add-on.
2016-10-19 14:26:39 +02:00
0d1bc587fa Fix T49523: very slow normal map tangent computation for rendering in 2.78. 2016-10-19 14:26:39 +02:00
e65e5045de Fix T49501: Animations imported via alembic render with wrong or no motion blur 2016-10-19 14:26:39 +02:00
b9c996e16b [msvc] make.bat, no need to set the cuda path at all, cmake will figure it out on it's own. 2016-10-19 14:26:39 +02:00
96ac3bd4bf [msvc] make.bat remove mixed cuda 7.5/8.0 build for release since all kernels can now be properly build with 8.0 2016-10-19 14:26:39 +02:00
1d36092627 Cleanup: Update links to online py API doc, and remove old commented stuff. 2016-10-19 14:26:39 +02:00
b8194a52a0 Fix T49553: Blender 2.78 crashes when File->Data Previews ->Refresh Datablock Previews
New recursive iteration over IDs in BKE_library_foreach_ID_link() was
broken by the infamous nodetree case. We cannot really recusively call
this function in that case, so better to deffer handling of
non-datablock NodeTrees as if real IDs here.

Also fixed initial ID not being stored as handled, in rare cases this
could also lead to infinite looping.

To be backported to 2.78a.
2016-10-19 14:26:39 +02:00
f87a81afb4 Cycles CUDA: make CUDA 8.0 the officially supported version for all platforms. 2016-10-19 14:26:39 +02:00
fd0dea585c Fix Cycles CUDA performance on CUDA 8.0.
Mostly this is making inlining match CUDA 7.5 in a few performance critical
places. The end result is that performance is now better than before, possibly
due to less register spilling or other CUDA 8.0 compiler improvements.

On benchmarks scenes, there are 3% to 35% render time reductions. Stack memory
usage is reduced a little too.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D2269
2016-10-19 14:26:38 +02:00
Julian Eisel
4d14bd10c0 Fix memory leak caused by unknown opeartor of keymap item 2016-10-19 14:26:38 +02:00
4640bf890e Fix T49548: Entering Cycles Rendered Viewport Unlinks Material from Objects.
We *always* want to increase mat user count when from Object (and not
Data), because in that case we are moving mat from object to temp
generated mesh, material can never be 'borrowed' in that case.

To be backported to 2.78a
2016-10-19 14:26:38 +02:00
Julian Eisel
e145990fdd Fix missing operator-type registration
Removed in a7dbc0704f, but only should've removed default keymap entry.
2016-10-19 14:26:38 +02:00
Julian Eisel
11120c2981 Fix T49506: Remove unused File Browser theme settings
If I didn't miss anything these are indeed not used. Old themes should still work (will only print info on redundant theme defines into console), but updated non-contrib themes already.
2016-10-19 14:26:38 +02:00
07508c8b93 Fix missing new eyedropper keymap entry in keyconfig_utils.py
Missing from rBe9bcdcdbbd91d9.
2016-10-19 14:26:38 +02:00
e96e66b05b Fix T49520: broken vertex colors in the game engine. 2016-10-19 14:26:38 +02:00
52e601f0c6 [Fix unreported bug] Snap align with normal was not working in derivade mesh
The `use_snapp_align_rotation` option was using only the first vertex
2016-10-19 14:26:38 +02:00
01b71b564b [msvc] make.bat - Fix:msbuild platform wasn't set when the architecture was auto detected. 2016-10-19 14:26:38 +02:00
9fea90ba36 Fix T49502: file browser on OS X not highlighting system folders and bookmarks. 2016-10-19 14:26:38 +02:00
4a8c43d756 [MSVC] Make.bat updates.
- Explicitly specify the platform for msbuild, to facilitate builds with just the Visual C++ Build Tools installed.
- When vs2013 is not found, try looking for 2015 as a fallback
- Clear up any batch variables that might have been set from previous runs
2016-10-19 14:26:37 +02:00
4da266f48c Fix wrong Cycles GLSL pointiness, still not supported but should be neutral 0.5. 2016-10-19 14:26:37 +02:00
90e1adabba Fix MSVC compiler warning due to using */* to start comment. 2016-10-19 14:26:37 +02:00
02605b72f1 CUEW: Use latest upstream version
Fixes typo in README :)

Thanks to @jesterKing!
2016-10-19 14:26:37 +02:00
7b43307508 Fix T49489: Pose marker in camera action + marker bound to camera -> crash.
'camera' Object pointer of TimeMarkers is a 'temp' hack since Durian project...
Would need to be either made definitive now, or removed/reworked/whatever.

But since we intend to use that object pointer for other needs, and current code
could lead to crashing .blend files, for now let's fix that mess (was missing
some bits in read code, and also totally ignored in libquery code).

Should be safe for 2.78a.
2016-10-19 14:26:37 +02:00
f978deddf8 UPBGE: Fix crash when calling shade_light texture when mtex has no tex. 2016-10-19 14:26:37 +02:00
dadd017d06 Cycles: Support earlier tile rendering termination on cancel
It will discard the whole tile, but it's still kind of more friendly than
fully locked interface (sort of) for until tile is fully sampled.

Sorry if it causes PITA to merge for the opencl split work, but this issue
bothering a lot when collecting benchmarks.
2016-10-19 14:26:37 +02:00
08d21ff582 Cycles: Fix typo in shader cancel routines 2016-10-19 14:26:37 +02:00
1733141db8 Adopt referenced scene in the context when evaluating sequences within a Scene Strip
This change makes it so that when the sequences within a Scene strip are
evaluated, they use the Scene that they come from as the context as opposed
the Scene that the Scene strip is in. This is necessary, for example, in the
case of the MulticamSelector where it needs to reference strips in the original
Scene as opposed to the Scene where the Scene strip is located.

Patch by @Matt (HyperSphere), thanks!
2016-10-19 14:26:37 +02:00
0df78d11e0 Cycles: Improve OpenCL line information handling
Previously it was falling back to just a path after #include
statement was finished. Now we fall back to a proper current
file name after dealing with the preprocessor statement.
2016-10-19 14:26:37 +02:00
acaa046e5e Update source tgz builder script
Was broken since splitting BKE_blender_version from BKE_blender.
2016-10-19 14:26:36 +02:00
7466603910 [MSVC] make.bat updates.
- The build folder name used to be depended on the order of the parameters, this is now normalized to
"build_windows_[Release/Full/Lite/Headless/Cycles/Bpy]_[x86/x64]_vc[12/14]_[Release/Debug]" regardless of the order of the parameters.

-Use CUDA8 for all kernels when building the release convenience target with visual studio 2015
2016-10-19 14:26:36 +02:00
08e4846540 Fix T49478: triangulate of face hangs Blender.
Another case of float imprecision leading to endless loop. INcreasing a bit 'noise threashold' seems to work OK.

Not a regression, but might be nice to have in 2.78a.
2016-10-19 14:26:36 +02:00
6c2f93aa7a Cycles: Fix compilation error with minimal feature set 2016-10-19 14:26:36 +02:00
949b23d29b Fix T49471: Vertex Connect randomly broken.
Not sure where this comes from, but code was converting BMEdge* to BMVert* to check oflags,
i.e. not accessing correct memory.

Regression, to be backported to 2.78a.
2016-10-19 14:26:36 +02:00
8aa04160ba Fix T49460: Particle group instance 'Use Count' value gets reset on file-load.
Regression caused rBbcc863993ad, write code was assuming dw->ob was always valid,
wich is no more the case right after reading file e.g.

Another good example of how bad it is to use 'hidden' dependencies between datablocks. :(
And another fix to be backported to 2.78a. :(((
2016-10-19 14:26:36 +02:00
d78a4b0c62 Fix T49466: Stupid typo in logicbricks new copy code from rB776a8548f03a
Moved that code forth and back a few times while creating rB776a8548f03a fix,
ended up forgetting to update it correctly for function where it layed down in the end.

Last-minute fixes are never a good thing... Now we already have real reason for 2.78 'a' release :(
2016-10-19 14:26:36 +02:00
a05f9bef3f Fix T49423: Data Preview of group containing only group instances is empty.
Code was not getting correct boundbox in some cases (group only instancing other groups e.g.), now
compute our own bbox in those cases.

Based on patch by @lichtwerk, but extended the fix to include linked datablocks in some cases
(linked objects in local groups, linked objects in local scene, etc.), this was also broken in existing code.

Reviewers: mont29

Subscribers: duarteframos

Differential Revision: https://developer.blender.org/D2257
2016-10-19 14:26:36 +02:00
a88af3e576 Fix T49461: Dynamic paint wetmap flickers.
Regression from rBa4a968f, we would adjust current point's wetness without actually protecting it
in new multi-threaded context, leading to concurrent access mess.

Now delay applying wetness reduction to current point to end of function, allows us to avoid having
to lock current point twice together with neighbor one (and reducing spinlock awainting too).

To be backported to 2.78a.
2016-10-19 14:26:36 +02:00
ff27b58b4c Fix T49464: Data Transfer modifier slows down redraw of window.
Never call function that might recompute a DM in an RNA itemf callback (or any UI-related func in general)!
There was an XXX comment asking if this was OK - well, no, it was not. :P

Could be ported back to some 2.78 flavour should we need it.
2016-10-19 14:26:35 +02:00
3bf9cbe7a2 Fix export image generated by export UV layout
Was only happening with new dependency graph.

The issue here is that scene's depsgraph layers will be 0 unless
it was ever visible. Worked around by checking for 0 layer in the
update_tagged of new depsgraph. This currently kind of following
logic of visible_layers, but is weak.

Committing so studio is unlocked here, will re-evaluate this layer.
2016-10-19 14:26:35 +02:00
cb9d010421 Fix Scene datablocks being created with a real user while never having any real datablock user.
Now using new system dedicated to that kind of cases, id_ensure_real_user(), instead.
That way, usercount of Scenes is handled correctly at deletion time.

Reported by @sergey over IRC, thanks.
2016-10-19 14:26:35 +02:00
c1205fd5ec [Windows/make.bat] Clean only after all parameters have been processed so the full path is known, and require a convenience target to be set. Also added a helpful error message if any of the required data is not available. 2016-10-19 14:26:35 +02:00
c9361c6935 Cycles: Cleanup file headers
Some of the files were wrongly attributing code to some other
organizations and in few places proper attribution was missing.

This is mainly either a copy-paste error (when new file was
created from an existing one and header wasn't updated) or due
to some refactor which split non-original-BF code with purely
BF code.

Should solve some confusion around.
2016-10-19 14:26:35 +02:00
711421a90f Cycles: Move BVH constants to an own files, so they are easily re-usable 2016-10-19 14:26:35 +02:00
0972786fa4 Buildbot: Another attempt to have OSX builder fixed 2016-10-19 14:26:35 +02:00
61ae5f1b23 Buildbot: Temporary disable CUBIN compilation 2016-10-19 14:26:35 +02:00
d882d4e91d Buildbot: Attempt to use proper Clang for CUDA binaries 2016-10-19 14:26:35 +02:00
bd4185b03b Buildbot: Disable QuickTime for the time being
Buildbot machine was updated to the new SDK which seems to have
QTKit removed.

For until we've installed older SDK or ported our code to a new
AVFramework disabling QuickTime.
2016-10-19 14:26:35 +02:00
Julian Eisel
483b4f0567 Fix missing properties editor update when changing 3D View camera
Actually two errors here:
* Properties editor wasn't refreshing on (NC_SCENE | ND_RENDER_OPTIONS) notifiers
* Was using notifier info bits wrongly, needs to send two separate notifiers

Decided to remove ND_RENDER_OPTIONS rather than adding properties editor scene context refresh for it, this is more than a render option change.
2016-10-19 14:26:34 +02:00
bdbf608941 OpenGL render: Skip GP passes if viewport has GP visibility disabled 2016-10-19 14:26:34 +02:00
b148eda5a7 dynamic fracture, divide force by mass to get higher probability of secondary fractures 2016-10-13 23:22:28 +02:00
bf3bb95097 added dynamic minimum shard size as option 2016-10-13 21:51:35 +02:00
eb45c12ef0 dynamic fracture, fix for passive shards... dynamic cache was not used at all for it 2016-10-13 20:10:52 +02:00
6276e3d174 dynamic fracture, added a third new constraint option "none" 2016-10-13 00:52:23 +02:00
41481a1be6 dynamic frac fixes (better activation, ability to merge cluster count and group) 2016-10-12 22:32:47 +02:00
a3704e9b6b crash fixes for dynamic split, also attempt to get rotations correct with limit impact 2016-10-12 17:25:13 +02:00
8e166a5926 fix, break anyway if there are no constraints at all 2016-10-12 12:13:37 +02:00
d22d1bae7c added constraint dynamic percentage and dynamic constraint building option 2016-10-12 12:06:21 +02:00
f8a043a106 another fix attempt for rotational anomalies 2016-10-12 01:23:07 +02:00
0a15defd44 partial fix attempt for incorrect rotation issue with dynafrac 2016-10-11 21:40:57 +02:00
d735ec0a2e minor fix for dynamic fracture, there was an off by 1 error which caused strange behavior on single shards 2016-10-11 01:22:34 +02:00
0b0fe66838 vary the seed when using presplit in dynafrac and fix for error when applying split to a single island 2016-10-10 23:24:16 +02:00
c9446653e9 improvement of pre-split dynamic fracture 2016-10-10 18:56:47 +02:00
d6574abb83 added split shards to island support for dynamic fracture (works only good if there are multiple islands) 2016-10-09 13:36:50 +02:00
5d6a36eb59 dynamic fracture, further minor transform tweak 2016-10-08 15:27:00 +02:00
794f85516c another minor tweak for transform issue 2016-10-08 00:22:59 +02:00
b5834d39ac fix for dynafrac, disallow passive objects as triggers again (to avoid the ground being a trigger) 2016-10-07 22:45:31 +02:00
5ce8f72a12 further attempt to fix / get the transform issues under control with dynafrac 2016-10-07 22:35:09 +02:00
81a67d8e98 fixed some more transform issues with dynamic fracture, added openmp for loop for boolean fracturing 2016-10-06 22:20:58 +02:00
5a46ad276c dynamic fracture, attempt to better control the higher level fractures via threshold 2016-10-06 17:49:32 +02:00
7c4489be8f partial fix for dynamic fracture transform issues, impact points might be calculated incorrectly still. 2016-10-05 22:16:18 +02:00
05c64b674a dynamic fracture, fix for texture propagation and autohide on secondary fractures 2016-10-05 17:29:22 +02:00
f0058e4980 Fix elbeem omp for msvc 2016-10-04 00:03:07 +02:00
8bd2323829 further tweaks for dynamic fracture 2016-10-03 15:11:24 +02:00
cc00da895e dynamic fracture: added back constraint support for it 2016-10-03 01:21:23 +02:00
63f90d1099 dynamic fracture, crash fix for autohide 2016-10-02 18:24:00 +02:00
030bb2f7e0 8% faster fluidbaking with gcc and 30% faster with clang 2016-10-02 17:58:40 +02:00
ed54923768 attempt to keep shards not affected by fracture kinematic if the object is kinematic / triggered 2016-10-02 13:51:47 +02:00
009dacd317 fixed some warning issues (const vs non const, wrong variable type in format string) 2016-10-01 18:06:52 +02:00
72f52c2dae backport of "fix Mac build for Xcode < 8" to FM branch
This was added to 2.78 release branch after the merge, so adding it here too.
2016-10-01 16:22:01 +02:00
723cb3c1ae added README 2016-10-01 14:31:28 +02:00
1f88e48d08 dynamic fracture can now react to multiple impacts on initial shard and 1st level shards 2016-10-01 14:25:27 +02:00
6b550a563e crash fix for direct text fracture (prefractured) -> bmesh use_toolflags set incorrectly 2016-09-28 22:52:10 +02:00
a6ebe080f7 windows compile fix 2016-09-28 12:47:22 +02:00
0b13b7adef fix Mac build for Xcode < 8
We need a long-term fix, but this will get 2.78 out the door.
2016-09-28 10:41:56 +02:00
192a18a99d added new bmesh boolean solver to fracture modifier as well 2016-09-28 00:01:28 +02:00
07e45ea86c merge compile fixes 2016-09-27 21:46:59 +02:00
23aabf5c81 Merge remote-tracking branch 'refs/remotes/origin/blender-v2.78-release' into fracture_modifier
Conflicts:
	CMakeLists.txt
	build_files/build_environment/install_deps.sh
	build_files/cmake/macros.cmake
	doc/python_api/sphinx_doc_gen.sh
	intern/cycles/app/CMakeLists.txt
	intern/cycles/blender/addon/properties.py
	intern/cycles/blender/blender_sync.cpp
	intern/cycles/kernel/bvh/bvh.h
	intern/cycles/kernel/geom/geom_bvh_volume.h
	intern/cycles/kernel/geom/geom_bvh_volume_all.h
	intern/cycles/kernel/kernel_volume.h
	intern/cycles/kernel/kernels/opencl/kernel.cl
	intern/cycles/kernel/shaders/node_subsurface_scattering.osl
	intern/cycles/kernel/svm/svm_closure.h
	intern/cycles/util/util_vector.h
	release/datafiles/splash.png
	release/datafiles/splash_2x.png
	release/scripts/addons
	source/blender/blenfont/intern/blf_font.c
	source/blender/blenkernel/BKE_blender.h
	source/blender/blenkernel/BKE_mesh_mapping.h
	source/blender/blenkernel/CMakeLists.txt
	source/blender/blenkernel/intern/blender.c
	source/blender/blenkernel/intern/image.c
	source/blender/blenkernel/intern/particle_distribute.c
	source/blender/blenkernel/intern/rigidbody.c
	source/blender/blenkernel/intern/scene.c
	source/blender/blenkernel/intern/speaker.c
	source/blender/blenloader/intern/readfile.c
	source/blender/bmesh/intern/bmesh_core.c
	source/blender/bmesh/intern/bmesh_polygon.c
	source/blender/editors/gpencil/gpencil_brush.c
	source/blender/editors/gpencil/gpencil_ops.c
	source/blender/editors/object/object_relations.c
	source/blender/editors/physics/particle_edit.c
	source/blender/editors/space_view3d/drawarmature.c
	source/blender/editors/space_view3d/drawvolume.c
	source/blender/editors/transform/transform_snap.c
	source/blender/gpu/shaders/gpu_shader_material.glsl
	source/blender/makesdna/DNA_modifier_types.h
	source/blender/makesdna/intern/makesdna.c
	source/blender/makesrna/intern/rna_camera.c
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/makesrna/intern/rna_sculpt_paint.c
	source/blender/modifiers/MOD_modifiertypes.h
	source/blender/modifiers/intern/MOD_util.c
	source/blender/nodes/shader/nodes/node_shader_bump.c
	source/blender/nodes/shader/nodes/node_shader_fresnel.c
	source/blender/nodes/shader/nodes/node_shader_normal_map.c
	source/blender/render/intern/source/render_result.c
	source/blender/render/intern/source/render_texture.c
	source/blender/windowmanager/WM_api.h
	source/creator/CMakeLists.txt
2016-09-27 21:46:27 +02:00
4bb1e224ba Blender 2.78: Update submodule hashes 2016-09-26 14:42:18 +02:00
2c19ddf4a6 Cycles: Fix T49411: Multiscatter GGX with zero roughness when Filter Glossy is enabled 2016-09-26 10:51:51 +02:00
6d483e20e0 Fix T49310: incorrect Cycles standalone normals with negative scale. 2016-09-26 10:51:51 +02:00
599e560a68 Cycles: Fix overflow caused by wrong size calculation in Mesh::add_undisplaced 2016-09-26 10:51:51 +02:00
daa1487425 Cycles: Prevent crash in special cases when object has less slots than mesh
This is something what was guaranteed in give_current_material(), just
copied some range checking logic from there.

Not sure what would be a proper fix here tho.
2016-09-26 10:51:51 +02:00
abc8810911 Cycles: Don't sum up memory usage of all devices together for the stats 2016-09-26 10:51:50 +02:00
5cb1251222 Fix T49417: Cycles crash - can't use 5 Gigabyte Tile EXR texture file
Was an integer overflow issue when calculating offsets.
2016-09-26 10:51:50 +02:00
c5558b3ccd Fix crash in own recent rB776a8548f03a049.
New ID may be null, have to check this too!

Reported by @panzergame over IRC, thanks.

To be ported to 2.78 as well.
2016-09-26 10:51:50 +02:00
94e91ca7e5 Fix T49430: append scene with gamelogic broken.
In fact, it was the whole remapping process that was broken in logic bricks area,
due to terrible design of links between those bricks...

Object copying was also broken in that case, fixed as well.

To be backported to 2.78.

Note that issue was actually probably there since ages, hidden behind dirty hacks
used in previous append code (though likely visible in some corner cases).

Listen kids: do not, never, ever, do what has been done for links between logic bricks. Never. Ever.
Even as pure runtime data it would have been bad, but as stored data...
2016-09-26 10:51:50 +02:00
4ed7fb581a Fix T49441: Grease Pencil - pie menu - brush name field crashes blender
Using context.active_gpencil_brush to access the active Grease Pencil brush
would result in a crash if trying to rename the brush, because the "ID" pointer
was not set.

To be backported to 2.78
2016-09-26 10:51:50 +02:00
08d14a86d4 Collada: Trying to get rid of some warning messages on linux 2016-09-26 10:51:50 +02:00
a5d8efe16c Collada: Trying to get rif of some warning messages on linux 2016-09-26 10:51:49 +02:00
01ed1de0d8 Fix: Collada Importer did not import the Blender Profile information correctly when multiple objects are bound to same armature. This caused Bone tails to be placed wrong. 2016-09-26 10:51:49 +02:00
a2e105186f some improvement for dynamic fracture, it now takes location and size of impact object into account with "Limit Impact" 2016-09-25 21:38:06 +02:00
35f81587b5 Fix T49427: Drivers of Shapekeys break when Append a group.
Optimization attempt with BKE_library_idtype_can_use_idtype() was not taking into account
the fact that drivers may link virtually against any datablock...

Has to be rethinked, but for after 2.78 release, this commit is safe to backport.
2016-09-22 16:52:10 +02:00
d32ae028ba Buildinfo: Improve behavior with detached HEAD
Try real hard to detect which branch we've detached from.
2016-09-22 15:02:52 +02:00
42f42cbfdc Fix T49425: Freestyle in viewport keeps updating over and over.
Regression caused by rBb27ba26, we would always tag datablocks to update in G.main,
ignoring given bmain, now always use this one instead.

To be backported to 2.78.
2016-09-22 15:02:32 +02:00
Julian Eisel
53ff09bc97 GPencil: Fix memory leak using stroke arrange OP 2016-09-22 15:02:25 +02:00
de311a0a15 Blender 2.78: Point locales to the latest branch 2016-09-22 12:37:35 +02:00
f3fe4e736f Cycles: Soft minimum for dice rates
Use 0.5 as a soft minimum for dice rates to help from setting them too
low. Lower values can still be set by typing in the value.
2016-09-22 12:33:32 +02:00
5ef46c1ef1 Cycles: Fix update of subdivision meshes when global dice rates change
When subdivision settings were moved from meshes to objects this was missed,
should work fine now.
2016-09-22 12:33:32 +02:00
7da7611c0b Cycles: Adaptive isolation
Idea here is to select the lowest isolation level that wont compromise quality.
By using the lowest level we save memory and processing time. This will also
help avoid precision issues that have been showing up from using the highest
level (T49179, T49257).

This is a pretty simple heuristic that gives ok results. There's more we could
do here, such as filtering for vertices/edges adjacent geometric features that
need isolation instead of checking them all, but the logic there could get a
bit involved.

There's potential for slight popping of edges during animation if the dice
rate is low, but I don't think this should be a problem since low dice rates
really shouldn't be used in animation anyways.

Reviewed By: brecht, sergey

Differential Revision: https://developer.blender.org/D2240
2016-09-22 12:33:32 +02:00
d14603021c Blender 2.78: Point addons to an updated branch 2016-09-22 11:14:48 +02:00
bca6aa47bc Blender 2.78: Move to release cycle 2016-09-22 11:13:58 +02:00
d63505e42e CMake: Fix copy-paste error 2016-09-22 11:07:37 +02:00
9836940d4d Bring blender_release.cmake uptodate with the changes from D2227 2016-09-22 11:07:37 +02:00
c6ab7c31a1 [windows] add some helpers to make.bat to facilitate making release builds.
New features:
1) Release target that checks for both cuda 7.5 and 8 with WITH_CYCLES_CUDA_BINARIES=ON and CYCLES_CUDA_BINARIES_ARCH=sm_20;sm_21;sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61 options set.
2) Option to switch between x86 and x64 builds, the default remains (auto detect the architecture) but can be overridden.
3) Option to switch between vs12(2013) and vs14(2015) default is 2013.

Reviewers: juicyfruit, sergey

Reviewed By: sergey

Tags: #platform:_windows

Differential Revision: https://developer.blender.org/D2180
2016-09-22 11:07:37 +02:00
22b39901e3 Fix non-finite normalization factor in certain cases 2016-09-22 11:07:37 +02:00
213e9aeb8c Fix: Grease Pencil sculpting crashes when sculpting on layers without any strokes
Reported by @loochmunz. I've also gone through checking for and fixing other places
where this was also occurring.


To be included in 2.78
2016-09-22 11:07:37 +02:00
9d976a4f7a GPencil D+W Pie: Don't show editing operators when not in editmode
These operators only operate on the selected strokes, but when not in editmode,
stroke vertices are not shown.

Safe for 2.78
2016-09-22 11:07:37 +02:00
83bbf57b5b regression fix for 1346482d23: The length of leaf bones should always be set to the length of the smallest bone. since the mentioned commit the importer did only recalculate the leaf bone length when the 'fix leaf bones' option was also enabled. 2016-09-22 11:07:36 +02:00
ea7d500b6d Fix T49386: Blender crashes when told to load an OCIO LUT that does not exist 2016-09-22 11:07:36 +02:00
0a97e63246 Fix T49375: align rotation with snap target isn't toggleable in edit mode.
Based on D2237, but fixed patch always hiding 'snap on self' button...

Should be safe for 2.78.
2016-09-22 11:07:36 +02:00
Martijn Berger
0247547b6b Lowercase includes for psapi.h and dbghelp.h windows includes.
This makes cross compilation a little less painful
2016-09-22 11:07:36 +02:00
1782263ef8 CacheFile: make sure SpinLock is destroyed when exiting Blender.
Missed in rB62b1cdd6.
2016-09-22 11:07:36 +02:00
c8c829360b Cycles: Fix typo that would sometimes result in subsurf modifier being disabled 2016-09-22 11:07:36 +02:00
750650c737 Fix T49245: Adaptive Subdivision with Auto Smooth causes weird mesh appearance 2016-09-22 11:07:36 +02:00
8e6aaa08c2 Fix T49384: crash in tangent space calculation with NaN mesh vertices. 2016-09-22 11:07:35 +02:00
fc2b8c9793 Fix T49372: Fresnel node: difference between 2.76 and 2.78 GLSL output 2016-09-22 11:07:35 +02:00
8909ff0e67 Fix filebrowser not getting back to valid dir in Release builds.
Stupid mistake wrapping path validation code inside a BLI_assert, which means it was
only called in Debug builds...

Found by Sergey, thanks.

Should be backported to 2.78.
2016-09-22 11:07:35 +02:00
7b748e9478 Fix crash in some cases when deleting particle systems.
Those 'never null' ID pointers are really a PITA to handle... luckily we don't have much of those around!

Found by Sybren, thanks.

Should be backported to 2.78.
2016-09-22 11:07:35 +02:00
4733544195 Fix Py's IDs user mapping: do not consider ShapeKeys' from here.
This is internal pointer helper for scene evaluation and tools, though exposed to bpy API,
it can give false 'dependency cycles' in bpy.data.user_map() results.

That's followup to rBe007552442634 really, both should be backported to 2.78
2016-09-22 11:07:35 +02:00
ca5f91951c Fix Py's IDs user mapping: do not consider proxy_from here.
This is internal pointer helper for scene evaluation and tools, it's not exposed to bpy API anyway,
and can give false 'dependency cycles' in bpy.data.user_map() results.

Found by sybren in his Splode work.
2016-09-22 11:07:35 +02:00
0960d523a2 Fix T49179: Parts of mesh disappear with adaptive subdivision
Problem was zero length normal caused by a precision issue in patch evaluation.
This is somewhat of a quick fix, but is better than allowing possible NaNs to
occur and cause problems elsewhere.
2016-09-22 11:07:35 +02:00
91966eeefa fix Mac build with Xcode 8
Small issues in GHOST
- use NSApplicationDelegate protocol for our app delegate
- make sure NSApp is initialized before using
(cherry picked from commit df7be04ca6)
2016-09-22 11:07:34 +02:00
fb85484e6c Fix memory leak in copy pose operator 2016-09-22 11:07:34 +02:00
9d70344620 Blender 2.78: Point locales to a new branch hash 2016-09-14 16:46:07 +02:00
d5eb0b58a0 Cleanup: Fix epic indent failure in previous commit :/ 2016-09-14 16:24:16 +02:00
c11fcc34c4 Fix missing PaintCurves list in bpy.data
Minimal list features for now, no add/remove stuff, that we can add later...

Reported by sybren.

Should be safe for 2.78.
2016-09-14 16:15:58 +02:00
a37e4d4738 Fix T49341: Bad motion blur behavior in Cycles when using Speed effect in Sequencer
Cycles was thinking it always rendering integer frame, which is not correct.
2016-09-14 16:14:17 +02:00
14d26df2f1 Fix T49342: TypeError when autocompleting bpy.app.something.
Regression from rB036c006cefe471. We can't use self here, self is bpy.app, not pydescriptor of python path getsetter...

So for now, do not try to replace getsetter by actual value in bpy.app's dict,
just return static var generated on first run.

Should be safe for 2.78.
2016-09-14 15:58:17 +02:00
e02c63df1b Attempt to fix broken path remapping in own rB443b3ca9b9cb. 2016-09-14 13:26:30 +02:00
b6508da380 Code Cleanup: Deduplicate undo node freeing code 2016-09-14 13:26:04 +02:00
929701931d Fix: GPencil drawing sessions now respect limits for maximum undo steps
When drawing with Grease Pencil "continous drawing" for a long time
(i.e. basically, drawing a very large number of strokes), it could be
possible to cause lower-specced machines to run out of RAM and start
swapping. This was because there was no limit on the number of undo
states that the GP undo code was storing; since the undo states grow
exponentially on each stroke (i.e. each stroke results in another undo
state which contains all the existing strokes AND the newest stroke), this
could cause issues when taken to the extreme.
2016-09-14 13:26:01 +02:00
e5f49efe25 Blender 2.78 release: Update addons hash once again 2016-09-14 12:39:07 +02:00
0d7f3d01d7 CMake: decouple WITH_CYCLES_OPENSUBDIV from WITH_OPENSUBDIV, and enable on OS X.
Reviewed By: sergey

Differential Revision: https://developer.blender.org/D2227
2016-09-14 12:37:34 +02:00
9a35ebc1ea Fix two issues related to 'partial' .blend files:
I) Filename was not put in temp Main generated to save selected data only,
this was breaking readcode when trying to open partial file, leading to missing
filename in final loaded Main data.

II) Read code would confuse partial .blend files with Undo ones, when they had no screen in them
(which happens to 99.999% of partial .blend files I guess).

Reported by @sybren, thanks.

Should be safe enough for 2.78 release.
2016-09-14 11:41:16 +02:00
df4602ee3b Fix compilation error: Shadowing of variable 2016-09-14 11:04:34 +02:00
fa47bd1796 2.78 release: Update splash screen label 2016-09-14 10:37:35 +02:00
e38acc2191 2.78 release: Update hash for addons submodule 2016-09-14 10:28:48 +02:00
c6e0c674ee Fix T35333: Update some WM/UI API functions docstrings.
Based on patch by @codemanx, but with slightly less verbose descriptions.

More detailed behavior etc. rather belongs to doc/python_api/examples/bpy.ops.x.py imho.
2016-09-14 10:26:22 +02:00
1e5ac3b648 Fix bpy.data.user_map() ignoring unused datablocks.
Should be backported to 2.78.
Found by Sybren here in studio, thanks!
2016-09-14 10:26:22 +02:00
dcccf4be30 Outliner: Report linked datablock edit failure when trying to rename linked data in outliner 2016-09-14 10:26:22 +02:00
50452f5b67 Fix T49323: Ineffective bone roll calculation with low rig scale
The code was expecting vector to be normalized, however after
applying inverted object matrix it was possible to have scale
applied to it.
2016-09-14 10:26:21 +02:00
4271c1cc71 Fix T49336: Outliner allows to edit restrict flags for linked objects 2016-09-14 10:26:21 +02:00
290e650590 Fix T49290: Specific .blend with hair crashes in MacOS 2.78 RC1 on render
The issue was caused by some false-positive empty non-AABB intersection.
Tried to tweak it a bit so it does not record intersection anymore.

Hopefully will work for all platforms. Tested here on iMac and Debian.
2016-09-14 10:26:21 +02:00
5de77bf8dc Fix T49327: Cycles OSL Mode: RGB Curves node only outputs gray scale images
To be backported to 2.78 release.
2016-09-14 10:26:21 +02:00
90f920c138 Fix T49296, assert failure in Bevel code.
The mesh interpolation function failed to fill a fractions-of-the-way
array properly when the distances are very small but nonzero.
2016-09-14 10:26:21 +02:00
b11f073ca0 Cycles: Fix wrong SSS in combination with hair on AVX2 platform
Not sure why exactly that happened, need a closer look.
2016-09-14 10:26:21 +02:00
293d5db895 Cycles: Fix shading and crashes resulting from constant folding on displacement
Constant folding was removing all nodes connected to the displacement output
if they evaluated to a constant, causing there to be no valid graph for
displacement even when there was displacement to be applied, and sometimes
caused crashes.
2016-09-14 10:26:21 +02:00
fd01cd7d06 Cycles: Replace object index hack with actual checks for SD_TRANSFORM_APPLIED
Using ones complement for detecting if transform has been applied was confusing
and led to several bugs. With this proper checks are made.

Also added a few transforms where they were missing, mostly affecting baking
and displacement when `P` is used in the shader (previously `P` was in the
wrong space for these shaders)

Also removed `TIME_INVALID` as this may have resulted in incorrect
transforms in some cases.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2192
2016-09-14 10:26:21 +02:00
2c1201502d Cycles: Fix bump mapping to use object space when used with true displacement
Bump mapping was happening in world space while displacement happens in object
space, causing shading errors when displacement type was used with bump mapping.

To fix this the proper transforms are added to bump nodes. This is only done
for automatic bump mapping however, to avoid visual changes from other uses of
bump mapping. It would be nice to do this for all bump mapping to be consistent
but that will have to wait till we can break compatibility.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2191
2016-09-14 10:26:20 +02:00
b67db67b01 [CMAKE/Platform/Windows] Only perform version check if the actual compiler is MSVC 2016-09-14 10:26:20 +02:00
Dmitry Dygalo
872065e19e Fix undefined variable on errors in Cycles ctests.
Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2201
2016-09-14 10:26:20 +02:00
f6fb072ab2 Fix OpenSubdiv related buffer overrun with multiple FVar channels.
The existing code uses the input value count of the first channel
for all of them. If the first channel is the largest, it leads to
a crash-causing buffer overrun in memcpy below. Likely this was
left since the time when only one channel was supported.

As a crash fix, probably should go into 2.78
2016-09-14 10:26:20 +02:00
16135990cd Fix missing 'prop_required' flags in some ID RNA funcs.
Not critical, but would rather have this in 2.78 (for API doc reasons mostly).
2016-09-14 10:26:20 +02:00
00abe6ecf1 Fix/Workaround T49297: Crash related to custom data draw (Blender with ASAN)
Root of the issue is that active render index became wrong. This is the actual
thing to be fixed, but as usual this is quite tricky to reproduce. Since such
bad situation might have happened more and fix isn't really difficult or
intruisive let's avoid crash for now.

Can be revisited once we figure out root of the issue.

Nice for 2.78 release.
2016-09-14 10:26:20 +02:00
3f5960b869 Fix T49299: Removing offset object in modifiers doesn't update mesh.
Own fault in new ID management work, thought rebuild the DAG itself was
enough to actually update whole scene, but we actually need to tag datablocks
for update as well, when we change (or remove) one of their ID pointers...
2016-09-14 10:26:20 +02:00
fb2a412b56 Cycles: Fix regular BVH nodes refit
For proper indexing to work we need to use unaligned node with
identity transform instead of aligned nodes when doing refit.

To be backported to 2.78 release.
2016-09-14 10:26:20 +02:00
30aaa92a19 Cycles: Add asserts to BVH node packing 2016-09-14 10:26:19 +02:00
979a4a613c Cycles: Cleanup: line wrapping 2016-09-14 10:26:19 +02:00
faec666bbe Fix T49283: Crash in BKE_ptcache_make_particle_key.
This is really hack-fix actually, not sure why `get_pointcache_keys_for_time()` seems to assume
it will always find key for given part index at least for current frame, and whether this assumption
is wrong or whether bug happens elsewhere...

Anyway, this is to be wiped out in 2.8, so no point loosing too much time on it, for now merely
returning unchanged (i.e. zero'ed) ParticleKeys in case index2 is invalid. Won't hurt anyway,
even if this did not crash in release builds, would be returning giberish values.
2016-09-14 10:26:19 +02:00
320d601e01 Fix T49286: Compilation error with XCode 7.0
Weirdly enough, this version of XCode seems to have static_assert()
even when NOT using C++11. This is totally weird and counter intuitive
since static_assert() is supposed to be C++11 onlky feature.

Can XCode stop using future, please? :)
2016-09-14 10:26:19 +02:00
e6071056a4 Cycles: Fix OpenCL speed regression introduced with the improved bump mapping
The two SVM nodes added with e7ea1ae78c caused a slowdown on AMD cards when rendering with OpenCL, whether displacement was used or not.
In the Barcelona Pavillon scene on a RX480, this would cause a 12% slowdown.

Therefore, this commit adds a additional flag for feature-adaptive compilation so that the new SVM nodes are only enabled when they are needed (Node tree connected to the Displacement output and Displacement type set to Both).

Also, the nodes were also added to shaders when the Displacement Type was set to Bump (the default), which was unneccessary and is fixed now.

Thanks to linda2 on IRC for reporting and testing and to maiself for help with the displacement shader code.

This fix might be relevant for 2.78, but it should be tested further before including it.
2016-09-14 10:26:19 +02:00
4929de9df7 Fix T49273: Crash during access to dupli weights at launch time.
See commit's comments for details, but this boils down to: do not try to use
purely runtime cache data as a 'real' ID pointer in readcode, it's likely
doomed to fail in some cases, and is bad practice in any case!

Thix fix implies dupliweight's object will be invalid until first scene update
(i.e. first particles evaluation).
2016-09-14 10:26:19 +02:00
9663471bb7 OpenSubdiv: Support multiple materials drawing in Cycles textured view
Consider for inclusion into 2.78.
2016-09-14 10:26:19 +02:00
abe4c38410 [cmake/cpack] allow override of package name
Cpack generates a standard filename with git information in it, which might not always be wanted for release builds, this patch adds an option to override that default filename.

Reviewers: sergey, juicyfruit

Reviewed By: juicyfruit

Differential Revision: https://developer.blender.org/D2199

ammended to fix: wrong variable name in main CMakeLists.txt
2016-09-14 10:26:19 +02:00
7aa0103ca2 Revert "Depsgraph: Prioritize evaluation of the new scheduled nodes"
This reverts commit 9444cd56db.

This commit caused some flickering in the bones when swapping IK to Fk.

While it's unclear why such change caused any regressions, let's revert
it to unlock the studio.
2016-09-14 10:26:18 +02:00
fcb7973849 [cmake/cpack] allow override of package name
Cpack generates a standard filename with git information in it, which might not always be wanted for release builds, this patch adds an option to override that default filename.

Reviewers: sergey, juicyfruit

Reviewed By: juicyfruit

Differential Revision: https://developer.blender.org/D2199
2016-09-14 10:26:18 +02:00
b281df01c7 Fix T41883: Strip keyframes not respected for scenes rendered by other scenes 2016-09-14 10:26:18 +02:00
8e7d6561f5 Add script which scales splash screen down
Based on reading documentation around. This particular version
is based on the ImageMagic documentation which could be found
there:

  http://www.imagemagick.org/Usage/filter/
  http://www.imagemagick.org/Usage/filter/nicolas/

Current filter is based on measuring mean error with the current
splash screen and choosing combination of parameters which
gives minimal mean error.
2016-09-14 10:26:18 +02:00
559e116a36 Fix cast shadows (material option) in the viewport
Fix cast shadows options (in material tab) not working in the viewport.
An off-by-one error. See D2194 for more.

Committing for Ulysse Martin (youle) who found & fixed this.
2016-09-14 10:26:18 +02:00
989ca313be Fix T49252: Crash when image textures used with true displacement 2016-09-14 10:26:18 +02:00
29f7a4abbd OpenSubdiv: Fix missing ORCO when enabling OSD but having dependency to the geometry
Was causing huge viewport lags.

Reported by angavrilov in IRC, thanks!

Safe and nice for 2.78.
2016-09-14 10:26:18 +02:00
802d253a46 Fix T49251: moving smoke domain with additional resolution causes crash.
This is a bug in the multithreaded task manager in negative value range.

The problem here is that if previter is unsigned, the comparison in the
return statement is unsigned, and works incorrectly if stop < 0 &&
iter >= 0. This in turn can happen if stop is close to 0, because this
code is designed to overrun the stop by chunk_size*num_threads as
the threads terminate.

This probably should go into 2.78 as it prevents a crash.
2016-09-14 10:26:18 +02:00
a2e08ef997 Fix own mistake in recent rB8b2a45052093, broke saving render results as images in some cases.
Reported by sebastian_k over IRC, thanks.

To be backported to 2.78.
2016-09-14 10:26:18 +02:00
44df27dc71 Attempt to fix compilation error with static boost on certain platforms
This was reported in T49231.
2016-09-14 10:26:17 +02:00
98b2411b30 Fix T49226: Incorrect Material viewport shading of Cycles Normal Map node in Edit mode for an object with Array modifier
Was incorrect indexing done in the array. Caused by 5abae51.

Not sure why it needed to be changed here, but array here is supposed to be
a loop data, so bringing back loop index as it originally was. The shading was
wrong in edit mode with BI active as well (so it's not like it's needed for
BI only).

Patch in collaboration with Alexander Gavrilov (angavrilov), thanks!

Should be double-checked and ported to 2.78.
2016-09-14 10:26:17 +02:00
3ea30ce1d0 Fix glUniform called from glBegin/glEnd blocks
Was causing some invalid operations in OpenGL.

After more testing should be fine for 2.78.
2016-09-14 10:26:17 +02:00
f496a34700 Fix T49220: Vertex paint doesn't work with OpenSubdiv
It's a bit tricky to align vertex color data between Blender and OpenSubdiv
so for now we simply disable OpenSubdiv in the paint modes.

Safe for 2.78.
2016-09-14 10:26:17 +02:00
7a6a7d9f7c CMake: Skip addons_contrib for release candidate builds
Nowadays release candidates are supposed to be as close to the final
release as possible.

Safe for 2.78 release branch.
2016-09-14 10:26:17 +02:00
41141248ef API doc update script: Fix generated zipfile name, was broken in 'release' case... 2016-09-14 10:26:17 +02:00
e1c1a0c3ee API doc: add new pure-rsync py script to update API doc on Blender server.
The other one (sphinx_doc_gen.sh) needs an ssh account on the server to work - and I hate bash, too! :P
2016-09-14 10:26:17 +02:00
2ef4db4077 Cycles: Fix unreported - Missing node group for the Camera Node
Thanks to linda2 for reporting in IRC.
2016-09-14 10:26:17 +02:00
579e8c707b Alembic: fix parenting issues when an object has multiple curves/points
subobjects.
2016-09-14 10:26:17 +02:00
4be5fae30c Fix T49249: Alembic export with multiple hair systems crash blender
Crash was due to a name collision in Alembic objects caused by the fact
that names derive from the one of the Blender object. An object having
multiple particles system would thus give its name to various
subobjects.

Now use the name of the particles system for the Alembic object.
2016-09-14 10:26:17 +02:00
184c781657 Fix a few OpenCL compiler warnings. 2016-09-14 10:26:16 +02:00
91705ad477 fix: not initialised variable can crash blender (related to modifiers with cage editing enabled) 2016-09-14 10:26:16 +02:00
ab934e7d61 Fix T49228: Separate by material, materials dissappear after reload.
Yet another mismatch where code would decrease usercount (of Material here) but never increase it again
when re-assigning the datablock...
2016-09-14 10:26:16 +02:00
894a4f5230 Fix T49229: ID user decrement error when deleting group instance twice.
Another great example of inconsistency in usercount handling - dupli_group was considered
as refcounted by readfile.c code (and hence by library_query.c one, which is based on it),
but not by editor/BKE_object code, which never increased group's usercount when creating
an instance of it etc.

To be backported to 2.78.
2016-09-14 10:26:16 +02:00
eb85bb008f windows compile fix, use portable BLI_snprintf instead of snprintf 2016-09-12 19:52:20 +02:00
57c9742438 added global keep shards mode for cutter groups 2016-09-09 14:12:09 +02:00
c04b4d393b fixes: activating clusters via percentage, add meshisland id as name in fracture too, load crash fix 2016-09-09 13:33:34 +02:00
0e5089c30a 2.78 release: Point locales to a proper updated branch 2016-09-02 11:54:54 +02:00
0dd4c3bde7 fix, enabled threading for autoexecute 2016-08-08 20:13:08 +02:00
659ca6a7d6 added threaded checkbox next to execute fracture operator 2016-08-08 14:53:47 +02:00
be6d3df29b made threading optional via a checkbox 2016-08-08 14:07:30 +02:00
af118bd3ec fallback to singlethreaded for dynamic, mousebased and fast bisect.. also changed back fast bisect orderding to have more uniform shapes 2016-08-08 12:38:48 +02:00
0f1f3ca292 first attempt to multithread fracturing, works only for prefractured for now 2016-08-08 00:37:08 +02:00
fe55273199 some more optimizations at bisect, bit faster and less memory consumption, and removing bakes now when refracturing 2016-08-07 16:02:13 +02:00
480a8c2bce fixes for bisect and bisect+fill, should look correct again and be a bit faster as well
using a kdtree based preselection method to speed up bisecting
2016-08-06 11:18:00 +02:00
36f511f9c3 small fix for loading possibly different jack shared library versions on different linux distributions, thanks to sergey for the fix 2016-08-02 15:53:29 +02:00
aaef4310e9 small enhancement for voronoi + bisect and solidify after FM use case
if you use voronoi+bisect and solidify after FM, you can automerge now without having autohideable inner faces. This should have the same effect as autohide in regular use case has.
2016-07-25 23:08:46 +02:00
c6f7f3bc38 memory optimization for smoke compressibility fix, dont use recursion but a queue to avoid potential stack overflows, thanks to angavrilov for this optimization 2016-07-23 16:39:25 +02:00
5c8804d6ae fixes to prevent unwanted smoke "explosions" in the domain when using moving colliders, thanks to angavrilov for investigating those problems and providing this fixes. 2016-07-17 21:31:44 +02:00
8f53838675 attempt to make fast bisect usable with mousebased fracture... now the user has a bit control how the halving is performed via the helpers 2016-07-11 16:42:58 +02:00
d8f5a81a9a some tweaks for the faster voronoi+bisect method, its faster but not interactive yet... but should mostly lead to correct results 2016-07-09 13:43:36 +02:00
0f48c6a392 attempt to make voronoi+bisect faster, but it has problems with selfintersection, so unfortunately not useable on any
model out of the box
2016-07-09 01:35:43 +02:00
89c8718872 fix for converting fm external mode back to objects, used wrong transformation for objects 2016-06-12 17:17:30 +02:00
126e443035 crash fix for starting sim after convert to objects in external mode
stale data was around in depsgraph, missed a relations update tag call
2016-06-11 15:56:28 +02:00
785ac13c39 partial solution for FM autoexecute, auto disables when sim runs and is enabled again on startframe
note: cache will always be overwritten in autoexec sim mode, because keeping it may lead to incorrect sim results
furthermore a couple of changes for external mode (attempt to be more BCB compatible)
2016-06-02 10:48:29 +02:00
0935d32ffb fix, force autohide facepair generation only from valid DM
if primary source is invalid, force fallback to secondary source earlier now
2016-05-27 20:28:33 +02:00
c6388928e6 crash fix, could happen that the internal ob->derivedFinal DM structures were invalid
happened in some cases and most notably under windows when attempting to calculate the DMs bounding box
2016-05-27 10:07:05 +02:00
97f6dc3d10 backport for missing smoke viewport display due to using "min" as variable name
This was a fix for T47991 and affects OSX only.
2016-05-23 10:30:56 +02:00
d47aab201f fix: seems autohide refresh was not triggered each time after loading a file
since this is runtime only data force to refresh it now.
2016-04-27 13:30:59 +02:00
4cf48bbe1f fix for solver / cluster solver iterations override, it caused different behavior at loading / refresh
solver iteration override was taken into account too late, after first validation which probably caused different simulation behavior using the default value for one frame
2016-04-08 13:52:38 +02:00
470d0cd6e8 set version char to "a" and cycle to "release" 2016-04-05 20:00:49 +02:00
1e321b998c Merge remote-tracking branch 'refs/remotes/origin/blender-v2.77-release' into fracture_modifier 2016-04-05 19:58:20 +02:00
89f6987953 Fix UV-Editor crashes w/ over SHRT_MAX UV's 2016-04-05 20:45:38 +10:00
63e0d3a47f Fix T47705: Freestyle line glitch.
The addressed issue is a regression from Blender 2.75, after the internal
switch from double to single precision floating-point numbers in the
Freestyle code base.  Face normal calculations require the higher
precision during the computations, even though the results can be stored
as single precision numbers.
2016-04-05 19:34:50 +10:00
2490779013 Correct merge error 2016-04-05 19:02:39 +10:00
8b55e0e877 Remove newly added function (harmless but unused) 2016-04-05 18:58:42 +10:00
d979ba0f73 Blender 2.77a: Point addons to a new submodule hash 2016-04-05 10:55:38 +02:00
19f323012a Particles: Fix broken grid distribution in some case from own recent rB201d3938622. 2016-04-05 10:51:07 +02:00
e97db72ae4 Fix T47902: Particle grid not using modifier stack, Take II.
Now only fix correct handling of use_modifier_stack for grid distribution,
fixing it globally breaks all existing edited hair systems. :/
2016-04-05 10:51:01 +02:00
2d887ae200 Revert "Fix T47902: Particle grid not using modifier stack."
This reverts commit 2bd3acf7cd.

Commit is valid in theory - but in practice, it means nearly all edited hair systems
would need to be re-created from scratch... Not nice, so better revert and note in code
that particle distribution is ugly and does not respect 'use modifier stack' option in most cases.
2016-04-05 10:50:56 +02:00
ebceb93bb4 Fix T47902: Particle grid not using modifier stack.
Disclaimer: this is tentative fix, seems to be working but you never know with particles.
If issue arise, we'll just revert this commit and hide 'use modifier stack' option
for grid distribution instead.

This commit also try to make choice of which dm to use during distribution more generic
(deduplication of code), again hopping not to break anything. :P
2016-04-05 10:50:55 +02:00
828c7956c8 Fix error in ghash/gset_ensure_p_ex
The key is needed in the case the ghash resizes.
Caused regression T47984.
2016-04-05 18:48:37 +10:00
275ca01eac Fix T47939, take II: Check clang package version, not llvm-devel one.
Looks like some distro still provide llvm-3.4-devel, while no more clang-3.4.
Since clang depends on llvm of same version, check clang only should ensure
us we also have matvhing llvm... *sigh*
2016-04-05 10:46:37 +02:00
95de7b9a5f Fix T47939: Install Deps OSL 1.7.1 and clang-3.5
Until we officially support llvm3.5 or more, only allow for 3.4 llvm packages,
and build own stuff otherwise...
2016-04-05 10:46:28 +02:00
f36de27339 Fix T47848: Fix regression in sequencer GL render
Own changes in 2.77 broke off-screen render with scene render size doesn't match output.
2016-04-05 18:45:36 +10:00
fc78a58337 Cycles: Fix wrong camera in volume check when domain is only visible to camera rays 2016-04-05 10:41:46 +02:00
37ab16d075 Cycles: Fix regression caused by recent camera-in-volume commit
Stupid me forgot that we don't have stop-element in the stack yet.
2016-04-05 10:36:15 +02:00
da0ce86a3c Cycles: Make curves modified by a taper object with modifier considered a deform modified
That might consider a bit more objects to be considered deform modified,
but it covers common case of using taper object without require of doing
recursive checks.

In worst case it'll be just some extra synchronization time, no render
time difference will happen for false-positive because of extra checks
happening in Cycles.
2016-04-05 10:36:14 +02:00
f615b57379 Fix curve editmode adding 3D primitives w/ 2D curves 2016-04-05 10:36:14 +02:00
a5cfe0f9dc Fix curve adding 3D nurbs when 2D is set
Ctrl-LMB ignored 2D constraint
2016-04-05 10:36:14 +02:00
e63a8e7ded Fix curve hide keeping spline active 2016-04-05 10:36:14 +02:00
f2ae9c6f85 Fix curve, missing update on Ctrl-LMB 2016-04-05 10:36:14 +02:00
45e68e190d Fix T47971: rigid body baking crash due to thread race condition. 2016-04-05 10:36:14 +02:00
754566cf5b Fix T48030: Can't zoom VSE properties panel 2016-04-05 10:36:14 +02:00
3ed49f8bc9 Fix T47505: Cycles OpenCL rendering crash on Windows.
Restore the boost bug workaround, but without changing the locale.
2016-04-05 10:36:13 +02:00
0f3d558982 Cycles: Fix wrong camera-in-volume stack when camera ray hits volume domain twice 2016-04-05 10:36:13 +02:00
8e1e3e0228 Fix T48001: Highlighting selected item in filtered lists.
active index was not reset to 'nothing' in case actual active item was filtered out.
2016-04-05 10:36:13 +02:00
f4eb7e149a Knife Project: revert fix for T43896
For now leave precision at half a pixel until we have real fix.
Resolves T48023.
2016-04-05 10:36:12 +02:00
713669f7e6 Cycles: Support deformation motion blur for curves deformed by taper 2016-04-05 10:36:12 +02:00
Philipp Oeser
18875f6aa3 Fix T48013: UV Sculpt Brush Does not appear in UV window - but does show up in uv panels (t, n)
Epic fail in recent rB2c3985 :/

To be backported to 2.77a!
2016-04-05 10:36:12 +02:00
f590b2f89f Fix When using keying sets, the toggling "all items" in the array target only goes from the index value down, instead of keying all 2016-04-05 10:36:12 +02:00
81e8bd107f Hide layers from UI in template 2016-04-05 10:36:12 +02:00
a66116f543 Fix T48012: Knife Project crash 2016-04-05 10:36:12 +02:00
b3f08cddf3 Fix NULL check before free 2016-04-05 10:36:12 +02:00
3108861981 Cycles: Fix wrong initialization order of mesh flags and object transform 2016-04-05 10:36:12 +02:00
0fcb17fc4f Remove the obsolete windows launcher 2016-04-05 10:36:11 +02:00
02081f86d1 CMAKE disable building the windows launcher, fix type in delayloading of debug dll 2016-04-05 10:36:11 +02:00
8efe90f0a0 CMAKE / msvc openmp, delay loading of openmp dll so we can set environment
variable before it is loaded
2016-04-05 10:36:11 +02:00
315703d725 Cycles: Aligned vector was not covered by guarded stat
This was making stats printed by the logging being wrong: they did not
include such memory as BVH storage.
2016-04-05 10:36:11 +02:00
e69c02a392 cmake fix full debug builds on msvc 2016-04-05 10:36:11 +02:00
4960006b27 Fix T47985: VSE GL-render scene strip hangs
Regression in d5f1b9c22,
threading deadlock rendering a scene from the OpenGL preview.
2016-04-05 10:36:11 +02:00
e4b1b00884 Fix T47983: Particles - Emit from Verts emits double on one vert.
When non-random, particle distribution used a small start offset (to avoid
zero-weight faces), which is fine with "continuous" entities like faces, but not
for discrete ones like vertices - in that case it was generating some undesired
"jump" over a few verts in case step was small enough
(i.e. total number of verts/particles was big enough).
2016-04-05 10:36:11 +02:00
96b9f45d7a Partly fix (unreported) particles not updating correctly when changing settings.
Point-cached particles (those using simulations) would not update at all outside of
first frame, due to PSYS_RECALC_RESET flag being ingnored in `system_step()`...

For some mysterious reasons, udate is still non-fully functional outside of startframe
(e.g. changing face distribution between random and jittered), but at least when choosing
'Vertices' you get particles from verts and not faces!
2016-04-05 10:36:11 +02:00
4fc9178af9 CMake cleanup target_link_libraries_decoupled 2016-04-05 10:36:10 +02:00
357787b06b Fix T46623: OSX bpy.app.binary_path_python incorrect
CMake's PYTHON_EXECUTABLE wasn't set.
2016-04-05 10:36:10 +02:00
a80f3d7ddb Fix T48000: Eyedropper sample-merged ignored at first 2016-04-05 10:36:10 +02:00
97836b7250 Fix T47814: VSE Scene 'Use Sequence' fails
Conflict with flags between depsgraph and sequencer caused error.
Now pass state of sequencer parents to avoid recursion.
2016-04-05 10:36:10 +02:00
37a785241b Fix T47961: Wipe effects should have 2 inputs 2016-04-05 10:36:10 +02:00
2ad02b63e5 Fix T47967: Select next active fails in some cases
For cases when there are multiple matches,
find the closest match (with increasingly fuzzy tests) instead of failing.
2016-04-05 10:36:10 +02:00
d17f3c6d56 Fix T47987: Blender Cycles standalone does not properly read UV coordinates from XML 2016-04-05 10:36:10 +02:00
2265628964 Fix T47986: OBJ Import fails w/ imagepath encoding 2016-04-05 10:36:09 +02:00
261c12aab4 Fix T47958: Crash in Walk or Fly Navigation in Camera mode when invoking from non-3DView region 2016-04-05 10:36:09 +02:00
0f5ca755fc Fix T47969: Select Random always uses same seed
Increment the seed on each use,
otherwise calling again selects the same order, unless you manually adjust the seed.
2016-04-05 10:36:09 +02:00
611e544191 Fix T47972: Blender crash showing particle system.
Do same as with faces - if no orcodata is available, fill orco with current location...
2016-04-05 10:36:09 +02:00
8aed449528 Fix T47973: Render stamp ignores font alpha 2016-04-05 10:36:09 +02:00
f3259ae602 BLF: alpha support for drawing to buffer 2016-04-05 10:36:09 +02:00
49573b8e39 Fix T47931: Missed world shader update when having object dependency 2016-04-05 10:36:09 +02:00
edb1cc6fa8 Fix T47697: Smoke simulation doesn't work in viewport
Seems to be a division by zero error.

Should be safe for an upcoming 'a' release.
2016-04-05 10:36:09 +02:00
ee128c348f Fix T47962: It's possible to set a Sound strip as a modifier Mask. 2016-04-05 10:36:08 +02:00
18029edf1f Fix T47758: rigidbody bug with constraint breaking and disable collisions.
This is a regression in Bullet, reverted the problematic change for now with
a custom patch.
2016-04-05 10:36:08 +02:00
fa429b3f0c Fix T47668: Cycles OpenCL glass not rendering correctly on AMD.
Work around what appears to be a compiler bug.
2016-04-05 10:36:08 +02:00
7ea29d69df Fix T47935: Hair particles; The display percentage parameter breaks after a render is done.
Follow same logic in `psys_render_restore` as in `psys_render_set` - if hair and
display percentage is not 100%, we have to recompute particles...

With regular 'emitter' particles just hiding some is fine (though using random here
will not give a precise proportion...).
2016-04-05 10:36:08 +02:00
61aea37d35 Fix T47951: UserId problem on reload.
readfile.c would increment object usercount in three places, where it should not.
Remember kids: Objects are **only** refcounted by Scene's bases, and Object->proxy!
2016-04-05 10:36:08 +02:00
8aefea0c3a Fix Cycles debug panel, being shown in BI as well. 2016-04-05 10:36:08 +02:00
721f0089aa Fix T47928: Crashing save corruption with dynamic paint drip effector groups.
Dynapaint's `foreachIDLink` was mnot handling effector_weights->group pointer...
2016-04-05 10:36:08 +02:00
70d417cbe8 Revert "Fix T47263: numpad4/6 rotates around worl Z axis and not view Y axis."
This reverts commit fe0ca82b23.

This is a design issue, needs more thinking, for now just revert back to old behavior.
2016-04-05 10:36:08 +02:00
1af7bf3a20 Fix T47910: Knife project fails
Regression in fix for T43896, using screen-space precision here is very problematic,
using lower precision here works for both reports.
2016-04-05 10:36:07 +02:00
9a7d576332 Fix T47838: Walk gravity fails w/ intersecting objects
Regression in 3ad0344, fix from @mano-wii.

More comprehensive fix can be done after 2.77a.
2016-04-05 10:36:07 +02:00
5bfa814dcb Fix T47900: VSE adjustment crashes on blank frame 2016-04-05 10:36:07 +02:00
d21ed9af21 Fix T47893: BGE crashes w/ generated mesh data 2016-04-05 10:36:07 +02:00
e71398f3c7 Fix T47890: Vertex mask w/ subsurf select fails
Regression in GL refactor
2016-04-05 10:36:07 +02:00
744ef820d1 Fix incorrect strncat use 2016-04-05 10:36:07 +02:00
f601a4b4f7 Fix T47830: Multi-edit w/ ui-list wont highlight
Regression from 4d6b892.
2016-04-05 10:36:07 +02:00
0889f8c127 Fix for crash of point density textures due to undefined point_data on loading. 2016-04-05 10:36:06 +02:00
a3ef7c986c Fix add mesh template 2016-04-05 10:36:06 +02:00
Philipp Oeser
5ac7186633 Fix T47842: UV sculpt brush widgets are available when not in uv sculpt mode.
rB5b3af3dd made the poll function here slightly too laxist.

To be backported to 2.77 should we make an 'a' release.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D1861
2016-04-05 10:36:06 +02:00
7a7b242007 Fix T47862: VSE hard cut fails
Regression caused by changing how video length is calculated,
however similar problems could be caused by strip length changing on-disk.
2016-04-05 10:36:06 +02:00
f036e1875f GPU: avoid redundant logic for non-spot lamps 2016-04-05 10:36:06 +02:00
7e29ce8e96 Fix for non spot lamps calculating spot values
Logical error in D1378, also incorrectly used lamp type as a flag.
2016-04-05 10:36:06 +02:00
a5bc674e88 Include requests' cacert.pem file
This allows us to verify certificates of HTTPS connections, which is
mandatory for logins like on Blender ID.

Reviewers: campbellbarton

Differential Revision: https://developer.blender.org/D1845
2016-04-05 10:36:06 +02:00
4717824f55 Fix T47670: cycles GLSL incorrect normal map node. 2016-04-05 10:36:06 +02:00
4f3178e4a5 Fix T47670: cycles GLSL incorrect layer weight / fresnel.
World space and view space normals were mixed up, we should only convert from
world to view space if a custom normal is connected, otherwise it is already in
view space.
2016-04-05 10:36:05 +02:00
a8ee74ed61 fix for rare crash at loading stored constraints
added a null pointer check so to prevent a crash atleast
2016-04-04 10:54:19 +02:00
d7eeff23bf another fix attempt for occasional loading crashes 2016-04-01 16:30:46 +02:00
47adafe20d fix, forgot to set userpointer in point constraint 2016-04-01 09:46:58 +02:00
0ba11ae9b1 fix, forgot to load participating constraints per meshisland
this caused crashes when trying to simulate with percentage breaking
2016-04-01 01:53:56 +02:00
e62c4c822b fix attempt for crash on loading last blend (quit.blend with dynamic fracture) 2016-03-31 21:36:01 +02:00
790af966a3 crash fix for loading files with dynamic fracture enabled
forgot to set runtime listbase pointers of fractureIDs to NULL
2016-03-31 20:07:07 +02:00
b26e1ad0f1 fix for occasional crashes with dynamic fracture while freeing the modifier
crash happened with scene objects which had a freed rigidbody world but didnt set the pointer to NULL.
2016-03-31 13:19:14 +02:00
7befec292b fix for loading splitshards to island blends and clusters properly
was necessary to skip "empty shards" properly and keep cluster index
2016-03-31 11:27:06 +02:00
8c70dd87c6 a bit clean up and attempt to reduce dynamic fracture memory leaks 2016-03-30 23:09:52 +02:00
603b9dfbe9 dont suppress undo save/load with dynamic any more
this seems a bit more stable, but does crash occasionally too, and may even
corrupt the blend. Workaround, open with official blender and FM is gone, save
and blend should be usable again.
2016-03-30 15:17:54 +02:00
d3cdd5c237 fix for different constraint behavior after refracturing / reloading / param change
constraint enabled flags were changed during sim and next sim started with pre-broken
constraints this way... thus different behavior.
2016-03-30 15:05:21 +02:00
fc5ffd9694 store constraints for prefractured mode now too in blend
this automatically creates constraints from scratch as fallback for older files
2016-03-30 10:24:08 +02:00
9c79a5151e Fix T47758: rigidbody bug with constraint breaking and disable collisions.
This is a regression in Bullet, reverted the problematic change for now with
a custom patch (backported to Fracture Modifier)
2016-03-30 10:21:20 +02:00
dce55610df allow multiple dynamic destruction with extra particles or verts
this should allow triggered dynamic destruction with different colliders at different times. Note: WIP and crashes often in relation with undo
2016-03-29 15:24:13 +02:00
536578a189 fix attempt for some dynamic fracture rotation glitches 2016-03-27 23:19:32 +02:00
738bcd8a0c fix: crash when removing FM, ob->derivedFinal can become NULL in this case 2016-03-27 15:12:47 +02:00
3e2ed11690 keep objects completely intact with compounds and stability factor = 1 2016-03-27 15:11:46 +02:00
e1e6e2d04b stability factor should now influence overall stability of object more directly.
This should allow to control breaking behavior of the compounds better.
As before the masses still have the biggest influence to the breaking behavior, followed by thresholds and
connection count per shard.
2016-03-26 18:50:39 +01:00
45dbc3d19c attempt to make compounds a bit more predictable, they should work now when colliding with passive objects too 2016-03-26 16:07:04 +01:00
cfec6debb6 removed a double bad level call stub, found by jensverwiebe, thanks :) 2016-03-21 16:04:53 +01:00
3990ee1bb8 Merge remote-tracking branch 'refs/remotes/origin/blender-v2.77-release' into fracture_modifier
Conflicts:
	source/blender/windowmanager/intern/wm_operators.c
2016-03-21 11:39:38 +01:00
22a2853b5d Blender 2.77: Point submodules to an updated hashes 2016-03-18 17:34:06 +05:00
870f911e36 Revert "Fix button display clamping values"
This reverts commit e4e21480d6.
2016-03-18 16:45:58 +05:00
4522ee109b Blender 2.77; We are now at release cycle 2016-03-18 16:43:43 +05:00
fc37440216 Sequencer: expose GL preview alpha in scene UI
While this isn't essential, accessing this setting required navigating to each scene and using render menu.
Expose in sequencer UI for more convenient access.
2016-03-18 15:44:39 +05:00
6f49d970e0 Fix T47818: GPencil Sculpt Brush settings update when adjusted using scrollwheel while sculpting 2016-03-18 15:44:25 +05:00
4e53ca9ed2 Fix T47760: Toggling GPencil's "Selection Mask" via Python does not update UI
Add rna updates to greasepencil sculpt properties

D1849 by @lichtwerk, reviewed by @aligorith
2016-03-18 15:44:25 +05:00
48ae702c3c Fix missing 'anim_data' in RNA API of Freestyle's linestyle.
Reported by Manuel Rais on ML, thanks.
2016-03-18 15:44:25 +05:00
2b0f0ffe0a Fix T47763: 2.77 RC2 (Fluid) Particle Baking slower compared to 2.67b.
Static schedule was responsible here...

Also, made a minor optimization in case adaptative (auto) subframes are enabled,
gives a few percent of speedup here.
2016-03-18 15:44:25 +05:00
1e5c7e7a0d Fix T47807: Toggle header shortcut doesn't work 2016-03-18 15:44:25 +05:00
bbaffd7ede Fix T47759: Mesh 'Select less', leaves isolated verts
Select less in mesh edit-mode would leave selected vertices/edges
in edge/face mode which don't support selecting these elements.
2016-03-18 15:44:24 +05:00
bcfa73dfd3 Fix T47784: BMesh.from_object broken keyword args 2016-03-18 15:44:24 +05:00
4bb12140e3 Fix T47772: Randomize stroke has direction bias 2016-03-18 15:44:24 +05:00
e100a8598f Fix T47788: Symmetrize flips multi-res data
Symmetrize was unusable with multi-res data,
add an option for the bmesh operator not to flip the multi-res depth.
2016-03-18 15:44:24 +05:00
f0e52274ad Correct UI active state w/ bevel-factor
D1838 by @JacquesLucke
2016-03-18 15:44:24 +05:00
e511c7a34e Fix/workaround T47685: Drag keymap slider fails
This is a special case where the UI update function re-creases the keymap we're currently editing.
Making it so dragging values fails.
2016-03-18 15:44:24 +05:00
3d1f050608 Fix crash loading some library blend files
Blend files with screen but no scene would crash.
2016-03-18 15:44:23 +05:00
90758ed2e8 Fix T47827: Single Channel Preview Error
Fix by @sergey with own fix for big endian.
2016-03-18 15:44:23 +05:00
80b906cb31 Fix T47787: When performing operation 'Make single user' -> 'obj&data', object could be removed from group.
Similar cause as in T47482, we used to have poor handling of 'user_one' cases of ID usage,
leading to inconsistent behavior depending on order of operations e.g.

Here, was object used by a group but not linked in any scene - once linked in scene,
their usercount would be 2, leading to 'making single copy', when it's actually not needed.
We now have better control here, so let's use it!

Note that other ID 'make single user' code will likely need similar fix (Images, etc.).

Safe to be backported to 2.77.
2016-03-18 15:44:23 +05:00
8b49fa29ca Fix T47785: Rendering Crash, Node Connector Crash, Changing Editors Crash
Regressions after 2.76, to be backported to 2.77.
2016-03-18 15:44:23 +05:00
6d4f51212b Fix T47773: Particle System with Boids Crash.
Problem was, during initialization of boids particles in `dynamics_step()`,
psys of target objects was not obtained with generic `psys_get_target_system()`
as later in code, which could lead to some uninitialized `psys->tree` usage...

Think it's safe enough for 2.77, though not a regression.
2016-03-18 15:44:22 +05:00
ab44c20409 Fix bad UI range of convergence distance which was above the hard limit
That was rather confusing to slide the value.

Perhaps makesrna can check cases like this?
2016-03-18 15:44:22 +05:00
45b0e93b2e Cycles: Do no limit viewport samples to USHRT_MAX when value is at 0.
We don't limit manually setting higher values, this was probably overlooked here.

Found by @Blendify in IRC.
2016-03-18 15:44:21 +05:00
34510e3cce Fix crash adding EditNormals modifier to NURBS object (or other types but mesh).
Kinda stupid, but that eModifierTypeFlag_AcceptsCVs could really use a comment alongside
its definition!

Safe to be backported to 2.77.
2016-03-18 15:44:21 +05:00
de80ecc8fb Fix T47753: World equirectangular regression
D1729 fixed 'View' projection but broke 'Equirectangular'.

This commit also changes equirectangular projection to match Cycles and the viewport.
2016-03-18 15:44:21 +05:00
fc2f0a1a25 Fix T47749: Crash subdividing wire edge w/ mdisps 2016-03-18 15:44:21 +05:00
d402611c1d CMake: remove OSX version lookup table
This assumed the OSX SDK version matched the OSX version, which isn't always true.

Also problematic for maintenance and would make building older Blender versions on OSX fail.

Passing in pre-defined OSX_SYSTEM is also supported,
if you have multiple and want to select one.
2016-03-18 15:44:20 +05:00
6ebd48f353 Skip scopes update for render result during rendering 2016-03-18 15:44:20 +05:00
7268e6c58f Fix T47681: Bump node doesn't work with SSS shader when using OSL 2016-03-18 15:44:20 +05:00
Julian Eisel
c20bcba363 Fix T47706: 'CTRL ALT Left Mouse' clicking on the dope sheet summary line crashes Blender
Simple NULL-check seems fine here, working as it should now. Most likely caused by rBc4dc14b079d81.
2016-03-18 15:44:20 +05:00
1e2c8ca6ea Fix T47688: Regression in gl_load
Error caused by 771f73b6
2016-03-18 15:44:20 +05:00
88a3b68610 BMesh: avoid assert dissolving degenerate faces
For dissolving 2-sided faces, theres no need to check they are valid before removal.
2016-03-18 15:44:19 +05:00
1e1118e7e7 Blender 2.77: We are now RC2 2016-03-04 22:08:19 +05:00
1e7458258c Blender 2.77: Point translations submodule to updated branch 2016-03-04 22:03:16 +05:00
3636693612 Fix typo in 'Vietnamese' language label (must have sneaked in while adding Basque one, grr). 2016-03-04 21:47:54 +05:00
7cd6a5c221 Fix T47683: broken BBox logic when drawing duplis.
Once a dupli had a valid bbox, that bbox would be used for all following objects
without bbox, instead of skipping clipping check.

Issue unveiled by rB3fa0a1a5bc0ff2, but not related at all (in fact, bug was present before that commit).
2016-03-04 21:12:00 +05:00
15ac4b4f9b Fix uninitialized memory use lattice-boundbox
Many other places weren't clearing boundbox dirty flag after calculation.
2016-03-04 21:12:00 +05:00
ce4a8210b3 Curve/line width change broke outline drawing
Partially revert e29a5ba6
2016-03-04 21:11:59 +05:00
Julian Eisel
67d310459d Fix T47674: "Change Data/Files" setting incorrect filter
Image filter was not set, but only if invoked from toolbar (image strip needs to be selected to see the button).
Caused by rB7fa72b8970, Wasn't aware there's another button for this for image strips.
2016-03-04 21:11:59 +05:00
b805b3735c Render Save Buffers: Use proper memory buffer size for a display buffer 2016-03-04 21:11:59 +05:00
ff32f81fd2 UI: move checkbox for missing add-ons to LHS 2016-03-04 21:11:59 +05:00
a78d679ddd Fix RNA property clamp assigning in Python
On first assignment the value was clamped, but successive assignments weren't.
2016-03-04 21:11:59 +05:00
5cbd14241f Edit Mesh: Edge tag toggle when no active path is found
User request, this matches 2.6x behavior more closely.
2016-03-04 21:11:59 +05:00
c82e6fe80b PyAPI: correct function name w/ arg parsing 2016-03-04 21:11:58 +05:00
50f188814f Fix T47676: Broken default values for particle brush strength.
Current startup .blend has old (percent?) values for particle brush strength.

Since rBe4e21480d6331903c90ab073746484498441e1ac, UI controls do not clamp automatically values anymore,
which means when you first enable comb (or any other brush) you get a 50 strength, waaaayyyy to powerful.

This commit fixes this in `BLO_update_defaults_startup_blend`, note that it does not fix custom users'
startup files, nothing to do here...
2016-03-04 21:11:58 +05:00
b00822e42d Fix T47644: crash (use-after-free) regression from rB7a74738914a66e.
Handling `me` data here is not good idea anyway, we override it completly with data
from `tmp` (crash came from freeing already existing bb from me, while pointer still existed in tmp).

(rediscovered it while working on T47676...).

To be backported to 2.77.
2016-03-04 21:11:58 +05:00
67b16c6170 Fix T47564: Unwrapping the same mesh results in different UVs.
Pointers of faces were passed as face keys during parametrizer's face creation. Since those
addresses were different for every run, the layout of the faces ended up being different
in the internal hash, leading to inconsistent order of their evaluation during LSCM solving,
and slightly different UV maps.

Solved by simply using faces' indices as key instead, which ensures we always get same results
with exact same input data now.

Many thanks to Roman Nagornov (RomanN) for raising the issue, investigating it and finding
the solution! And thanks to Brecht for quick review too.
2016-03-04 21:11:58 +05:00
3382ba0238 Cycles: Fix wrong default value for volume samples 2016-03-04 21:11:58 +05:00
d1efd44c1d Fix assert in UI code
Dont attempt to clip empty string
2016-03-04 21:11:57 +05:00
198700a36d Fix T47642: Crash baking w/ cycles 2016-03-04 21:11:57 +05:00
322fa27829 Fix T47635: Texture paint performance regression
Flipped bindcode check in D1414 caused projection paint to always do full updates.
2016-03-04 21:11:57 +05:00
562a488fb0 Add Basque (Euskara) new language.
Nothing critical, but would be nice to backport this to 2.77.
2016-03-04 21:11:57 +05:00
0c32f755a6 Fix T47643: Blender crash. Linked speaker issue.
Speaker's localization func would not make direct-linked its used sound datablock...
2016-03-04 21:11:57 +05:00
aa177d48c7 Fix T47638: Bad auto-smooth value for new meshes
Code was using degrees as radians.

Still unclear why default cube will have 180 degrees angle, but new meshes 30,
but that's kinda separate topic which is to be addressed separately.

This is a subject for final 2.77 release.
2016-03-04 21:11:57 +05:00
6a97b9c4a2 Fix (unreported) crash when opening a file from splash screen when 'load UI' option is disabled.
See rB935e241fa6ea095493 for details of the issue, but first fix caused regression T47632.

So for now handling the issue in a localized way, this is not a real solution (since this could happen
in other cases), but will do for 2.77.

This commit is to be backported to 2.77.
2016-03-04 21:11:57 +05:00
01485b389a Fix T47632: Revert "Fix (unreported) crash when opening a file from splash screen when 'load UI' option is disabled."
This reverts commit 935e241fa6.

Issue will be fixed in a more localized way for now (not that nice, since this use-after-free can possibly happen
in other places too, but only safe solution for 2.77).

This commit is to be backported in 2.77.
2016-03-04 21:11:57 +05:00
91457def83 Fix T47604: Sculpt + Modifier undo gives invalid normals 2016-03-04 21:11:56 +05:00
28e4f8eb5c Fix T47615: crash trying to use point density with lamp object. 2016-03-04 21:11:56 +05:00
550215a65e Cycles: Fix compilation error of certain OpenCL split kernels 2016-03-04 21:11:56 +05:00
77f96266e8 Fix T47608: Cycles cage baking crash after recent uv derivative fixes. 2016-03-04 21:11:56 +05:00
42fd804cca Fix T47605: Elsyiun theme info text hard to read 2016-03-04 21:11:56 +05:00
2d5343cd92 Fix T47582: Curve handle thickness regression 2016-03-04 21:11:56 +05:00
86bb5f70d6 Fix T47586: Nurbs handle thickness regression 2016-03-04 21:11:56 +05:00
9fcc849aa3 Fix T47583: Mesh wire edge thickness regression 2016-03-04 21:11:55 +05:00
9867042ab0 Fix T47592: Wrong line width w/ custom-bones 2016-03-04 21:11:55 +05:00
2c3c8fbaed Docs: early exist build process on error
Don't attempt to build docs when generation fails.
2016-03-04 21:11:55 +05:00
02b0f51164 Docs: Add missing context members 2016-03-04 21:11:55 +05:00
61e848280e Fix T47596: Bone motion path - confusing UI in 3DView tools.
Now using same UI as in object/armature properties, also save one line in 3DView panesl. ;)

Nothing crucial there, but nice & safe to backport to 2.77 imho.
2016-03-04 21:11:55 +05:00
e956ebd0f9 Fix T47593: 'Move to layer' will be crash in blender 2.77rc1.
To be backported to 2.77.
2016-03-04 21:11:54 +05:00
43429578d3 fix, should need to fracture only once now in case you enable split shards to islands with constraints or clusters on 2016-03-01 20:36:36 +01:00
9c33f3db3f partial fix for suddenly missing self-collision of shards of the same object, this happened even after converting to regular rigidbodies when disable collisions was active ! (so this is now off by default) 2016-03-01 18:27:42 +01:00
66ffb880bc fix for loading inner vertex groups and set min weight for passive vertexgroups to 0.01, just keeping it > 0 did not yield correct results when passive vertexgroups were used 2016-02-28 10:24:37 +01:00
1b85ceabc5 fix for loading files, need to skip "empty" shards which dont have any mesh info because they didnt intersect with the original geometry, before this each meshisland stored a temp shard, now we lookup shards out of the shard map instead, but this could point to such empty shards, leading to incorrectly loaded files. 2016-02-27 14:06:33 +01:00
b594b25dad Fix: "Twist" GP Sculpt brush in 2D Editors was unusable... now mostly usable, if still slightly offset 2016-02-26 13:32:47 +01:00
9c474b187a Fix: "Twist" GP Sculpt brush didn't work well in 3D View 2016-02-26 13:32:44 +01:00
4df911aa58 2.77 splash
by Pokedstudio
2016-02-26 12:53:40 +01:00
00ca17acaa Blender 2.77 release: Point submodules to a release branches 2016-02-26 12:12:11 +01:00
f0f38731db fix for wrong transformation of shards after loading (and fix for potential crashers while loading) 2016-02-21 19:53:04 +01:00
3db5b76201 compile fix after merge 2016-02-21 13:27:46 +01:00
1c09344dba Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier
Conflicts:
	CMakeLists.txt
	SConstruct
	build_files/build_environment/install_deps.sh
	build_files/scons/tools/Blender.py
	build_files/scons/tools/btools.py
	extern/CMakeLists.txt
	extern/SConscript
	extern/bullet2/CMakeLists.txt
	intern/cycles/blender/blender_camera.cpp
	intern/cycles/blender/blender_texture.cpp
	intern/cycles/kernel/geom/geom_triangle_intersect.h
	intern/cycles/kernel/kernel_compat_cpu.h
	intern/cycles/kernel/svm/svm_voxel.h
	intern/cycles/util/util_path.cpp
	intern/ghost/intern/GHOST_ContextGLX.cpp
	intern/iksolver/intern/IK_Solver.cpp
	release/datafiles/locale
	release/scripts/addons
	release/scripts/startup/bl_ui/space_userpref.py
	source/blender/blenkernel/BKE_blender.h
	source/blender/blenkernel/BKE_bvhutils.h
	source/blender/blenkernel/SConscript
	source/blender/blenkernel/intern/DerivedMesh.c
	source/blender/blenkernel/intern/armature.c
	source/blender/blenkernel/intern/cdderivedmesh.c
	source/blender/blenkernel/intern/editderivedmesh.c
	source/blender/blenkernel/intern/image.c
	source/blender/blenkernel/intern/mesh_remap.c
	source/blender/blenkernel/intern/particle.c
	source/blender/blenkernel/intern/rigidbody.c
	source/blender/blenlib/intern/string.c
	source/blender/blenloader/intern/readfile.c
	source/blender/editors/interface/interface.c
	source/blender/editors/interface/interface_handlers.c
	source/blender/editors/mesh/editmesh_knife.c
	source/blender/editors/mesh/editmesh_select.c
	source/blender/editors/object/object_bake_api.c
	source/blender/editors/space_graph/graph_ops.c
	source/blender/editors/space_outliner/outliner_intern.h
	source/blender/editors/space_outliner/outliner_tools.c
	source/blender/editors/space_sequencer/sequencer_edit.c
	source/blender/editors/space_view3d/drawmesh.c
	source/blender/editors/space_view3d/drawobject.c
	source/blender/editors/transform/transform_conversions.c
	source/blender/editors/transform/transform_input.c
	source/blender/editors/transform/transform_snap.c
	source/blender/makesdna/intern/makesdna.c
	source/blender/makesrna/SConscript
	source/blender/makesrna/intern/SConscript
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/makesrna/intern/rna_nodetree.c
	source/blender/makesrna/intern/rna_rigidbody.c
	source/blender/modifiers/SConscript
	source/blender/python/mathutils/mathutils_geometry.c
	source/blender/render/extern/include/RE_render_ext.h
	source/blender/render/intern/source/bake_api.c
	source/blender/render/intern/source/pipeline.c
	source/blender/render/intern/source/pointdensity.c
	source/blender/render/intern/source/renderdatabase.c
	source/blender/windowmanager/WM_api.h
	source/blender/windowmanager/intern/wm_files.c
	source/blenderplayer/bad_level_call_stubs/stubs.c
	source/gameengine/Ketsji/BL_Action.cpp
2016-02-21 13:27:17 +01:00
eca5449a29 change: let fluid move down across other modifiers in case it will be added after fracture which has a couple of other modifiers above it (exception for fluid only, since it can handle shards) 2016-02-11 11:55:30 +01:00
1051f71291 fix for material loading in FM external mode and generally decreased file loading times, especially noticeable with large FM objects, by using sorted fd->datamap in readfile.c (avoids linear search) 2016-02-09 17:45:34 +01:00
ca21fc8b55 fix, forgot to activate plastic connection handler in external mode 2016-02-08 21:49:40 +01:00
f66e70a855 fix for external mode material collection function 2016-02-08 17:24:51 +01:00
00ccb99a67 fix for name and indexbased meshisland and meshconstraint lookup via python inside the FM 2016-02-05 12:29:23 +01:00
9c744358a5 fix: there was a speed regression when building many constraints during fracture or after loading 2016-02-04 23:14:10 +01:00
80def34da1 some more mutex locking for dynamic fracture, there still were crashes when interactively moving dynamic objects during running sim 2016-02-04 20:19:57 +01:00
25057ba379 added threading lock to modifier sync during rigidbody object sync, helps against crashes in dynamic mode 2016-02-04 19:53:45 +01:00
2b0a6aa5bc improved output of constraint impulse visualization a bit, included name, impulse and threshold as well as attempted to offset strings at same position 2016-02-03 19:37:54 +01:00
03db2ca8e7 windows compile fix 2016-02-03 16:14:28 +01:00
5a834c1608 added constraint impulse visualization (very basic only) and reworked the mesh constraint name system 2016-02-03 14:46:31 +01:00
55b2d46f15 compile fix for windows and mac 2016-02-02 15:47:06 +01:00
b1e4964ede added basic physics visualization for viewport rigidbodies like in game engine (its optional and can be turned off) 2016-02-02 14:01:46 +01:00
9e9bbed144 ignore individual mesh island transforms in rigidbody system again and just re-apply them when converting back to objects, it just caused trouble and brought not the expected result 2016-02-01 14:02:30 +01:00
509bf61c21 fixes for: did assume autohide material was always at number 1, did change to find inner material number, own verts transformation bug, shards to islands delay bug (needed to click twice before), and some crashers with dynamic and prefractured as well as reduced a memoryleak in prefracture mode 2016-01-31 22:45:30 +01:00
87f895311f some more effort to make FM simulation results looking closer to BCB simulation results 2016-01-31 01:59:35 +01:00
12f7fd5a08 attempt to reduce a memoryleak 2016-01-30 16:42:34 +01:00
03a4109930 exposed bullet tick callback to bpy.app.handlers, also wrapped the passed timestep into the rigidbody world, so it can be accessed too 2016-01-30 16:03:26 +01:00
b85da312f0 fixes for dynamic and external mode, in external mode each simulation run should be consistent with the prior ones now 2016-01-30 15:57:56 +01:00
819bc74e22 fix, small typo in appliedImpulse soft limit (read only) 2016-01-29 11:11:37 +01:00
c073d7cf60 added appliedImpulse() to regular constraints too 2016-01-28 23:30:39 +01:00
0c4939c013 added a RNA function to read the appliedImpulse from each constraints live, during simulation (slow when done from a python frame handler over all constraints) 2016-01-28 23:04:12 +01:00
39e00e5959 fix: dynamic mode didnt work at all anymore and has still some issues like flickering after baking and a crasher on exiting blender, also testwise enabled autoexecute on prefracture during sim 2016-01-28 21:01:14 +01:00
0ab52e7f51 fix: added extra update call on hook object in custom modifier evaluation 2016-01-27 23:46:38 +01:00
84696d3c75 fix: forgot to accumulate differences of multiple hook modifier changes 2016-01-27 21:58:08 +01:00
d5d33dbd40 fix: fake parenting in testfile didnt work anymore after fake hook was added to code, now both should work depending on whether the kinematic flag is set (=parenting) or not (=hook, if vertexgroup and hookmodifiers are used) 2016-01-27 21:19:05 +01:00
45435120f3 fix for silly brace mistake, which led to crash with fracturing a default cube 2016-01-27 20:08:21 +01:00
bcc260c778 improved the fake hook system, should behave now exactly as a regular hook and added some FM code comments to plan further work. 2016-01-27 18:23:15 +01:00
2cbd8c9d44 added handling of vertexgroups and a fake hook system inside the FM, so passive shards can be influenced by hook modifiers via vertexgroups. 2016-01-26 21:34:05 +01:00
5ad7a248a3 fixed two crashers: 1) when object had no material, that assignment failed. 2) constraints with empty meshislands crashed too 2016-01-26 01:03:12 +01:00
0adaddd4c4 fix for passive parenting hack, it was not taken into account after transforming the object interactively 2016-01-25 17:58:27 +01:00
1dd3595443 added a fake parenting for passive shards, those are simply moved with the object itself, so you can parent the entire object and have exact motion data in the passive shards 2016-01-25 17:47:18 +01:00
e29680e0e2 forgot to take some rigidbody settings into account during object conversion 2016-01-24 19:11:03 +01:00
6efacde5c0 fix for possible rotation glitch when converting back to objects 2016-01-24 17:46:35 +01:00
7023be40be fix for Fracture Modifier to object converter (external mode), not all settings were taken into account, and object disappeared when not being on startframe, but as converting mid-sim yields unexpected results, still limiting conversion to startframe, added a notification for this 2016-01-24 17:18:28 +01:00
d50a3d7097 added dynamic threshold adaption in case of changing timesteps for plastic constraints, also enabling plastic constraints in case they enter plastic state now 2016-01-24 15:51:13 +01:00
62ac065a4c fix for windows only: avoiding changing the global locale avoids slowdown in windows string operations 2016-01-24 13:02:34 +01:00
e476e50b61 fix: spring constraints were not created properly while setting up the simulation 2016-01-24 00:57:17 +01:00
90b76659ca some more fixes to have proper plastic constraint support 2016-01-23 21:40:40 +01:00
0384b49e14 fix for material assignment to meshislands, dont create unnecessary material slots any more 2016-01-22 10:33:20 +01:00
50e308c19c taking now all constraint properties into account when converting back to objects 2016-01-22 01:56:31 +01:00
7b4a37b1b0 partial fix, take proper constraint locations and rotations into account when converting back to objects, but todo, take own object transform into account too 2016-01-22 00:36:14 +01:00
8e79bae2eb added names for meshislands, can now convert back to named objects, added load / save support (was missing) 2016-01-22 00:00:29 +01:00
3d36d357c2 fixes for the monitoring logic of plastic constraints, again 2016-01-21 19:42:27 +01:00
e2670b3814 fixes for correct rotation calculation in prefractured and external mode 2016-01-21 12:02:00 +01:00
7c3c6f8310 used more exact angle calculation method for external mode, different formulae for tolerances, and some cleanup of obsolete stuff. 2016-01-21 02:12:48 +01:00
7761311305 added material handling (so meshislands get correct materials from original objects) and added plastic tolerance values, which are taken into account with special simulation mode only. 2016-01-20 23:30:55 +01:00
340798fe56 reduced a performance bottleneck when adding many constraints in a loop, do not trigger modifier updates or set validate flags or even call bullet functions... but todo is to keep a useful update mechanism 2016-01-20 18:42:49 +01:00
b8c63aead5 avoid resetting cache (and iterating possibly through the rigidbody group) when adding mesh constraints 2016-01-20 00:40:22 +01:00
3553669d12 attempt to make mesh island packing faster when being called in a loop, create the dm only once after packing 2016-01-20 00:23:33 +01:00
35701ed26e crash fix in FM refresh operator (null pointer access) 2016-01-19 23:23:43 +01:00
982f94f269 rigidbody type on meshisland should be taken into account now properly and be settable, also adding new constraints should happen faster now (when called in a loop) 2016-01-19 21:20:28 +01:00
eb8af755dd further attempt to fix "plastic constraint" logic (external fracturing mode only) 2016-01-19 19:02:55 +01:00
dede676e90 implemented some special constraint breaking method further (plastic constraint breaking), for external fracturing mode 2016-01-18 21:59:07 +01:00
1ae8bcc8e6 exposed per-constraint breaking angle and distance to python (for external mode only, for now) 2016-01-18 19:55:10 +01:00
b800df49d7 fixed constraint restore with external fracture mode (using participants instead of jumping around in list, which messes up the iteration loop) 2016-01-18 18:03:20 +01:00
66242f5e76 constraints transformation fix, transformations are updated on validation now 2016-01-18 01:33:45 +01:00
df389e31d6 first successful simulation attempt with a bigger test data set, todo... set constraints relative to object , multiply with obmat during evaluation 2016-01-18 00:51:44 +01:00
8d58ffe0be extended FM python API: constraints have now settable locations and rotations, additionally there is an highly experimental constraint breaking mode (for external fracture mode ONLY) 2016-01-17 19:33:06 +01:00
f7fa6906e6 initial, basic python API for Fracture Modifier contents: mesh_islands and mesh_constraints are createable, removable externally prior to running the simulation (in special "External" fracturing mode) so you can pack objects into the modifier (as mesh islands) and set constraints to connect them. This can happen in immediate update mode or updating is done via refresh operator. You can also have read access for island data after simulation, to dump the results. 2016-01-17 16:14:48 +01:00
b1c3782c46 added activation by force, if force exceeds an adjustable threshold, kinematic rigidbodies get activated / triggered by a force field 2016-01-14 13:04:10 +01:00
84d8b15a18 set shards to passive if shard weight (average vertex weight) is > 0.0f instead of 0.5f, this allows to keep shards passive in case they dont get enough weightpaint (in case they are inside, and interpolation of weights is not enough) 2016-01-06 18:27:46 +01:00
d34550c126 fixes: lower stability factor now lets the object break earlier ( effect was inverted) and added uv_layer to fracture presets (was missing) 2016-01-05 15:55:20 +01:00
093a5501bf taking stability factor now into account at dummy constraint calculation for compounds, it influences search radius and limit now, too 2016-01-04 21:08:49 +01:00
9ad72754c6 attempt to get more control over compound destruction behavior during simulation, with stability factor; recursive breaking of neighborhood happens if one connection breaks 2016-01-04 19:46:13 +01:00
f1981b3cfc partial fix for displacement / autohide flicker problem, happens now only with automerge (occasionally) and with automerge + fix normals (regularly), but for displacement and glass you mostly need only autohide; automerge and fix normals are for smooth objects where cracks should be nearly invisible (after fracturing) 2015-12-30 20:47:25 +01:00
24ff36d84b added an autohide filter group, its helpers can be used to animate revelation of cracks which are hidden otherwise. This is basic revelation functionality via object locations and sizes only. 2015-12-28 15:04:07 +01:00
d8b561de76 fix: make sure a rigidbody exists on each mesh island after loading when trying to access it 2015-11-29 19:59:47 +01:00
5d554ca7ea enabled trigger in dynamic fracture again, fix for cache stopping problem as well 2015-11-10 09:54:55 +01:00
2ea86a8817 fix for dynamic fracture rotation glitch (was wrong calculation) 2015-11-09 10:59:46 +01:00
5f796ef1ef attempt to fix customdata related memoryleak... it has been reduced, but isnt completely gone yet 2015-11-06 12:55:58 +01:00
e237ef3a40 minor fix for removed fracture setting in preset 2015-11-04 18:07:30 +01:00
e141527ddb Merge remote-tracking branch 'refs/remotes/origin/blender-v2.76-release' into fracture_modifier
Conflicts:
	release/scripts/addons
	source/blender/windowmanager/intern/wm_operators.c
2015-11-04 18:01:12 +01:00
0076ba4833 deactivated the unfinished multiple fracture settings per object for now, didnt work properly 2015-11-04 15:21:27 +01:00
ca18f5ddd4 added inner uv map setting, which will contain only inner face's UVs, useful for texture based inner smoke in conjunction with fracture modifier 2015-11-04 15:05:19 +01:00
f337feaf5a BLender 2.76: We go 'b' series now 2015-11-03 15:56:35 +05:00
936a685ea8 Don't expand toggle brush on linking
Toggle brush is more a runtime only feature, not really supposed to be used
as real ID linking as it's done for modifiers i.e.
2015-11-03 15:49:54 +05:00
b8438a870d Fix T46626: Crash generating previews
Brush.toggle_brush was allowed to be an invalid pointer,
it worked for the one operator that used it - but in general bad practice,
requiring a lookup on every access.

Ensure the pointer is kept valid now.
2015-11-03 15:49:38 +05:00
e5ccc1e19d Fix/workaround T46622: crash w/ metas & particles
Metas are scanning all scenes duplis,
which can go into particle systems without an initialized derived-mesh.

For now just do NULL check, its not correct but real fix is not fitting well with current design.
2015-11-03 15:49:18 +05:00
3c54514354 dynamic fracture should be bake and saveable now, but still has rotation glitches and glitches with change in mesh island sequence. 2015-11-02 14:12:15 +01:00
d7daecccbd Fix T46651: Select linked crash w/ wire seam edges 2015-10-31 19:26:47 +11:00
b611bdb629 Revert "Fix T46494: Can't de-select a face w/ mixed modes"
This reverts commit 381501ab45.
2015-10-31 19:26:11 +11:00
c9cd41547c added basic support to clean up keyframes directly after converting to keyframed objects, but you need cache to bake so the operator can run again (and it will refracture automatically, too) 2015-10-30 19:12:17 +01:00
c794d87f12 optimization: when converting to keyframed objects, do not key passive shards any more (as they dont move anyway) 2015-10-30 11:46:51 +01:00
12e4da6c1a Fix T46507: Cycles baking re-orders face
Regression in 2.76, order of tessellated vertices needs to follow MFace tessellation.
2015-10-30 13:43:59 +05:00
de96d1acd1 Blender 2.76a: Fix CUDA compilation on 32bit platform 2015-10-29 20:11:22 +05:00
379a754b83 changed volume calculation method for convex hull and triangle meshes, mass fractions should be calculated more accurately now, but note, might change behavior of older simulations !!! 2015-10-29 15:58:27 +01:00
b5e4cc820b BLender 2.76a: Update addons submodule 2015-10-29 17:26:14 +05:00
bc9f118169 Set blender version to '2.76a' 2015-10-29 22:08:52 +11:00
74055fb813 Cleanup: quiet warning
Not cherry picked, just included for release build.
2015-10-29 21:32:47 +11:00
Dalai Felinto
b1eff080bd Temporary "fix" for crash when saving OpenEXR Multi-View from Image Editor 2015-10-29 21:10:17 +11:00
Dalai Felinto
c2337748e5 Fix T46617 File Output Node seems to save only black images into OpenEXR image data
If the node output had only one layer, it would be detected as singlelayer, and it would miss the blender exr header string
2015-10-29 21:10:17 +11:00
f30a270a70 Freestyle: Fix for 'Distance from Object' modifiers without a target object.
'Distance from Object' color/alpha/thickness modifiers without a target
object were raising a run-time exception although it is not considered an
error condition.
2015-10-29 21:10:17 +11:00
424ea476b1 Fix T44231: Freestyle causes crash on render.
The reported crash was confirmed as a segmentation fault in std::sort().
The cause of the crash was traced down to a binary comparison function
that was not satisfying the so-called strict weak ordering requirements of
the C++ standard sorting function.  Specifically, the comparison operator
has to return false when two objects are equivalent (i.e., comp(a, a) must
be false), but that requirement was not met.

Since the binary comparison operator in question could be a user-defined
Python function, here a safety measure is implemented in the C++ layer to
make sure the aforementioned requirement is always satisfied.
2015-10-29 21:10:17 +11:00
1823e56625 Follow up to previous commit, proper fix for T46284, incorrect Texture
shading in Texture paint mode and cycles
2015-10-29 21:10:17 +11:00
25beefa8dd Revert "Fix T46284: Texture paint, wrong shading mode"
Should fix T46616 but will reintroduce T46284.
The second, original bug needs different handling

This reverts commit 904db487a7.
2015-10-29 21:10:17 +11:00
887e5cb7b0 Fix T46605: Compositing causes access violation when rendering from command line
Seems was caused by the race condition in the stats printing, should be all fine now.

Nice for 'a' release.
2015-10-29 21:10:16 +11:00
4eb34dbc88 OpenSubdiv: Fix wrong handling of vertex parent
Vertex parent was not registered as CPU data requirement.

Should be in the 'a' release.
2015-10-29 21:10:16 +11:00
8026a1d543 Fix T46606: Trackball Rotate jumps releasing shift 2015-10-29 21:10:16 +11:00
13c473f707 Fix broken comment about our WM progress report for python (its not a progress bar at all). 2015-10-29 21:10:16 +11:00
c2e7f6d5b4 Fix T46604: Crash in ChainPredicateIterator instantiated without predicates.
Also fixed a potential crash in the copy constructor case.
2015-10-29 21:10:16 +11:00
349abb5f58 Freestyle: minor speed-up by omitting the calculation of the smallest edge size.
BlenderFileLoader tries to find the smallest edge size but the computed value is not used.
2015-10-29 21:10:16 +11:00
299f647004 Fix: Prevent warnings from popping up when trying to edit driver expressions from buttons
Previously, a warning was added to provide feedback to users trying to change the values
of driven properties why their edits would not have any effect on the propeerty. However,
it turned out that instead of only showing up when the user tried to increment/decrement/slide
the property's value, it was also firing everytime they were trying to edit the expression.
That however is not what we want at all!

This fix assumes that BUTTON_STATE_TEXT_EDITING is used for expression editing, and
BUTTON_STATE_NUM_EDITING (or everything else) refers to the user trying to adjust the
value normally.
2015-10-29 21:10:16 +11:00
1ce73aa72b Fix T46599: Copy Rotation behaves erratically when Use Y is disabled
When the "Use Y" option in the Copy Rotation constraint is disabled, the constraint
behaves eratically when rotating all the target on all axes at the same time.
This is partially to be expected due to the way that euler rotations work
(i.e. the rotation orders stuff - you should use a rotation order based on most to
least important/significant rotations). Hence, by locking Y, you're causing accuracy
problems for Z.

What was not expected though was that changing the rotation orders on the objects
involved (for the record, it's the constraint owner that counts) did nothing.
It turns out that for objects, the rotation order settings were getting ignored!
This commit fixes this problem, and this particular case can be resolved by using
"XZY".

Notes:
* Since all object constraints were previously working on the assumption that they
  used XYZ (default) order, it is possible that this change may have the unintended
  consequence of changing the behaviour of some rigs which relied on the buggy
  behaviour. Hopefully this will be a rare occurrence.
2015-10-29 21:10:15 +11:00
4081dab9d5 Fix: Missing update after scrubbing time in Graph Editor
Sometimes the timeline header didn't update after time-scrubbing in the graph
editor ends, leaving the "Pause" button visible until the next refresh of the
timeline (e.g. on mouse over)
2015-10-29 21:10:15 +11:00
ebc899790b Fix: X-axis values in Graph Editor should not be displayed as timecodes in "Drivers" mode 2015-10-29 21:10:15 +11:00
95cc31fdcd Fix error in bone UI 2015-10-29 21:10:15 +11:00
50ecd510bb Fix invalid exceptions w/ preview API
D1575 by @januz
2015-10-29 21:10:15 +11:00
ca51398fd8 Fix T46538: Mark and Clear Seam in UV Editor, assigning Hotkeys.
UV Editor keymap is not bound to a given editor (spacetype)...
2015-10-29 21:10:15 +11:00
ff5a34e370 Fix related to T46538: do not popup choice menu of mark/clear seam UV editor op invoke when prop is already set! 2015-10-29 21:10:15 +11:00
4aac73a86f Correct own error w/ snap-scale T46503
Don't use nan for comparisons.
2015-10-29 21:10:15 +11:00
d1c6364099 Fix ffmpeg memory leaks
- audio_stream wasn't freed.
- audio/video stream + context weren't freed on failure.
2015-10-29 21:10:15 +11:00
c01e9cefe1 Fix ffmpeg saving long paths
Was checking wrong length on string copy.
2015-10-29 21:10:14 +11:00
e54f38ebf0 Fix for error w/ RenderView in ImageView list 2015-10-29 21:10:14 +11:00
15364094d0 Fix snap-scale w/ axis constraint
Related to T46503,
fix only worked when the snap target was axis-aligned.
2015-10-29 21:10:14 +11:00
62a973db31 BGE: Fix T46556: check on null sound datablock pointer. 2015-10-29 21:10:14 +11:00
3f067c61a0 Cycles: Watertight fix for SSS intersection
Same as previous commit, just was missing in there.
2015-10-29 21:10:14 +11:00
673bc6d65a Cycles: Fix for watertight intersection
It was possible to miss some intersection caused by wrong barycentric
coordinates sign.

Cases when one of the coordinate is zero and other are negative was not
handled correct.
2015-10-29 21:10:14 +11:00
ce268f6005 Fix T46521: Python: bvh.ray_cast doesn't find a plane facing in the other direction under certain circumstances
The issue was caused by wrong sign check. It originally came from more optimized
Cycles code where because of other reasons it wasn't visible yet. But in fact it
should be solved there as well.
2015-10-29 21:10:14 +11:00
54f1e682c6 Fix T46569: Crash w/ mask & locked-track enabled 2015-10-29 21:10:14 +11:00
4d581c01cc Fix T46561: Crash in outliner delete hierarchy
When children & parents were selected in the outliner,
it attempted to free the the object twice.
2015-10-29 21:10:14 +11:00
e1f5433f1d Fix T46565: Movie render crash w/o permissions
Rendering to a path that didn't have write permissions would crash.

Also fix error where `G.is_rendering` was left set when rendering failed.
2015-10-29 21:10:13 +11:00
7d070f97ad Fix T46524: Use Alpha (Straight/Premultiply) option missing in 2.76, part II.
Different issue actually, here RAWTGA was simply forgotten in the alpha-capable formats...
2015-10-29 21:10:13 +11:00
e8b3ba2983 BGE: Fix physics meshes conversion with modifiers.
Previously meshes with modifiers were considerate as empty (no polys).
2015-10-29 21:10:13 +11:00
be4ee42e1c Fix T46544: Can't unpack generated image 2015-10-29 21:10:13 +11:00
bedc58ac4e BGE: Fix T46381 : last action frame not updated.
It fix T46381. Normally BL_Action::Update (manage action time, end, loop…) should be called the same number of times as BL_Action::UpdateIPO (update action position, scale ect… in the game object).
But the bug report shows that UpdateIPO is called one less time than Update. To fix it i revert the commit 362b25b382 and implement a mutex in BL_Action::Update.
Example file : {F245823}

Reviewers: lordloki, kupoman, campbellbarton, youle, moguri, sybren

Reviewed By: youle, moguri, sybren

Maniphest Tasks: T39928, T46381

Differential Revision: https://developer.blender.org/D1562
2015-10-29 21:10:13 +11:00
349609c743 Fix T46529: Unwrap UV w/ use-subsurf fails
Regression since moving to looptri.
2015-10-29 21:10:13 +11:00
60ad008162 Fix T46531: Cannot use % in filenames.
Same case as with space char really, one should not use those special chars in
filenames, but they are globally supported by all current FS/OS, so no real reason
to enforce that behvior on users here.

To be backported to 'a' release.
2015-10-29 21:10:13 +11:00
34def18764 Fix T46520: mathutils.bvhtree crashes with distance input.
Should be backported to 'a' release.
2015-10-29 21:10:13 +11:00
0afdd1139b Fix T46524: Use Alpha (Straight/Premultiply) option missing in 2.76 for DDS files.
All optional image format are not #define'd in submodules like DDS read/write code.
This means values of `eImbTypes` would not always be the same in all contexts, yuck!

This is a regression and should be backported to 'a' release.
2015-10-29 21:10:12 +11:00
59c1a96975 Fix T46429: Movie clip is deformed by resolution multiplier when offset is added in sequence editor. 2015-10-29 21:10:12 +11:00
f81ecf117f Fix broken CD_NORMAL interpolation callback (would generate non-unit vectors).
Even if the weights are normalized, the weighted sum of normalized vectors
usually does **not** give a normalized vector (unless all source vectors
are aligned).

This probably was not a big issue in most cases, since we usually interpolate
similar vectors here - but still!
2015-10-29 21:10:12 +11:00
cde725e26f Fix T46508: data_transfer of normals fails in case objects are transformed.
The final stage of the process (copying/interpolating new dst cddata from src cddata)
was simply broken in normal case, where we need to convert from source to destination
object space.

This patch is a bit verbose, but I cannot see how to avoid it really.

To think this code is in master since over 6 months and it only gets reported now... :/
2015-10-29 21:10:12 +11:00
42b6d843bd Mesh remapping: fix loop 'best matching normals' not using transform space.
Also, cleanup, reduce declarations of tmp_co/_no...
2015-10-29 21:10:12 +11:00
6c1b73c0da error in last commit 2015-10-29 21:10:07 +11:00
ff3913d1ec Fix for missing id_lib_extern, assigning ID's 2015-10-29 21:08:50 +11:00
dfba50bf6a Fix T46502: Linked dupli-group lost on reload 2015-10-29 21:06:42 +11:00
9a5d74a998 Fix T46503: Snap scale fails using corner pivot 2015-10-29 21:06:41 +11:00
40e69a6e95 Fix crash pressing +/- in file-selector
Filenames over 128 chars would crash.
Move BLI_newname into file_ops,
this was only used in one place and isn't all that re-usable.
Also remove special behavior for 4 digits.
2015-10-29 21:06:41 +11:00
ab6c7c5888 Fix crash w/ PlayAnim & long filenames
Paths >128 chars could crash.
Replace BLI_newname with direct BLI_stringenc/dec use which makes more sense in this case.
2015-10-29 21:06:41 +11:00
040c9ae55c Fix T46493: Wrong camera zoom blur with non-unit pixel aspect 2015-10-29 21:06:41 +11:00
381501ab45 Fix T46494: Can't de-select a face w/ mixed modes 2015-10-29 21:06:41 +11:00
7d25105290 Fix memory leaks in PlayAnim
Was never freeing filenames or pictures.
2015-10-29 21:06:41 +11:00
2f1bab75d7 Fix T46465: Lag scrubbing w/ PlayAnim 2015-10-29 21:06:41 +11:00
c1990affac PlayAnim: avoid list count setting frame from mouse 2015-10-29 21:06:41 +11:00
5acb0ba569 Fix T45900: Allow again white spaces in file names.
Should probably be added to 'a' release, should we do one...
2015-10-29 21:06:41 +11:00
ae1335f7cf Fix T46483: vertex/edge slide with correct UVs sometimes pinning UVs. 2015-10-29 21:06:40 +11:00
e5ee9d1eff Fix related to T46223: memory leak when loading multilayer multiview images.
Differential Revision: https://developer.blender.org/D1549
2015-10-29 21:06:40 +11:00
061f20112e Fix T46223: multiview image sequences crashing.
Differential Revision: https://developer.blender.org/D1549
2015-10-29 21:06:40 +11:00
7d31777d71 BGE: Fix animations update when scene is suspended. 2015-10-29 21:06:40 +11:00
50dd619e88 Fix T46487: OpenSubdiv objects are invisible in Blender Internal "Rendered" viewport mode 2015-10-29 21:06:40 +11:00
228625b9fb Fix T46453: JPEG quality not stored in file
This is a feature unique to jpeg that would store the quality it was saved.

- Use struct instead of bit-shifting.
- No longer store the 'flag'.
2015-10-29 21:06:40 +11:00
57d919c1ec Cleanup: remove historic, blender-only jpeg io 2015-10-29 21:06:40 +11:00
a5a58ec140 Fix T46284: Texture paint, wrong shading mode
Project-paint now supports painting to cycles materials.
2015-10-29 21:06:40 +11:00
1632a5503b Missed this in previous commit... 2015-10-29 21:06:39 +11:00
51a13869bc Fix T46467: Clean Keyframes removes the channels. 2015-10-29 21:06:39 +11:00
f4c22ac4b6 Fix T46002: mathutils.geometry.intersect_line_line_2d doesn't operate on lines, but on line segments.
Ugly issue really, but at least doc now matches behavior of the function. :|
2015-10-29 21:06:39 +11:00
2e4d580f9d Fix T46450: Seams from islands, wont show 'Sharp' 2015-10-29 21:06:39 +11:00
8af2029ca5 Fix T46458: BGE Crash on load
regression from 96dd213e7
2015-10-29 21:06:39 +11:00
5ea4f5b4a3 Fix T46447: fix build on non-x86 platforms. 2015-10-29 21:06:39 +11:00
ff01b24ecd Fix T46446: texture nodes image node not working with image sequences. 2015-10-29 21:06:39 +11:00
cdc8f4d65a Fix T46434: Shear w/ local-center & editmode fails 2015-10-29 21:06:39 +11:00
ae4b02c6bb Fix T46444: Crash importing DAE w/ empty armature 2015-10-29 21:06:39 +11:00
a5938e01e5 Cycles: Increase number of textures allowed for OpenCL render
Currently OpenCL devices are packing images into a single texture,
which means technically number of textures is not limited here.

Now OpenCL will use same number of textures as CPU. If we want
to bump number of textures further, this values are to be modified
in sync.

NOTE OpenCL still does not support float textures.

Original patch from a guy called bliblubli in the tracker with
some own modifications.

Reviewers: brecht, dingto, sergey

Differential Revision: https://developer.blender.org/D1530
2015-10-29 21:06:38 +11:00
d039cc69dc Fix T46441: texture paint soften brush at 0 strength works at full strength. 2015-10-29 21:06:38 +11:00
70549fe8e0 Fix T45152: multiview/stereo render not working with Freestyle + Cycles. 2015-10-29 21:06:38 +11:00
9bfc5fc7b5 Fix T44048: freestyle lines in Cycles are in the wrong color space. 2015-10-29 21:06:38 +11:00
c24d88d488 Fix T46437: Make progress report py helper resitent to 'zero steps' passed value...
To be backported, should we need an 'a' release.
2015-10-29 21:06:38 +11:00
a66d700fa7 small fix for potentially unintended calculation 2015-10-28 19:43:01 +01:00
2ccdaf398e changed calculation of stability factor for compounds and adapted UI a bit (for compounds) 2015-10-28 17:38:34 +01:00
12806f5ef8 disabled damage propagation (and settings) in code and ui, was slow and not really necessary, also fixed a crash which happened when freed bullet manifolds were used again. 2015-10-28 16:43:40 +01:00
e6d181c01a tiny fixes for autohide and attempt to get rid of propagateDamage crashes (again) 2015-10-27 13:19:46 +01:00
e3254e3615 attempted fixes for : autohide, damage propagation in compounds (was crashing after some time) and compound parameter changes do reset the cache now, too 2015-10-27 11:32:48 +01:00
2dfdbe4081 calculating minimum impulse per object now, also made solver iteration settings not visible for compounds any more (they relate only to constraints) 2015-10-26 20:25:59 +01:00
5cb7c07e31 attempt to fix some (stack overflow related ?) crashes 2015-10-26 15:34:40 +01:00
fe4909e752 tiny fix, forgot to assign ids to meshislands in splitshards to island mode 2015-10-26 14:43:36 +01:00
e2a01d408d small fix for ui description of mass_threshold_factor 2015-10-25 09:41:32 +01:00
3c8876c5a1 new parameter "stability factor" (for constraints, compounds) and resetting all shards by default now on refracture, except in mousebased fracture (faster to keep unchanged shards there) 2015-10-25 09:27:37 +01:00
d64c367560 some enhancement attempts for compounding, supposed to be better controllable in some cases, but still odd behavior with multiple compound objects 2015-10-24 13:01:03 +02:00
5019780664 fix for triggers and multiple compound objects (but compound building is slower again, due to necessary broadphase handles for triggers) 2015-10-23 18:45:28 +02:00
d72a489ddb exposed a couple of compound damage propagation parameters, need to test still to find good values 2015-10-23 12:02:41 +02:00
42f644204c windows compile fix 2015-10-22 21:53:18 +02:00
8611d01c68 crash fix in propagateDamage, checking for index being smaller than connection size now 2015-10-22 19:58:08 +02:00
ba39be6bc3 speed enhancement for building compounds (omitting broadphase handles) and successful test with clusters, values need a bit tweaking but basic principle works 2015-10-22 13:16:42 +02:00
a7b45823be added very basic damage propagation scheme to compoundbased fracture (direct damage is too small, can be increased this way, but you mostly get single parts falling off only) 2015-10-21 17:32:01 +02:00
b212d62340 some fixes for compound method, but still not very well controllable 2015-10-21 15:18:26 +02:00
597936b3fb new feature: attempt to accelerate simulation of many adjacent shards by compounds; todo... improve connectivity check 2015-10-20 21:31:29 +02:00
962480865a fracturing multiple settings seems to work (again) but todo: splinters, multiple islands / setting, constraints 2015-10-18 11:25:52 +02:00
0eae9ab115 fix attempt for splinters, did crash.. now works but its incorrect for multiple settings 2015-10-17 17:49:10 +02:00
9168aface9 small fix for multiple fracture settings (but, other files still dont work with it, investigating... 2015-10-17 15:47:03 +02:00
4a2dad0f8d multiple fracturing settings seem to work, but tested with 1 file only for now... 2015-10-17 15:28:21 +02:00
ade29c9713 fix for older blends, so they work as before again 2015-10-16 21:13:32 +02:00
e0fdc8279c experimental new feature: multiple fracture setting per predefined mesh island, delimited by a vertexgroup per island 2015-10-16 20:48:15 +02:00
c2730a8554 dynamic fracture, another improvement attempt, still a bit jerky movement 2015-10-14 20:01:41 +02:00
45d9914ac3 dynamic fracture: attempt of fixing rotation, its better than before but still not 100% correct 2015-10-14 18:16:31 +02:00
9dcabad07b fix for trimesh shape, in case of fracture modifier take physical mesh from each meshisland as shape mesh now 2015-10-11 21:51:58 +02:00
bd5d172bb3 allow to update deforming rigidbody mesh even when vertex count changes (by revalidating it), good for having fluids as deforming rigidbodies for example 2015-10-11 20:53:32 +02:00
48f7dd68f8 Fix T46403: motion tracking not workig with Xcode 7 on OS X.
Caused by use of the uninitialized shape_ variable in Resize().
2015-10-11 11:55:11 +05:00
3ed22c3f3c Revert "Fix T46406: Cycles ignores default socket value associated with group socket"
Fixes T46442.
2015-10-11 11:54:51 +05:00
23f7e16960 Fix/Workaround T46431: blender-softwaregl crashes
Order of initialization bug only impacted mesa's software-gl.

For now effectively revert support for glx-context-flags.
2015-10-10 13:48:35 +05:00
a3cf9c54d8 Use PyThreadState_GetDict, avoid Python internals
Works around problems caused by exposing Py internals (Py_BUILD_CORE).

    Build error with GCC, Py3.6 & OpenMP
    Linking error on MSVC
2015-10-09 23:01:22 +11:00
d53af76420 Blender 2.76: Point submodules to updated release branches 2015-10-09 16:40:54 +05:00
51384e7e36 Blender 2.76: Entering release stage 2015-10-09 16:31:46 +05:00
48c50bea72 Fix T46420: Segfault when instancing smoke domain.
Looks like instancing of smoke sim is not supported at all
(was fake-working in 3DView in 2.74, but not rendered).

But it should not crash - code was adding temp 'fromdupli' base to the delayed
drawing list...

Nice to backport this to 2.76 I think.
2015-10-09 16:23:41 +05:00
31d3d434aa Correct own error in editmesh bvh
Flag mix-up and uninitialized var.
2015-10-09 16:23:41 +05:00
f39babc9d6 Fix leak creating 'empty' looptri bvh tree 2015-10-09 16:23:41 +05:00
a67433bc19 Fix T46415: empty node group in GLSL shader has incorrect socket type conversion. 2015-10-09 16:23:40 +05:00
7a93fbc807 Fix T46407: Enabling OSL breaks Vector Transform node 2015-10-09 16:23:40 +05:00
68d5e1d3ae Fix: Do not show "Paste Flipped" in the Dope Sheet's Grease Pencil mode 2015-10-09 16:23:40 +05:00
323851fa71 Fix: "Tweak user" red-alert flag was not getting set on strips on active track
The "tweak user" flag used to flag strips using the same action as the active strip
was not getting set on other strips that live on the same track as the active one.
Strips with this flag set are shown with a red colour to indicate that editing the
action may have the unintended consequence of modifying another strip.
2015-10-09 16:23:40 +05:00
85f5c1a362 Fix T46406: Cycles ignores default socket value associated with group socket 2015-10-09 16:23:40 +05:00
f4ac865367 Cycles: Fix wrong float3->float3 conversion node 2015-10-09 16:23:40 +05:00
dc018d4f61 Fix bplayer (c) 2015-10-09 16:23:40 +05:00
ef7a3fb2fb Fix T46405: Cycles point density missing update when modifying source object 2015-10-09 16:23:39 +05:00
5d0a99b6ee Cycles: Fix for point density always using render settings for modifiers 2015-10-09 16:23:39 +05:00
7980891a13 Fix T46410: VSE Mask ignores animated properties 2015-10-09 16:23:39 +05:00
8d22715d67 Fix T46401: bad step size w/ radians 2015-10-09 16:23:39 +05:00
fe32c438ac BMesh: maintain select-history when sorting 2015-10-09 16:23:39 +05:00
5d59a51aca Fix T45886: cont.deactivate(ActionActuatorInPropertyMode) does not work
Make sure the Action Actuator actually deactivates when given a negative
event while using the property play mode.
2015-10-09 16:23:38 +05:00
ad950be67c Fix mesh validate: 'r_changed' ignored loop edits 2015-10-09 16:23:38 +05:00
a79f439580 Fix game-property use-after-free error
D1538 by @hal01
2015-10-09 16:23:38 +05:00
9713b11644 Fix FileBrowser: do not show 'advanced filter' panel outside of lib browsing context,
it’s only used there so far.

Reported by Thomas Beck (plasmasolutions) over IRC, thanks.

Safe enough for 2.76.
2015-10-09 16:23:38 +05:00
d5e1c9ab9f Fix T46390: Sound sequencer API doesnt' work when built with SCons
The issue was caused by original patch efde4dbb.

This seems to be really old bug, but safe for 2.76.
2015-10-09 16:23:38 +05:00
1b7fc80ecd Fix T46392: Navmesh generator error.
We now have to explicitely enure tesselation of DMs when we need it.

Notes: Maybe we could use looptris here as well?

Not a regression (bug already present in 2.75, but not 2.74), nice to backport to 2.76 nontheless.
2015-10-09 16:23:38 +05:00
9ccec0a288 Fix T46389: Shrinkwrap fails in editmode
Own regression caused by fix for T46067,
edit-mode bvh only contained unselected faces.

This commit adds support for an edit-mode bvh containing all faces.
2015-10-09 16:23:38 +05:00
e95a213f7a Fix T46333: Particle Info Node broken w/ BI
Patch from @a.romanov

This also fixes multiple particle systems - which never worked.
2015-10-09 16:23:37 +05:00
e5a6c542af Cleanup: warning 2015-10-09 16:23:37 +05:00
c647685538 Fix T46375: Inverted scroll in node template menus 2015-10-09 16:23:37 +05:00
1a37144ecd Fix T46354: Curve Modifier does not update (new Dependency graph)
Result of curve modifier depends on transform of the object which should
be reflected by the depsgraph relations.
2015-10-09 16:23:37 +05:00
3b17a650b6 Fix T46377: No python executable in 2.76 rc3 distribution for OSX 2015-10-09 16:23:37 +05:00
f7bc573b60 SCons: Support compilation with 10.11 SK on OS X 2015-10-09 16:23:36 +05:00
971566ba46 Fix T46352: Cycles fails to render when material contains UV mapped texture as volume input 2015-10-09 16:23:36 +05:00
365dadeecc Cycles: Remove redundant coordinate clipping in voxel SVM node
It is now handled via texture extension type.
2015-10-09 16:23:36 +05:00
5c0d68d687 Cycles: Fix missing z-coordinate check in volume sampling 2015-10-09 16:23:36 +05:00
b5ca4ee5b0 Fix T46358: Cycles point density uses repeat extension type 2015-10-09 16:23:36 +05:00
a142beb888 Fix T46305: normal map display issues in viewport when using VBOs. 2015-10-09 16:23:36 +05:00
690621bd24 CMake: detect OS X 10.11 / Xcode 7. 2015-10-09 16:23:35 +05:00
8621f480bf Fix T46368: Subtitle Export: Subtitles are not sorted by time.
We need a temp list of Text effect strips here, to be able to sort it as we want...
2015-10-09 16:23:35 +05:00
b2d325a768 Fix (unreported) broken export of timecodes in SubRip VSE exporter.
Would write 1.04 seconds as `00:00:01,40` instead of `00:00:01,040`...

Anyway, we already have BLI API for timecodes, much better to add
SubRip timecode format there, heavily simplifies code.

To be backported to final 2.76.
2015-10-09 16:23:35 +05:00
9b153763a3 InstallDeps: Fix broken OSL (would not generate valid default names for its .oso pre-compiled files).
Also, externalize temp/hacky patches in own dir, much much cleaner than integrating them in bash script!
2015-10-09 16:23:35 +05:00
1bc28db0ef Fix memory leak in compositor code with RGB curve nodes. 2015-10-09 16:23:35 +05:00
0c6346379f Cycles: Correction to point density with particle source and world mapping 2015-10-09 16:23:35 +05:00
2976a94c84 BGE: Fix T46302: abort call for unnormalized quaterions. 2015-10-09 16:23:35 +05:00
ea835c8a73 Fix T46339: Edge sliding when there is only one vertex in the mesh crashes blender.
If t->mode remains edge/vert slide, restoreTransObjects() ends up calling
projectVert/EdgeSlideData(), which tries to access invalid customdata...

Not sure why we call again restoreTransObjects() and resetTransRestrictions() here tbh,
but safer not to change that for now.

Should be backported to 2.76 if possible.
2015-10-09 16:23:34 +05:00
c2d070a3fb Fix T46321: 3D view not refreshed immediatelly after pasting keyframe in dope sheet (for a single channel) 2015-10-09 16:23:34 +05:00
2f7eb53ed0 Fix T46331: File open does not show thumbnails, when a filter_glob is provided by python scripts.
No reason to exclude usual file-type 'guessing' for operator-filtered extensions...

Safe for 2.76, should we need to merge more fixes.
2015-10-09 16:23:34 +05:00
596bf1aff6 allow freeslip / partialslip in fluid with export animated mesh on obstacle, for testing purpose with fracture modifier, attempting to reduce fluid jitter on moving shards 2015-10-08 19:51:42 +02:00
3e4ce322c4 allow deforming rigidbodies now with mesh_source 'FINAL' as well 2015-10-06 22:47:25 +02:00
fb78f6d518 Fix T46332: Can't select an object with OpenSubdiv enabled
The issue was introduced by a wrong fix for T46247. Now both reports should
be properly solved.
2015-09-30 21:05:13 +05:00
035d27dca6 Revert "Fix T46247: Side-reported, bbox for zero-verts object with OSD subsurf and GPU compute would be -INF."
This reverts commit b278e8742b.
2015-09-30 21:05:06 +05:00
e1c77fb98d Address request from T46136: make softrange for 'simple deform' angle from -360 to 360 degrees...
This should be safe enough for final 2.76, sould we make other RC.
2015-09-30 20:22:59 +05:00
e0a08d50a2 Blender 2.76: Update Release Candidate splashscreen label 2015-09-30 20:09:46 +05:00
7914d04d13 Fix T46325: Armature: No more possible to rotate a bone with only its tip selected, in EditMode.
Regression from rB312cb0a957b81233ea, now we make an exception for TFM_ROTATION mode...
2015-09-30 20:08:26 +05:00
67dffa60ae Fix T46313: Cycles bake normal map
Regression moving to bake to looptri
caused by mismatch w/ MFace and MLoopTri when the 3rd index was 0.
2015-09-30 20:08:26 +05:00
ae4fcdc7ba Fix T46299: Windows: File Browser Crash while listing big folders in preview mode (fonts, images...).
Windows-only bug, mmap & co are not threadsafe by default on this platform, so we have to add a dedicated
spinlock for them in win32.

Note that we may try to get rid of those mmap later, but not for 2.76!

To be backported to final 2.76...
2015-09-30 20:08:26 +05:00
24615ecab5 Blender Internal: Fix regression in point density texture
The issue was introduced by original Cycles point density support commit,
it lead to a constant density of 1 for object verticies point density source.
2015-09-30 20:08:26 +05:00
6cb20d6287 Cycles: Fix wrong particles min/max calculation for point density
Solves wrong object mapping reported in T46301.
2015-09-30 20:08:26 +05:00
2ecc405b69 Fix T46285: "Select parent" if there is no parent doesn't work correctly. 2015-09-30 20:08:26 +05:00
c3dbb533b2 Fix T46271: switching between textures in texture buttons not updating preview. 2015-09-30 20:08:26 +05:00
0191a618ef Fix T46212: blender internal lights in exclusive light group wrong in viewport. 2015-09-30 20:08:25 +05:00
c31bace2a4 Fix crash reporting render errors during baking. 2015-09-30 20:08:25 +05:00
Julian Eisel
4d76fdd3e9 Fix file browser not sorting file list when opened from editor menu 2015-09-30 20:08:25 +05:00
Julian Eisel
b3d12f65c0 Fix node auto-offset to left broken
Own, really stupid mistake in rBc653077bf56 :| Kids, don't commit at night!
2015-09-30 20:08:25 +05:00
7dcd3a0e0d Fix T46249: Boid goal object that has a force field set to 'Every Point' shape causes crash.
This is a mere bandage, that whole area is known broken anyway, but at least it should prevent the crash.

Note that that kind of stuff (the efd->index being a pointer) is really bad practice imho...

Should be backported to final 2.76.
2015-09-30 20:08:25 +05:00
7a81cccd1d Fix T46239: Cross effect strip input fields can't be changed (in its properties panel).
Those shall not be editable in UI...
2015-09-30 20:08:25 +05:00
fd964bbf1c Fix T46247: Side-reported, bbox for zero-verts object with OSD subsurf and GPU compute would be -INF.
Trivial fix, to be backported to final 2.76 if possible.
2015-09-30 20:08:25 +05:00
Dalai Felinto
a985bf73e5 Multiview: fix Image Editor not showing Views menu when rendering
non-stereo Multi-View camera rigs (unreported)
2015-09-30 20:08:24 +05:00
ca1809988a Fix T46226: Bake normals multi-res crash 2015-09-30 20:08:24 +05:00
21c00cbd0e Fix T46227: ShapeKeys Lattice by the driver, problem updates in new depsgraph
The issue was caused by driver referencing path outside of the key datablock.
2015-09-30 20:08:24 +05:00
eae90798b6 Fix T46232: Boids crash w/ random rule selection 2015-09-30 20:08:24 +05:00
34bcd2f0ea Fix T46219: Knife cuts fail away from center 2015-09-30 20:08:24 +05:00
Dalai Felinto
99cdafc651 Fix T46225: Crash when rendering halo flare
Error introduced in the multiview commit.
Also bringing back the "continue" statement instead of "return", as it
was before multiview.
2015-09-30 20:08:24 +05:00
7ea1e5de8d Fix T46222: Eyedrop picking objects inconsistently 2015-09-30 20:08:23 +05:00
3399314a6f Blender 2.76: Point submodules to new commits 2015-09-30 20:07:06 +05:00
39155c1c46 Revert last commit where attempt of keeping autohide state was made 2015-09-27 21:15:44 +02:00
a2ff84c66a attempt to reduce flickering with autohide by memorizing which faces were not deleted in one autohide pass and keeping them, side effect: when playing the sim backwards autohiding wont work properly until reset to start frame again. 2015-09-27 20:50:07 +02:00
479a1a9a1a separate autohide and automerge distances, autohide alone is ok for glass and is faster, while automerge is more useful in conjunction with smooth objects and fix normals, to hide the cracks better, also automerge caused errors with thin glass objects like window panes 2015-09-26 17:47:18 +02:00
e24ea81d65 Fix T46215: Explode modifier looses textures 2015-09-23 19:02:27 +05:00
f6445cd6ae Fix T46217: Make normal artifacts 2015-09-23 19:02:26 +05:00
8db7ca1cca Fix T46202: OS X (and Windows?) crash when going fullscreen.
Calling event handling recursively during window live resize is problematic,
the code wasn't designed to do that. Instead postpone event handling until
after live resize.
2015-09-23 19:02:26 +05:00
05ed4a4da1 Update module test to pass w/o freestyle enabled 2015-09-23 19:02:26 +05:00
eca8d9aa02 Update test to RNA API 2015-09-23 19:02:26 +05:00
6b9d496aa5 prevent assert: select-linked UV delimit w/o UV's 2015-09-23 19:02:26 +05:00
c8670f45b9 OpenSubdiv: Fix crash with empty mesh
Reported by newbz in IRC, thanks!
2015-09-23 19:02:26 +05:00
65a56a10bb FFmpeg: Solve memory leak happening on encoding video 2015-09-23 19:02:25 +05:00
96c0aebeae Fix T46194: Crash rendering particles
Off by one error in 38940662
2015-09-23 19:02:25 +05:00
d26fc19fd8 Remove arbitrary simulation time limit in liquid sim. Tested and works fine with more than 100s 2015-09-23 19:02:25 +05:00
f6b0194746 Fix T46201: Popup menu in post_load handler crash
Match regular file loading logic for new-file operator.
2015-09-23 19:02:25 +05:00
a41bdb77d3 Fix bplayer (c). 2015-09-23 19:02:25 +05:00
fe98ce1375 Sequencer: show X,Y in text effect location 2015-09-23 19:02:25 +05:00
a457ad0057 Render: Free persistent image storage when loading new file 2015-09-23 19:02:25 +05:00
d16ee90b9c Fix (unreported) Append/link code: All library datablocks could end with same name.
This was broken since ages I think, did not really hurt since we usually never use libs' names
to access them. Rather bad behavior however, breaking a ground rule of our ID system!

And no real reason to add new libraries to new (split) Main at all, libraries are
never considered linked datablocks, which means they should always be in 'main' Main->library list.

Not a regression, but should be included in 2.76 imho.
2015-09-23 19:02:24 +05:00
c0384c4645 Fix T46159: OpenSubdiv does not always give same results as Blender own subsurf code with crease edges 2015-09-23 19:02:24 +05:00
23427bfebf Fix view-selected w/ custom bone shapes
Was ignoring bone-length, also check that drawing shapes is enabled.
2015-09-23 19:02:24 +05:00
574e859e38 Fix T46186: Panel doesn't update on brush change 2015-09-23 19:02:24 +05:00
869c3344c9 Fix T43715: IK pole target + stretch not working for a single bone chain. 2015-09-23 19:02:24 +05:00
78f4e22dc3 RNA: angle step-sizes were too small
These were ignored previously, so it wasn't noticeable.
2015-09-23 19:02:23 +05:00
Julian Eisel
869736b5d6 Fix node auto-offset failing during heavy compositing (sometimes)
Compositing might make main thread so busy that animation is considered done due to duration before final position is reached.

Also added check to avoid unnecessary redraws.
2015-09-23 19:02:23 +05:00
cec28ebf5e Fix T46050: blender internal geometry node UV not working inside node group. 2015-09-23 19:02:23 +05:00
3c30467cda Fix T46144: blender internal face texture color wrong in raytraced reflection. 2015-09-23 19:02:23 +05:00
c8200c000a fix build error w/ clang 2015-09-23 19:02:23 +05:00
74b210387f Fix T46169: Link to bpy API in addons tab of user preferences is outdated.
Now use auto-generated one, like e.g. for link in Help main menu...
2015-09-23 19:02:23 +05:00
c08896e2c4 Fix T46161: Rotate around selection changes bezier curve handle type.
Issue is, when 'Rotate Aroud Selection' is set, in Edit mode we do a fake transform operation
to get center point around which to rotate. For curves, most transform operations involve
a check of handle types. For now, added 'TFM_DUMMY' as an exception here.

Think it would be best to actually undo those changes in case of cancelled operation,
but this is much more involved, while this fix is safe enough to be included in final 2.76.
2015-09-23 19:02:22 +05:00
aabb8db753 Fix leak in UI Panels
Switching screens quickly didn't free the panels activedata.
2015-09-23 19:02:22 +05:00
Julian Eisel
139cab0937 Correction to previous commit 2015-09-23 19:02:22 +05:00
Julian Eisel
1358920716 Fix file key select using wrong file after border select in scrolled view
Basically, after border selecting, a wrong file was selected by using arrow keys if the screen was scrolled a bit vertically. Reason was that we didn't use correct view space coordinates but region space coordinates for measuring distance from mouse to first/last file in selection after border select.
2015-09-23 19:02:22 +05:00
42eb1cc64e Fix T46030: Strange behavior of Cycles Brick Texture
Added some extra seed to the hash, so it's now less likely to give repetitive
patters at values around zero.

This will change distribution of bricks for existing files. but it's something
inevitable.
2015-09-23 19:02:22 +05:00
07c3311475 Fix UI crash entering very long strings
Strings exceeding UI_MAX_DRAW_STR weren't null terminated.
2015-09-23 19:02:21 +05:00
141de0cc7f Fix T46148: Sculpt view-clip fails in ortho mode 2015-09-23 19:02:21 +05:00
b0a6d48659 Doc: escape enum name & description
Needed since key enum now uses many characters as they're typed.
2015-09-23 19:02:21 +05:00
c586e30053 Blender 2.76: Update translations submodule 2015-09-17 19:48:06 +05:00
7b8bfec06d Merge branch 'master' into blender-v2.76-release 2015-09-17 19:46:21 +05:00
20bc9aadc6 Blender 2.76: Point submodules to latest release branch from according repos
No tagging is done yet, will happen in a bit.
2015-09-17 18:03:23 +05:00
c86186f030 small crash fix for fast bisect / fast bisect fill 2015-09-12 15:20:35 +02:00
1bd9a911c4 crash fixes for greasepencil edge fracture 2015-08-07 15:38:23 +02:00
f870eee4d4 fix: remove doubles on internal cutter mesh created by (nearly) cyclic greasepencil strokes (so non-manifolds are avoided there) 2015-08-06 21:10:57 +02:00
9263098a7f fix: set cutter axis correctly (RNA called a different function there) 2015-08-06 19:33:05 +02:00
aa8c0143d2 mark "Dynamic Fracture" as WIP 2015-08-06 14:41:32 +02:00
d05a85cd7f compile fixes due to merge 2015-08-06 14:23:10 +02:00
4c52ad04b1 Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier
Conflicts:
	CMakeLists.txt
	build_files/cmake/macros.cmake
	intern/cycles/kernel/geom/geom_triangle_intersect.h
	intern/cycles/kernel/kernel_shader.h
	intern/cycles/kernel/svm/svm_closure.h
	release/scripts/modules/bpy_extras/io_utils.py
	release/scripts/startup/bl_ui/properties_data_modifier.py
	release/scripts/startup/bl_ui/space_view3d.py
	release/scripts/startup/bl_ui/space_view3d_toolbar.py
	source/blender/blenkernel/BKE_blender.h
	source/blender/blenkernel/BKE_deform.h
	source/blender/blenkernel/BKE_mesh_mapping.h
	source/blender/blenkernel/BKE_object.h
	source/blender/blenkernel/BKE_rigidbody.h
	source/blender/blenkernel/CMakeLists.txt
	source/blender/blenkernel/SConscript
	source/blender/blenkernel/intern/cdderivedmesh.c
	source/blender/blenkernel/intern/object.c
	source/blender/blenkernel/intern/rigidbody.c
	source/blender/blenloader/intern/readfile.c
	source/blender/blenloader/intern/versioning_270.c
	source/blender/blenloader/intern/writefile.c
	source/blender/editors/animation/keyframes_general.c
	source/blender/editors/armature/armature_edit.c
	source/blender/editors/gpencil/gpencil_ops.c
	source/blender/editors/object/object_intern.h
	source/blender/editors/object/object_shapekey.c
	source/blender/editors/space_action/action_edit.c
	source/blender/editors/space_view3d/view3d_draw.c
	source/blender/makesdna/DNA_modifier_types.h
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/modifiers/MOD_modifiertypes.h
	source/blender/modifiers/intern/MOD_fluidsim.c
	source/blender/modifiers/intern/MOD_normal_edit.c
	source/blender/modifiers/intern/MOD_util.c
	source/gameengine/Converter/KX_BlenderSceneConverter.cpp
2015-08-06 14:22:23 +02:00
2c58498e6d fix: properly initialize cluster indices of mesh islands, failing to do so caused different activation behavior when triggering 2015-07-23 17:47:02 +02:00
840cc057a1 crash fix, do not reset shards in dynamic fracture 2015-06-13 10:55:45 +02:00
a8226be315 automatically trigger entire clusters now, if any 2015-06-13 09:22:18 +02:00
a051a76c8a attempt to add a cut by objects / geometry (other FM) option as well as properly resetting shards after fracture parameter change (the latter didnt work properly) 2015-06-07 21:21:06 +02:00
929b0fb444 added possibility to brickify objects, but you need to craft a brick helper object which consists of several islands and covers atleast the bbox of the object to be fractured, and you need to put a fracture modifier which creates just islands on the helper object as well 2015-06-07 16:45:09 +02:00
9a891f26dd fix: limit speed transfer to dynamic objects only, caused severe glitches with prefractured objects 2015-06-06 23:04:44 +02:00
2421696f60 fix : fast bisect algorithms caused misbehavior when refracturing, also removed the forced settings (Mesh shape, constraints) with fractal boolean 2015-06-06 15:50:36 +02:00
73f1c37871 fix: display glitch when triggering shards due to own error in pointcache 2015-06-06 11:19:44 +02:00
c1447bc9ba fix: reducing the shard count didnt work with new, faster refracture method in prefracture 2015-06-05 21:22:48 +02:00
289d8b247e dynamic fracture: some crash fixes when changing between prefractured and dynamic mode (memory was partially overwritten instead of cleared) 2015-06-05 19:23:47 +02:00
40f3759482 dynamic fracture: disabled loading / saving of dynamic mode again, it still has too many issues 2015-06-04 20:34:17 +02:00
cd603674c9 dynamic fracture: re-added modified version of speed transfer, it depends now on linear / angular deactivation threshold whether speed is transferred or not (to reduce "jumping" of shards on the ground) 2015-06-04 14:20:13 +02:00
52ef935b7d dynamic fracture: relocated some functions and removed speed transfer from parent to child shards, it looked unrealistic, but TODO, animation often stops in case of fracture events.... 2015-06-04 10:28:04 +02:00
3a40e2b657 dynamic fracture: new option to limit the first impact (shard activation area can be limited to impact object) 2015-06-03 16:43:05 +02:00
90d6041f4e for now, deactivate loading for dynamic files again, there are still issues to solve (like proper cache handling after loading) 2015-06-03 11:25:46 +02:00
6f71cb361e dynamic fracture: cache works much better now 2015-06-03 11:01:32 +02:00
89e2e80ef6 dynamic fracture: slightly improved caching behavior, but it still flickers and doesnt continue simulation properly after cache ends 2015-06-02 15:44:25 +02:00
d79851ba2f fix: small rotation fix for dynamic fracture and fix for shard lookup 2015-06-02 14:27:10 +02:00
0e5638c04b fix: crash when repeatedly refracturing in prefractured mode with same settings 2015-06-01 21:27:06 +02:00
9888d30bb6 fix: crashes with dynamic fracture, but this is still WIP ! 2015-06-01 20:26:57 +02:00
2c26325272 some performance improvement with mouse based fracture (addon), only attempting to refracture necessary shards 2015-06-01 15:40:23 +02:00
3392741d19 dynamic fracture: do reset after settings changes and clean up constraints now too in dynamic fracture events 2015-05-27 18:29:25 +02:00
e4fbcce537 dynamic fracture: now multiple dynamic objects can exist, need to test interaction with prefractured, though 2015-05-21 18:28:18 +02:00
07ce06d212 dynamic fracture: fix for loss of rotation, and transferring speeds of parent shards to children now 2015-05-21 12:02:33 +02:00
9161459515 dynamic fracture: finally the transforms seem correct... but this mode still is highly unstable, and is prone to crash often, use sparsely ! 2015-05-20 23:03:31 +02:00
0d27ecdc04 hrm, now somethings with caching is broken... need to investigate 2015-05-19 16:35:45 +02:00
809402e927 still fighting with proper transformations in case of multiple fractures 2015-05-19 15:55:40 +02:00
30b3ebb59a dynamic fracture: fixed transformation calculation 2015-05-18 22:40:41 +02:00
d00f6177ae dynamic fracture: works a bit more stable now, but still lacks proper transformation calculation and speed takeover from parent to child rigidbodies 2015-05-18 20:33:24 +02:00
360c01cb86 dynamic fracture: attempts with loading and saving, and proper caching, still highly unstable 2015-05-18 16:29:39 +02:00
ec90dcb5b7 first commit of dynamic fracture, still highly unstable, needs fixes in storage handling and memory management 2015-05-17 22:04:55 +02:00
1e5c376e0f fix: crash when using fractal boolean with 1 shard and split shards and other misbehavior (boolean did not create valid rigidbodies, so objects were stuck in the air with 1 shard and fast bisect / fast bisect fill created 1 shard too much everytime) 2015-05-07 19:52:26 +02:00
f168ba85a9 fix: passive vertexgroup was ignored 2015-04-19 09:54:22 +02:00
728f259329 fix: loading subobject group modifiers correctly again 2015-04-07 18:46:06 +02:00
4f9941afcb fix: modifier will respond now to manual changes in transformation (setting values numerically, clear transformations, apply transformations and origins) and ghost setting should be respected properly now with mesh collision shape 2015-04-07 17:10:48 +02:00
f369be74d3 previous merge went wrong somehow, several parts of mesh data transfer code were missing 2015-04-01 13:43:48 +02:00
4e7f37c6e8 compile fixes due to merge 2015-04-01 11:32:33 +02:00
85cb9a2b0d Merge remote-tracking branch 'refs/remotes/origin/blender-v2.74-release' into fracture_modifier
Conflicts:
	intern/cycles/render/scene.cpp
	release/datafiles/blender_icons.svg
	release/datafiles/blender_icons16/icon16_mod_data_transfer.dat
	release/datafiles/blender_icons32/icon32_mod_data_transfer.dat
	release/scripts/startup/bl_ui/properties_data_modifier.py
	source/blender/blenkernel/BKE_blender.h
	source/blender/blenkernel/BKE_customdata.h
	source/blender/blenkernel/BKE_data_transfer.h
	source/blender/blenkernel/BKE_mesh_remap.h
	source/blender/blenkernel/intern/customdata.c
	source/blender/blenkernel/intern/data_transfer.c
	source/blender/blenkernel/intern/data_transfer_intern.h
	source/blender/blenkernel/intern/deform.c
	source/blender/blenkernel/intern/mesh_mapping.c
	source/blender/blenkernel/intern/mesh_remap.c
	source/blender/blenkernel/intern/object.c
	source/blender/editors/include/UI_icons.h
	source/blender/editors/object/object_data_transfer.c
	source/blender/editors/space_outliner/outliner_draw.c
	source/blender/makesdna/DNA_modifier_types.h
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/modifiers/MOD_modifiertypes.h
	source/blender/modifiers/intern/MOD_datatransfer.c
	source/blender/modifiers/intern/MOD_util.c
2015-04-01 11:31:53 +02:00
000dfc0319 Point submodules to the final release tag 2015-03-31 18:39:23 +05:00
dedfd0cfa9 Branch is not really a release state! 2015-03-31 18:26:53 +05:00
08f7b20ebb Bugfix: Fix for crash when trying to create new action in Shape Key DopeSheet mode
When the active object had no shapekey data, trying to create a new action from the
Shape Keys mode of the DopeSheet would crash. The segfault here was a silly regression
caused by my earlier Action Stashing work.

However, the old (pre-Action Stashing) code here also wasn't that great either.
While it didn't crash, it would still silently create a new action, even if that
could not get assigned/used anywhere. To prevent both of these problems from
happening again, I've added additional null checks, as well as beefing up the poll
callback here to forbid keyframing
2015-03-31 18:18:05 +05:00
4f57f15648 Fix T44077 material update fails in textured mode when VBOs are off.
The issue has been here since we changed drawing code for meshes to use
vertex arrays instead of immediate mode when VBO was off. Basically we
should now always invalidate the GPU objects regardless of the VBO
setting in the preferences.

The bug has been there since 2.73 at least, but what made it apparent
now is that new version resets preferences and as an extension the VBO
flag.

Should be included in final 2.74 release
2015-03-31 18:18:05 +05:00
a555fa5b28 Fix T44201: Crash Deleting Hierarchy in Outliner
Typical error using '->next' member of a freed linked list item. A bit trickier
even here, since we have some recursion...

Trivial fix for nasty crasher, safe for 2.74 imho?
2015-03-31 18:18:05 +05:00
abb92632f8 Fix T44193: Hair intersection with duplis causes flickering
It was an issue with what bounds to use for BVH node during construction.

Also corrected case when there are all 4 primitive types in the range and
also there're objects in the same range.
2015-03-31 18:18:04 +05:00
5ca59f7134 Fix T41191: Custom Loop Normals Viewport shading not updating when set from py script
Missing update tagging...

Safe for 2.74.
2015-03-31 18:18:04 +05:00
accd6083a5 Fix for invalid buffer access on zero-face meshes 2015-03-31 18:18:04 +05:00
e6b81ae69a Fix T44186: Bezier Bevel facto mapping broken when 'start' was set to 'Resolution' and 'end' was not.
Trivial, we need totla_length in that case too.

Safe to be backported to 2.74.
2015-03-31 18:18:04 +05:00
5ca0cf3702 Remove use_invert_vertex_group use_ prefix
To match other modifiers.
2015-03-31 18:18:04 +05:00
6410b1bd59 Fix T44149: Compositing : Node Groups do not work correctly
Input constants are to be connected before removing proxies,
otherwise node groups might give totally different result.

This is a regression and to be put into final release.
2015-03-31 18:18:04 +05:00
5e92d1254e Fix T44137: bpy.path.is_subdir fails
`bpy.path.is_subdir("/abc/def/ghi","/abc/de")` incorrectly returned True
2015-03-31 18:18:04 +05:00
3593082a75 Point addons to 2.74-rc4 tag 2015-03-26 21:12:32 +05:00
cb19df1c45 Bump splashscreen to rc4 2015-03-26 21:04:56 +05:00
b2a3796b2d Fix T44133 SSAO in OpenGL rendering from orthographic camera did not
work

Safe to include in final release
2015-03-26 16:18:41 +05:00
01a29487e8 Fix T44138: Crash in DataTransfer modifier when selecting a source with no loops.
Simply check and early return in case we have no source or destination items
(verts/edges/loops/polys) available...

Also, fix an assert in `BKE_mesh_calc_normals_poly()`, when called with no poly.
2015-03-26 16:18:41 +05:00
1311f2d8f1 Yet another fix for crashing particles. 2015-03-26 16:18:41 +05:00
30e06a1775 Fix 2 typos ( shakin' hands ) 2015-03-26 16:18:40 +05:00
1c8ee52423 Fix for crash when using particle emission with clump/roughness curves
in a smoke sim.

This interaction between sims is totally stupid and must be recoded
entirely in some utopian future.
2015-03-26 16:18:40 +05:00
dcfbffcf57 Fix T44128: Ray visibility only enables diffuse if glossy is also enabled
Issue was caused by accident in c8a9a56 which not only disabled glossy
reflection if Glossy visibility is disabled, but also Diffuse reflection.

Quite safe and should go to final release branch.
2015-03-26 16:18:40 +05:00
fa1fc11344 Simplify recent commit 2015-03-26 16:18:40 +05:00
143dbfb33e Fix T44118: Rotated background image disappears
Image clipping didn't take rotation into account.
2015-03-26 16:18:40 +05:00
f1f797599f Fix T44123: Cycles SSS renders black in recent builds
Issue was introduced in 01ee21f where i didn't notice *_setup()
function only doing partial initialization, and some of parameters
are expected to be initialized by callee function.

This was hitting only some setups, so tests with benchmark scenes
didn't unleash issues. Now it should all be fine.

This is to go to the 2.74 branch and we actually might re-AHOY.
2015-03-26 16:18:40 +05:00
8804e6493c Point addons to v2.74-rc3 2015-03-24 20:31:27 +05:00
3ec48d3bd8 We're now RC3 2015-03-24 19:49:40 +05:00
eb9826d8d9 Versioning code to correct socket naming after
340b76b42c

Reported by formerly Old_Demon on blenderartists.

Apparently this caused old files to lose their links to material sockets
(noob own mistake from inexperience with node system).

This should either be included in release with version checking being
set to version 2.73 and subversion 10, without tweaking the
BKE_blender.h file

OR

340b76b42c should be reverted for this
release.

Thanks to Lukas for checking this out.

Conflicts:
	source/blender/blenkernel/BKE_blender.h
	source/blender/blenloader/intern/versioning_270.c
2015-03-24 19:49:18 +05:00
c7dc142c1b Fix T44102: Mirrored objects render black with Blender Internal and Autosmooth.
Normals are not vertices, we cannot apply matrix's scale to them...
2015-03-24 19:47:50 +05:00
d2d3a41ce8 Fix T44089: All addons do not use same default for orientations.
Transformed 'OrientationHelper' class into 'orientation_helper_factory' function,
which returns an OrientationHelper customized class with specified default axes.
2015-03-24 19:47:50 +05:00
03d662d7bd Fix T44065: fixed vehicle constraint
Commit ffee7f1a58 broke vehicle constraints; this fixes that.
2015-03-24 19:47:50 +05:00
33bf1e0e18 Revert part of D1074 related to acceleration taked into account.
It has been reverted because it was affecting obstacle avoidance
(T44041).

This fix should be backported to 2.74
2015-03-24 19:47:50 +05:00
6289d5b8d1 Fix T44110: Plane track doesn't work when built with scons
For some reason recent change in avoiding non-aligned eigen vectors
was behaving differently for cmake and scons. Made it a bit different
now by storing scalars. This is more robust approach anyway, because
it's not really guaranteed Mat.col() gives a pointer inside data,
depending on column-major vs. row-major storage.

This is to be backported to 2.74 branch.
2015-03-24 19:47:50 +05:00
6b1638cf79 tweaks to packman build
remove --asroot arg to makepkg
2015-03-24 19:47:50 +05:00
07e815df4b Fix T44076, SSAO in solid mode will disable antialiasing in wireframe
mode.

Yes it will, because those modes stay active. So on user side, expose
depth of field option always (I don't see why not), but disable SSAO in
wireframe/bounding box mode. It is a known limitation that compositing
does not support antialiasing yet, but better give users some more
control.

This could be included in final release but it's not that serious
either.
2015-03-24 19:47:49 +05:00
a10e7ca830 Make sure matcap icons are within range.
Basically out of range could happen when opening files made in 2.72 when
the new icons for texture painting were added. Apparently some more
caution is needed here.
2015-03-24 19:47:49 +05:00
01ee21ffb9 Fix T43926: Volume scatter: intersecting objects GPU rendering artifacts
Fix T44007: Cycles Volumetrics: block artifacts with overlapping volumes

The issue was caused by uninitialized parameters of some closures, which
lead to unpredictable behavior of shader_merge_closures().
2015-03-24 19:47:49 +05:00
3cf120be67 OSX: fix 1 leak ( found and fixed by marcclintdion ) and 1 possible leak in dragndrop, backport to 2.74 2015-03-24 19:47:49 +05:00
d22c56819c OSX/GHOST: need one more release in error case 2015-03-24 19:47:49 +05:00
ff455f1ae1 Partly fix T44025, pixelFormat retain was left, for 2.74 backport 2015-03-24 19:47:49 +05:00
9bbb53ef68 Cycles: Avoid memcpy of intersecting memory
Could happen when assignment happens to self during sorting.
2015-03-24 19:47:49 +05:00
7b9a8337ad Disable IME for headless builds 2015-03-24 19:47:49 +05:00
210f90cb77 Fix for building win32 headless 2015-03-24 19:47:48 +05:00
856da320e7 Fix/Improve FKey bone creation
- new bone is now made active
- previous selection cleared
- bone direction places the tip on the active bone (if available)
2015-03-24 19:47:48 +05:00
2967c07a61 Add missing update adding a shape-key
Noticeable when pin is enabled.
2015-03-24 19:47:48 +05:00
638368a930 Fix T43989: Sequencer - Ctrl snapping a sequencer strip does not work if you specify the x axis.
New 'strip' snapping was simply not computed in case of constrained transform, hence init
'0' value was used as frame offset in this case.

This commit reorganizes a bit that snapping, to keep it more 'confined' into `snapSequenceBounds()`
dedicated function. It still needs a minor hack (setting snapping mode to something else than
defualt `SCE_SNAP_MODE_INCREMENT`, to avoid this snapping to be called by contraint code).

Thanks to Antony for review and enhancements.

This fix should be backported to 2.74.
2015-03-24 19:47:48 +05:00
bef0649151 Fix T44040: Blender crashes when nodes are muted
It was actually an old issue with wrong conversion happening for muted
nodes, which wasn't visible before memory optimization commit.

This is to be backported to the final release.
2015-03-24 19:47:48 +05:00
8108fc77c6 Fix out-of-bounds read BKE_deform_flip_side_name 2015-03-24 19:47:48 +05:00
d62e3e7001 Use fabsf for floats 2015-03-24 19:47:48 +05:00
16cc6ae80e Fix for crash adding mask modifier 2015-03-24 19:47:48 +05:00
37172e7e49 Fix bad memory access freeing viewport which uses movie clip 2015-03-24 19:47:47 +05:00
f71f559d03 Fix crash using "Copy to selected" on ID-props 2015-03-24 19:47:47 +05:00
163d99b7a9 Fix crash using removed data as function arguments 2015-03-24 19:47:47 +05:00
06adae7b43 Fix RNA active spline assignment 2015-03-24 19:47:47 +05:00
9f69f7f700 Fix T44027: Normal Edit Mod : Radial from object normals affected by target object scale.
The way we were getting diff to apply to vcos from target object was just bad!

Also, fixed another related issue - negated scale would be clamped to nearly zero,
now only consider absolute version of size (we do not care about its sign here anyway).

This should be backported to 2.74 (with previous commit too).
2015-03-24 19:47:47 +05:00
4f08b3cf83 BLI math vec: add 'abs' functions to get absolute values of a vector.
Unseful when handling e.g. scale, sometimes.
2015-03-24 19:47:47 +05:00
c6f1be0728 Fix T44020: Crash exporting fluid sim to fbx
The issue is coming from wrong fluid modifier copy callback,
which might have left some pointers shared across original
and target fluid modifiers.
2015-03-24 19:47:47 +05:00
584aed0721 Fix T44021: Crash switching Rendering Engines while viewport rendering + animating
Make sure preview render job is cancelled before freeing the render engine
associated to the viewport.
2015-03-24 19:47:47 +05:00
337ce035b6 Make sure disabling attribute arrays also resets the counter so we don't
do it twice.
2015-03-24 19:47:46 +05:00
1ad57f287b Fix T43853: Audio animation bug (fcurves)
For a detailed bug explanation see the comments in the report.
2015-03-24 19:47:46 +05:00
3523a136d0 use center between objects for constraint types different than fixed, note: other types only work between clusters and settings for them are limited to the type currently.... 2015-03-22 18:17:11 +01:00
25397ea355 fix: some speed improvement for converting to objects or to keyframed objects and proper renaming of shards and constraints being created 2015-03-22 10:13:39 +01:00
9fa84d09e4 fix: another possible fix for loading correct vertexbased constraints 2015-03-20 00:32:10 +01:00
b3bc2166a6 fix: vertexbased constraints should be rebuilt correctly now after loading 2015-03-19 23:54:30 +01:00
fa116391df added a new vertex coordinate based constraint build method, as alternative to meshisland centroid based constraint building 2015-03-19 18:06:15 +01:00
d11592a700 fix: crash with fast bisect and fast bisect / fill due to refactoring 2015-03-18 16:06:13 +01:00
9775830ef7 fix: bugfixes for fractal boolean and greasepencil edge cutting due to refactoring 2015-03-18 00:00:49 +01:00
14a023abdd refactoring of FractureModifier: split very long functions into more, shorter ones 2015-03-17 20:48:03 +01:00
1f547c14ec Point submodules to 2.74-rc2 2015-03-17 20:11:30 +05:00
a1bb0d698b Fix an incorrect assert in lnor code.
There is one case where we do can have only two edges for two loops...
2015-03-17 18:19:46 +05:00
48d4b80246 Refer to Task 43975: Deleting a Shapekey can break the relative pointers
This patch would reassign the relative of all keyblocks to the relative
of the deleted keyblock. And it fixes the misalignement of the index values
after the keyblock is deleted.

Reviewers: campbellbarton

Differential Revision: https://developer.blender.org/D1176
2015-03-17 18:18:19 +05:00
8d31c7f452 Use "Release Candidate 2" string on the splash 2015-03-17 16:49:59 +05:00
ee87056fd9 Correct assert 2015-03-17 15:49:40 +05:00
9c154d5b58 Fix T43997: Paste fcurve keeps handle selection 2015-03-17 15:49:36 +05:00
a40d7b93ac PyAPI: bpy.ops enum error was cut short 2015-03-17 15:49:33 +05:00
8c3853a9b5 Update themes for 2.74 2015-03-17 15:49:29 +05:00
Julian Eisel
b64d3bde8b Fix T44003: Flatty Light: GPencil vertices and timeline keyframes black
I noticed our version code and subversion got out of sync in the past, maybe
that's what the issue was here.
Deleting the entries from the .xml makes it fall back to the default values.
2015-03-17 15:49:25 +05:00
931f876ddd BGE: Fix for T43994 Steering actuator bug with Navmesh
Now the facing option is taken into account as before

This is a regression and to be ported to the final release branch.
2015-03-17 15:49:21 +05:00
2d1879b714 Fix T43959 jittering in 2D texture painting.
This is still not perfect,
but should work smoother now. Previously there was visible wobbling
while painting.

This can be included in final release.
2015-03-17 15:49:17 +05:00
86b862ecc9 Revert "Fix T43865: Cycles: Watertight rendering produces artifacts on a huge plane"
The fix was really flacky, in terms during speed benchmarks i had
abort() in the fallback block to be sure it never runs in production
scenes, but that affected on the optimization as well. Without this
abort there's quite bad slowdown of 5-7% on the renders even tho
the Pleucker fallback was never run.

This is all weird and for now reverting the change which affects on
all the production scenes and will look into alternative fixes for
the original issue with precision loss on huge planes.

This reverts commit 9489205c5c.
2015-03-17 15:49:08 +05:00
651689fc62 Fix T43974: Alpha output of movie clip node crashes blender
Issue was caused by a bug in the memory optimization commit,
should be backported to the final release branch.
2015-03-17 15:49:04 +05:00
f0e37fceb2 Partial fix for T43967: Background is wrong in 2.74
Was missing do-versions code after rotation order change in Cycles.

This is a regression and to be ported to the final release branch.
2015-03-17 15:48:56 +05:00
d21c1dc1b4 partial material deletion fix for Fracture Modifier, effectively keeping necessary slots, else the mesh gets messed up which leads to crashes, and... making visible_mesh_cached now necessary for returning a dm out of the modifier 2015-03-13 10:32:54 +01:00
13551302c0 fix: correction for material handling with sub object groups, it could happen that the index was calculated incorrectly, thus leading to black faces (no material) 2015-03-12 21:37:51 +01:00
151b6f25db added material handling for sub object groups, target object gets all materials of group (no duplicate slots, with proper index remapping) 2015-03-12 19:42:34 +01:00
8bd7d43ae0 added different constraint types which can be applied between clusters, with sub object groups meshes from different objects are converted to clusters automatically, so you can have in a limited way different constraint types between different objects 2015-03-10 12:42:37 +01:00
29c1dfcf8a combined cutter group with other point sources now, and moved it under Advanced Options, and some cleanup of ifdef 0 code 2015-03-07 12:29:07 +01:00
546eee7005 crash fix: forgot to "walk" over the cutter_group inside the modifier, effectively forgetting to set references to the helper group, thus resulting in a crash at loading time 2015-03-05 20:55:56 +01:00
006d6cfaf4 fix: greasepencil by edges did not take object transformation into account properly 2015-03-05 20:23:41 +01:00
70f7052a54 possible fix for loading subobject group objects with textures 2015-02-25 22:43:38 +01:00
9b6c9a8299 fix: crasher at loading objects with subobject groups, but TODO, sometimes odd mesh error (like missing texture or even 1 displaced vertex, probably due to threading issues ?) 2015-02-23 21:01:07 +01:00
28da4a786e fix: loading for subobject groups partially fixed, needs manual refresh afterwards still, TODO, proper material handling ("merge" object materials) 2015-02-23 14:20:56 +01:00
55df8ba231 fix: sub object groups should work a bit more reliable now, did crash very often before 2015-02-23 10:51:07 +01:00
e2669381e2 simplified greasepencil to mesh code (in fracture by greasepencil edge) a bit 2015-02-22 11:05:33 +01:00
c7b2cbe3b4 good performance improvement for autohide, using BM_face_at_index() now instead of BM_face_at_index_find(), which makes it reasonably faster 2015-02-22 01:44:27 +01:00
61ad3f80b7 fix: improved "fix normals" in conjunction with autohide, might be slower, but looks way better with the right settings (as in fix normals search radius and autohide distance) now, using limited dissolve with keep normals operator (during autohide) 2015-02-21 22:55:07 +01:00
f1714a370e fix: skip invalid shards when doing voronoi+bisect+fill, (less than 3 verts), this caused crashes when trying to load files with fracture results being stored this way 2015-02-21 14:04:05 +01:00
a6b53d6892 fix: some performance optimization when rebuilding constraints on triggered objects (was calling unnecessary restoreKinematic() function in this case) 2015-02-20 12:57:07 +01:00
bb64f588dd fix: rewrote clustering so it operates on the mesh islands now prior to constraint generation, instead of operating on shards only during fracture time 2015-02-19 18:58:23 +01:00
f5414f989b fix: mesh was messed up if you used no pointsource, just the islands. 2015-02-18 23:33:22 +01:00
2d1b5121df added greasepencil edge fracture, the direction of cutting is currently limited to global X, Y or Z axis 2015-02-18 20:46:15 +01:00
66affa5cf3 fix: cutter groups should work mostly now 2015-02-18 11:57:24 +01:00
eebf770f1d fix : set some better default values for Fractal Boolean, so the object / default cube should not explode automatically, but its far from optimal still this way.... (active objects with Mesh Shape cause unstable simulation behavior) 2015-02-17 22:39:25 +01:00
3014c07906 fix : forgot to set inner material with fractal boolean 2015-02-17 22:13:21 +01:00
61ca70df40 added cutter groups, this is intended to define custom sets of objects to make boolean cuts against, but its still WIP, as it still fails too often 2015-02-17 21:37:55 +01:00
0a604079b6 revert bad activation fix for triggering, caused crashes in some cases (like on non-kinematic triggers) 2015-02-15 19:32:47 +01:00
30de8274a3 fix: trigger system now triggers in time, there was a delay before due to unnecessary postponed revalidation, now the shards are directly activated on hit 2015-02-13 16:47:30 +01:00
4d82812e13 fix: for severe performance issue with fractal, did unnecessary unwrapping operations there 2015-02-10 22:37:46 +01:00
ef47b883cd crash fix: removing the fracture modifier again from object without executing fracture first did crash 2015-02-10 10:49:10 +01:00
02d82a9035 limit autohide distance between 0.0 and 10.0 (mostly very low positive values are used, like 0.001) 2015-02-09 14:24:09 +01:00
a238bbf323 crash fix: changing constraint settings prior to execute fracture caused a crash 2015-02-09 14:23:26 +01:00
f085584c71 fix: do not write shards with only 1 vertex, this causes problems when loading the file afterwards, omitting those shards and islands seems not having a negative effect up to now 2015-02-09 14:11:48 +01:00
43d426bb26 fix: crasher when appending object with modifier and when trying to remove rigidbody traces when no rigidbody world is available 2015-02-07 15:06:44 +01:00
28efc108ed fix: added cluster_group to presets 2015-02-06 21:28:53 +01:00
3fb798666a fix: clustergroup centroid search didnt take obmat into account 2015-02-06 21:24:00 +01:00
d4fce19d4f added a cluster group setting, where helper objects can define locations of cluster cores (shards will be added to its clostest core always), converted objects belong to a group now also 2015-02-06 16:26:21 +01:00
5cabdd394f fix: inner vertex group was empty after refracture 2015-02-04 14:49:59 +01:00
841d916796 fix : autosmooth didnt work on all faces when boolean fractal with smooth inner faces was used (added unnecessary sharp edges before) 2015-02-03 19:07:18 +01:00
a715ef9f7f allow independent setting of cuts and iterations (please PLEASE keep low like about 5 max but not at the same time ! or computation time will explode) but this allows some control over fractal pattern,
also allow smoothing of inner faces
2015-02-03 18:02:13 +01:00
5263d91491 first attempt of fractal boolean fracture, but speed is slow, result may be messed up and sim is unstable (use mesh shape and margin = 0, as well as scale down the physics mesh... or use constraints to keep the object together) 2015-02-03 14:41:17 +01:00
746c5035c2 Revert "splash screen update for branch"
This reverts commit 53efacd78c.

In future please don't commit custom splashes to branches, adds unnecessary binary file overhead to the whole repo

Noted here:
http://wiki.blender.org/index.php/Dev:Doc/New_Committer_Info#Branch_Usage
2015-02-02 09:40:21 +11:00
53efacd78c splash screen update for branch 2015-02-01 20:04:10 +01:00
3bc11a9cf2 fix: crasher when removing the modifier on frame > 1 and trying to rerun the sim , fix: crasher when reverting the file with fracture modifier on it 2015-02-01 18:44:44 +01:00
9f987ae2d0 remove version hack for MeshDataTransfer (since this is reverted now) 2015-01-24 13:17:34 +01:00
3dda7a4312 Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier
Conflicts:
	source/blender/editors/space_outliner/outliner_draw.c
	source/blender/makesdna/DNA_modifier_types.h
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/modifiers/MOD_modifiertypes.h
	source/blender/modifiers/intern/MOD_util.c (reverse-merged from commit 4401500cac)
2015-01-24 13:15:58 +01:00
fd490f416f Revert "Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier"
This reverts commit 4401500cac, reversing
changes made to bdb170ca60.
2015-01-24 12:58:35 +01:00
bbf09d9ee6 Point 2.73a release to updated addons revision 2015-01-20 23:16:03 +05:00
ced2738049 Show 'a' on the splash screen 2015-01-20 20:40:25 +05:00
e076fca578 Point addons to the backported revision 2015-01-20 19:10:39 +05:00
9bd38a1796 Bugfix T43293: Crash when editing shared GPencil datablock in VSE
The problem here was that when a Grease Pencil datablock is shared between
the 3D view and another one of the editors, all the strokes were getting handled
by the editing operators, even if those strokes could not be displayed/used
in that context. As a result, the coordinate conversion methods would fail,
as some of the needed data would not be set.

The fix here involves not including any offending strokes in such cases...

Conflicts:
	source/blender/editors/gpencil/gpencil_edit.c
2015-01-20 21:17:56 +11:00
aee458d674 Fix error in freestyle api 2015-01-20 20:20:17 +11:00
08eabd1997 Fix own error in freestyle api
Conflicts:
	source/blender/freestyle/intern/python/BPy_ViewShape.cpp
2015-01-20 20:20:03 +11:00
c9ca7b816e Fix T43311: using displacement shader crashes blender
Issue was caused by wrong order of scene device update, which could
lead to missing object flags in shader kernel.

This patch solves a bit more than that making sure objects flags are
always properly updated, so adding/removing volume BSDF will properly
reflect on viewport where camera might become being in volume and so.
2015-01-20 20:18:23 +11:00
dd1be8ccc5 Fix for security issue loading blend's
Auto-Execute option could be overridden by opening a startup.blend
2015-01-20 20:18:23 +11:00
41cb67647d Fix T43301: Three of the 'mirror keyframes' tools were mirroring along wrong axis.
Names are rather confusing here... :/
2015-01-20 20:18:23 +11:00
1bae0566b2 Sequencer: Don't crash when trying to rebuild proxy without having sequence edits 2015-01-20 20:18:23 +11:00
5374cfae78 SDL wrangler: Support loading SDL2 libraries of different names
Seems different distros might have different naming rules, so need
to adopt our code for that.
2015-01-20 20:18:23 +11:00
57087245a4 Fix T43156: Cycles incorrect final render, proper viewport with moblur disabled
Really stupid issue caused by typo in bitfield bit lead to bit conflict,

Not sure how it was done, could be some bad merge conflict resolve in the
original commit or just pure man stupidnes.

This is a nice example when having set of small test render scenes hooked
to the ctest would really help.

It's probably not that stopper issue (even tho still quite bad) since it
was made 2 months ago. But if we ever do 'a' this time it's a nice change
to include.
2015-01-20 20:18:23 +11:00
e51d7f1fb3 Fix T43229: Knife-project regression (broke knife-project)
There have been quite a few issues with knife precision,
tested reports (T43229, T42864, T42459, T41164) and this works with all.
2015-01-20 20:18:22 +11:00
f9aa8c64e6 BMesh: Tweak behavior for select more/less
Stepping over faces gives overall nice results but it stopped wire edges from working.
Now step over wire too.
2015-01-20 20:18:22 +11:00
0073b17d03 Fix OpenGL Context freeing 2015-01-20 20:18:22 +11:00
324d0448b1 Fix typo in OCIO configuration file 2015-01-20 20:18:22 +11:00
c08ef9c62a Fix T43208 material flickering in edit mode.
Happens because material setting now occurs in the derived mesh drawing
routine as it should. However that means that it also happens during
selection and that influenced the drawing state somehow.

In 2.72 this did not occur because material setting happened during draw
setting (skip or draw) instead of after the draw setting passed (so
selection would skip it by use another draw setting function). Of course
this violated design but worked.

Made it now so backbuffer selection does not enable materials (it's
redundant in those cases anyway).

This could be ported to a possible 'a' release but as is classic with
display code there may be some other places that it could backfire.

Tested fix with texture/vertex painting and selection which use
backbuffer for both subsurf and regular meshes and it seems to work OK.
2015-01-20 20:18:22 +11:00
ba43ea24a7 Fix T43204: Shrinkwrap constraint, project mode: Space ignored in bone case.
Own fault in rBb154aa8c060a60d to fix T42447... Reverted that commit, and added
kind of not-so-nice hack instead.

Note root of the issue comes from the special case we are doing here re 'Local'
space of parent-less objects. In that case, local space should be the same as
world one, but instead we apply the object rotation to it... This is inconsistent
with all other cases and could very well lead to other issues as T42447, but afraid
fixing that properly would be rather hairy - not to mention it would likely break
all existing riggings etc. :(

Should be safe for a 2.73a, shall we need it.
2015-01-20 20:18:22 +11:00
1253a46370 Fix for regression in bmesh connect-pair
T42563 fix wasn't right, fortunately this doesn't fail in most cases.
2015-01-20 20:18:22 +11:00
9a0c2c734c Fix texture sampling with generative modifiers - sample backbuffer
returns indices in mesh face range
2015-01-20 20:18:21 +11:00
973e387247 Fix for GTest 2015-01-20 20:18:21 +11:00
fdbedfef69 Fix gtest linking on ubuntu and do minor cleanup.
Generally for build systems, libraries that do not depend on other
libraries, such as system libraries, OpenGL etc always go at the end.

We could even get rid of some duplicate dependency libraries here but
auto duplication by build systems and differences between OSs make this
difficult.

GTest still duplicates all libraries twice to solve some issues which is
weird (maybe libs are not sorted correctly for some reason? needs
investigation)
2015-01-20 20:18:21 +11:00
1d0c23823d Fix crash in texture paint sampling when sampling materials without
textures slots
2015-01-20 20:18:21 +11:00
a1a182c268 Fix T40257: Frustum culling not working properly
Instead of getting fancy this time, we'll just use Mahalin's simpler
fix. This may have slight performance impacts, but it is a lot simpler
than the previous fix and shouldn't cause as many bugs.
2015-01-20 20:18:21 +11:00
e5fbe7466e Revert "Fix T40257: Frustum culling not working properly"
This reverts commit 315609ec0c.

This fix still causes more issues than it solves.
2015-01-20 20:18:21 +11:00
012f7ca1b5 Fix invalid memory access in gradient brushes - could cause a crash in
MacOS.

This looks like an oldie and should not influence release, but if we do
make an 'a' build it's safe to include.

Report by Craig Jones, thanks!
2015-01-20 20:18:21 +11:00
22cc938056 ugly modifier numbering "fix" for fracture modifier... just for the branch! 2015-01-11 18:04:32 +01:00
4401500cac Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier
Conflicts:
	source/blender/editors/space_outliner/outliner_draw.c
	source/blender/makesdna/DNA_modifier_types.h
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/modifiers/MOD_modifiertypes.h
	source/blender/modifiers/intern/MOD_util.c
2015-01-11 17:35:46 +01:00
bdb170ca60 refactored function for loading fracture modifier out 2015-01-11 17:21:39 +01:00
53034cf102 compile fix due to function name cleanup 2015-01-09 15:12:47 +01:00
4c6b50c8ab Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier 2015-01-09 14:54:19 +01:00
67439dfe06 Remove executable flag from the build configuration files
They're not intended to be executed directly and seems mode change happened
by accident.

Setting -x for this files to avoid possible incidents by trying to run this
files in shell.
2015-01-08 23:44:29 +05:00
96629dfe0e exclude git/arc files from tgz archive 2015-01-08 23:44:02 +05:00
1a7c5ccbfb correct permissions 2015-01-08 23:43:55 +05:00
Dalai Felinto
b4d8fb573e Logic Bricks *must* be kept in alphabetical order 2015-01-07 18:17:20 +05:00
a52fe40c84 Followup to fe3e000: no need to exit pose mode on operator redo
This is to be backported to the release branch.
2015-01-07 15:44:49 +05:00
fedb34c592 Fix: Segfault in Image Editor when transforming GPencil Strokes 2015-01-07 15:44:30 +05:00
9f5223e4d2 Fix: Missing updates for UI panels and main region when using Grease Pencil in Image Editor 2015-01-07 15:44:20 +05:00
2db46a6045 Fix: Restored "Draw Poly" to D Ctrl RMB, as D Alt LMB was blocked by Alt-D (duplicate) keymap 2015-01-07 15:44:15 +05:00
f7aab6ca5b Blender 2.73 release commit
Hopefully this one would eb the exact revision used for 2.73 final release
2015-01-06 17:58:44 +05:00
110459c0da GTest was broken on Linux 2015-01-06 14:57:07 +05:00
ee045d2bd5 BLI_string_utf8: add BLI_strncpy_utf8_rlen 2015-01-06 14:55:57 +05:00
d93ccef052 Fix T43143: DPX header wrong, making it impossible to import to other software
The issue was caused by the single letter in header, which is expected to be
captial as per standard: http://www.simplesystems.org/users/bfriesen/dpx/S268M_Revised.pdf
2015-01-06 14:33:39 +05:00
0b5a64fe7f Fix T43122: Shrinkwrap target, wrong linked object 2015-01-06 14:33:39 +05:00
f322362363 Recent fix for SDL2 broke joysticks for SDL1.2 2015-01-06 14:33:38 +05:00
b8b7bd0e6a Fix for crash for 'Edit Source'
was accessing freed menu region.
2015-01-06 14:33:38 +05:00
ff09547f80 Fix 8 memory leaks from bad PyList_Append use 2015-01-06 14:33:38 +05:00
91a975100c Fix for view map cache not flushed by updates of edge detection options.
This fix should be considered for inclusion in the 2.73 release, since
it concerns a new feature of Freestyle introduced in 2.73.
2015-01-06 14:33:38 +05:00
5be01ff4b3 Cycles: Fix compilation error on AVX platforms with -arch-native
Was a conflict in headers between clew and util_optimization.h.
2015-01-06 14:33:38 +05:00
a912699792 Fix (unreported) 'pad9' not shown by UserPrefs' KeyBinding filter.
Minor glicth, but still... Safe for 2.73.
2015-01-06 14:33:38 +05:00
b7b5c99215 Fix T43099: Modifiers in edit mode might mess up materials
The issue was originall caused by 2e8ba17 by removing necessery call
GPU_enable_material(). It was probably removed because in some cases
material was enabled after calling setDrawOptions.

That wasn't always a case for edit mode.

This is absolutely to be included to 2.73
2015-01-06 14:33:38 +05:00
84dde30662 Fix T43066: Joystick broken in GE since 2.73rc
Caused by move to SDL2, fix thanks to jensverwiebe.
2015-01-06 14:33:38 +05:00
6fab0a4643 Joystick: Suppress add/remove device events
Previously they'll be printed to the console as a totally unknown events
together claim this shouldn't have happened which is just misleading.
2015-01-06 14:33:38 +05:00
137ddd665e Fix an odd line that slipped in my ghost_hack_first_file commit 2015-01-06 14:33:37 +05:00
fe3e000511 Fix T42780: Object linking allows to have linked armatures in pose mode
This isn't so bad for until one goes re-posing the armature and then uses undo.

It is the same issue as with edit mode which was solved back in the days.
2015-01-06 14:33:37 +05:00
b0dc79c14b Revert "Fix T42888: Separate and Combine HSV distorts the hue value"
This reverts commit 1549fea999.

After some further discussion with other developers in the team it becomes
clear there's no correct solution here. It is just more matter of what's
more convenient in particular case.

We're just going back to old code to avoid possible frustration with the
older files in newer blenders. This also means all HSV/HSL is considered
to be "linear" in the shading nodes.

Would be ported to 2.73 final.
2015-01-06 14:33:37 +05:00
6b6b28a9d4 fix for doc generator 2015-01-06 14:33:37 +05:00
0a1deaf89c Fix leak in cycles-bake 2015-01-06 14:33:37 +05:00
71d16196f3 Fix leak in select-similar regions 2015-01-06 14:33:37 +05:00
2a72518af7 Fix buffer overrun calculating unique names 2015-01-06 14:33:37 +05:00
a04f7de6b7 Fix a very stupid memleak in own bpy_app_translations.c code...
Safe for 2.73.
2015-01-06 14:33:37 +05:00
9cc8a5c673 Fix T43034: beautify-fill leaves zero area tri's 2015-01-06 14:33:37 +05:00
4508642489 cleanup: redundant tri-normal calculation 2015-01-06 14:33:36 +05:00
e436c83be0 Only add a fill brush to default .blend if there isn't one already. For
some reason this happened twice here.

Likely candidate for 2.73 final
2015-01-06 14:33:36 +05:00
950be80ab8 Fix T43010 regression in material setting.
Caused by own fix for another display case.

Shoud be safe for 2.73 final.
2015-01-06 14:33:36 +05:00
julianeisel
919ec85f6c Fix T42977: Weights failed to display in Wireframe mode when using Face Select
D948, reviewed by @mont29 (thanks for that)
2015-01-06 14:33:36 +05:00
cde1351578 Fix T42641, Graphical fragments showing on Blender 2.71 and higher when baking.
Safe for 2.73...

This revert rB9b0ab890676790bb1e8e77797629b889ea66f69e - needed to set that threshold to a small
negative value to remove the last artefacts reported in T39735, but now I could not reproduce
any with the previous 0.0f value, so restoring it for the time being.

If this 'shadowed neighbor face' case re-appears, we can always choose a value in-between, like -1e-18f...
2015-01-06 14:33:36 +05:00
9556f61013 Fix T43013: Flip with bridge aligned loops 2015-01-06 14:33:36 +05:00
880f4fbc38 cleanup: use cross_tri_v2 when area isn't needed. 2015-01-06 14:33:36 +05:00
ae1d416aec OSX: revive GHOST_HACK_getFirstFile cause it breaks things on older OSX versions.
Dunno exactly why this was done earlier, but propose not to remove code not understood.
2015-01-06 14:33:36 +05:00
31862bc562 Fix T42938: image.save_render sometimes saved the wrong pass
Stupid mistake with non0initialized image user.

Safe for final 2.73 release branch.
2015-01-06 14:33:36 +05:00
f1ab8f8930 Cycles: Fix really bad bug with shadow rays on non-SSE CPUs
basically shadow rays were totally broken and most of the time did not record
any intersections, leading to really ad rendering artifacts.

This commit makes it so regardless of enabled optimization level render result
would be the same.
2015-01-06 14:33:35 +05:00
3fcc5520fd Fix rna paint update callbacks assuming meshes 2015-01-06 14:33:35 +05:00
5a51b93aa5 fix: restore kinematic state for regular triggered rigidbodies always now, they very likely were kinematic before, user must disable triggered checkbox if this is not desired 2015-01-02 15:15:01 +01:00
6c4c1fbb3c fix for unnecessary activation of all parts again and again, this resulted in never ending movement... now this applies to kinematic objects only, which lose their kinematic state due to being triggered 2015-01-01 12:54:51 +01:00
752dd1c567 fix for incorrect merge in MOD_boolean_util.c, old functionality isnt necessary any more 2014-12-31 15:46:21 +01:00
6be2aab8d6 compile fixes due to merge 2014-12-31 14:00:22 +01:00
6b6a968053 Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier
Conflicts:
	extern/SConscript
	release/datafiles/splash.png
	release/datafiles/splash_2x.png
	source/blender/blenkernel/intern/rigidbody.c
	source/blender/editors/physics/rigidbody_constraint.c
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/modifiers/intern/MOD_boolean_util.c
	source/blender/windowmanager/WM_api.h
2014-12-31 13:59:45 +01:00
480ed9df62 crash fix: automatic material names management was wrong (got internally longer and longer and caused a stack overflow after some fracture attempts) 2014-12-27 16:21:34 +01:00
c93971e49e fix: convert to keyframes works directly from bake now, too 2014-12-27 14:40:05 +01:00
be30a2cd18 added a trigger flag, only rigidbody objects with this flag can trigger other objects (which themselves must be animated and have their "triggered" flag enabled 2014-12-27 13:27:10 +01:00
d46632d4cf fix: apply scale only prior to fracture again, preserve rotation because splinter rotation needs to be local 2014-12-27 13:08:27 +01:00
b0921d3f99 activate objects now when constraints are broken, this is an attempt to get rid of single shards stuck in the air, not being connected visually to other shards 2014-12-18 20:20:23 +01:00
fab16ef5d6 windows crash fix: material name had incorrect length 2014-12-17 21:00:28 +01:00
29434373dd fix for: splinters (axises should be local X, Y, Z again), added object name into material name, and allow conversion-to-keyframed-objects of multiple objects at once 2014-12-17 18:34:46 +01:00
d7a9e5ac94 fix: load inner vertex group now directly after blend has been loaded (no additional refracture necessary) 2014-12-15 20:51:52 +01:00
904dc50fd4 fix for inner vertex groups (contains real inner shards vertices now only) and option for smooth inner faces (useful with following subsurf and displacement modifier, works properly with boolean only 2014-12-15 13:36:42 +01:00
42f7a29f57 small fix, need to check for context.object being possibly None 2014-12-10 23:35:51 +01:00
5bb20444c6 added hack to enable loading fracture presets via python (bpy.context.fracture is not known otherwise when using python_file_run, it needed a fake context 2014-12-10 23:30:18 +01:00
05fdb2e63f added a breakable checkbox for fracture modifier, this is an attempt to enable destructability later on when needed 2014-12-06 22:53:50 +01:00
88ddeb3edc Modifier GUI "redesign", second revision 2014-12-01 20:23:49 +01:00
b4b0eb6315 splash update 2014-12-01 19:52:43 +01:00
420dff8cd3 Modifier GUI "redesign", first revision 2014-12-01 13:12:49 +01:00
8e2b30f1eb rename "Initial Particle Coordinates" to "Particle Birth Coordinates" 2014-11-24 16:39:23 +01:00
c890d60651 cluster breaking angle, distance, percentage added, rename contact distance to search radius, jump back to start frame of rigidbody cache now automatically at fracture time (or frame 1) 2014-11-24 16:36:27 +01:00
f09b89df01 automatically apply scale and rotation when executing fracture now 2014-11-21 20:41:15 +01:00
07d652a840 crash fix for convert to objects and fix for invalid positions after conversion as well (was all zeroed out) 2014-11-21 15:41:54 +01:00
1922d5e6d2 fix for convert to keyframed objects, had oddly rotating objects and NaN values in transform panel 2014-11-21 14:58:43 +01:00
b463ffc52c small improvement for autohide, removing inner edges now as well 2014-11-17 15:48:58 +01:00
95ccb70e1d fix for "fix normals", used incorrect float to short and back conversion and ignore global rotation of object in normals rotation now 2014-11-17 02:35:53 +01:00
60c776d014 limit autohide to faces with inner material and fix attempt for convert to keyframes bug (messed up object locations / rotations) 2014-11-16 16:23:09 +01:00
b89f7af287 added ghost objects, they do not collide but can activate animated objects 2014-11-16 03:07:31 +01:00
dcb0c61495 autohide now automatically removes doubles as well to close small gaps between shards due to constraint movement, tweaks to pointcache (no reset of cache) and a new bm operator (no normal recalc) were necessary 2014-11-15 00:35:18 +01:00
c519abe466 tweaks for convert to keyframe objects and fix normals 2014-11-14 16:49:34 +01:00
949be0f50a change order of checked expressions in rigidbody object creation -> could crash on non-mesh object 2014-11-13 22:43:08 +01:00
1dc314342d memory leak fix in find_normal 2014-11-13 01:43:07 +01:00
9283c5e96c fix normals improvement: take only normals pointing to same direction into account inside a certain search radius 2014-11-13 00:12:39 +01:00
fdb18c9d64 can activate constrained objects too, new setting: cluster solver iterations override, attempt to show only cracks between clusters during activation 2014-11-12 13:14:00 +01:00
96aac3fa6f rigidbody trigger activation fix, works better with constraints now and let objects with passive group appear as active 2014-11-12 11:46:36 +01:00
f7d25d5c6d for rigidbodies with mesh shape, take only the mesh into account when triggering rigidbodies (instead of boundingbox) 2014-11-10 18:46:57 +01:00
985df04b87 only take active objects into account with kinematic deactivation (trigger) 2014-11-09 20:08:46 +01:00
f3d0a7591f automatically create inner (and outer) material if not specified 2014-11-09 12:55:21 +01:00
0a59c0132e Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier
Conflicts:
	source/blender/blenkernel/intern/pointcache.c
	source/blender/blenkernel/intern/rigidbody.c
2014-11-08 12:58:48 +01:00
608a662ecb triggered objects dont need to be fractured any more and restore kinematic after load 2014-11-08 12:14:36 +01:00
16ee031bb7 only activate actually touched shards (todo, maybe override this with a global setting) 2014-11-06 21:16:01 +01:00
b306d0de39 had to disable trigger of constrained object by other non-triggers, this lead to permanent bullet crashes 2014-11-06 19:06:08 +01:00
18675f77fc another crash fix if simulation was continued after cache end with trigger and constraints, cache might behave incorrectly still if an object is refractured for example, but the others are not 2014-11-06 15:47:53 +01:00
ee199c563d crash fix for trigger when used with constraints, they were attempted to be removed multiple times 2014-11-06 14:10:32 +01:00
1fb3642cda added a new "Triggered" checkbox to rigidbodies, which allows them to be triggered in case they are kinematic. this will reset the kinematic state and make them dynamic 2014-11-06 12:39:58 +01:00
fcad67e087 fake trigger, disable animated checkbox on collision, (but this should be done by hand, earlier, to get better impact speeds) 2014-11-06 02:33:21 +01:00
936bb32d45 new splash screen and fixes for convert to keyframe operator, empty was parented incorrectly (depgraph update missing, but threaded option is broken now) 2014-11-02 01:44:22 +01:00
32a4b43dbc bugfix, convert to keyframed objects didnt work when escape was used to stop the simulation before 2014-11-01 17:10:18 +01:00
88a66ded74 optional job system for convert to keyframed objects, faster conversion, and taking bakes into account 2014-11-01 14:37:58 +01:00
026ffafb1b Bake modifier simulation to keyframed objects directly 2014-11-01 01:28:20 +01:00
d7bc7de7a9 customdata support with sub object groups 2014-10-31 11:46:12 +01:00
f12479c458 support fractured mesh as fluid obstacle 2014-10-31 02:08:34 +01:00
d2fa5668ae centroid fix / point cloud fix, forgot to multiply with splinter matrix 2014-10-30 13:20:59 +01:00
f64eef7a5f simplified wood splinter settings, can set scale factor and direction now directly 2014-10-30 12:10:37 +01:00
27521b0671 crash fix: when fracture is triggered on disabled modifier, modifier is re-enabled and fracturing again, simulation can crash. Also fix for not being able to fracture afterwards (push button twice or alternatively hit Alt A or remove and re-add the modifier 2014-10-24 20:48:25 +02:00
cfec1eea63 reordered functions and made them static in MOD_fracture.c, leaving out some unnecessary info for writing to blend in writefile.c (still have that read_struct memoryleak sometimes) 2014-10-21 18:55:18 +02:00
a6a38e56f4 compile fixes after using more strict compilation settings, quiet some warnings effectively this way 2014-10-19 20:59:34 +02:00
aa7ccbff35 crash fix: deleting fracture modifier helper objects left group objects with go->ob == NULL, which caused crashes in depgraph update, now also deleting group objects with go->ob == NULL 2014-10-19 13:28:34 +02:00
79392ccad9 simpler and cleaner reimplementation of clustering algorithm, caused crash before 2014-10-18 10:27:46 +02:00
a98a70dd0c Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier 2014-10-12 17:13:29 +02:00
8cea11e1a7 memoryleak fix, forgot to free nor_tree in some cases 2014-10-11 15:22:25 +02:00
120b572367 fix for messed up mesh if object is moved out of particle range, and some clarification for sub object group (last attempt to fix failed again, hrm) 2014-10-11 14:31:16 +02:00
3aa6de7e43 fix for: comparison with wrong rigidbody count caused deactivation of the cache and simulation was not cached any more 2014-10-10 20:30:00 +02:00
a468002406 dont use BLI_findlink for first shard (can access directly) and load shards into correct "parent" struct 2014-10-10 16:29:33 +02:00
7ccbc6651b crash fix when fracturing, missed initalization of listbase and quiet some warnings 2014-10-10 16:07:17 +02:00
3fbbb2752c replaced Shard pointer to arraypointer by ListBase for FracMesh->shard_map in DNA, for fracture modifier 2014-10-10 15:55:50 +02:00
92dbf1c9da forgot to calculate volume of whole object in mass calculation, leading to each shard having the same mass 2014-10-10 10:43:57 +02:00
e0712fc38b Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier 2014-10-09 23:34:39 +02:00
556476ab22 reactivate fracture modifier object deform motionblur support, was disabled with last commit 2014-10-09 22:55:27 +02:00
b5ab717f88 Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier
Conflicts:
	source/blender/editors/physics/CMakeLists.txt (reverse-merged from commit c9769a6808)
2014-10-09 22:28:51 +02:00
1c256222dd memory leak fix for text fracture / sub object groups 2014-10-09 19:27:04 +02:00
c9769a6808 Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier
Conflicts:
	source/blender/editors/physics/CMakeLists.txt
2014-10-09 17:13:27 +02:00
c4b94f3049 explaining comment: "need to distinguish between mesh and non-mesh objects for fracture modifier" and quiet some warnings 2014-10-09 16:29:33 +02:00
bec396fc96 removed unnecessary conversion from radians to degrees (internally) and using degrees just in the UI 2014-10-09 16:24:55 +02:00
4048c4ddae replaced rigidbody count function (avoiding 3 different loops over rigidbodies) and quiet some warnings 2014-10-09 14:55:42 +02:00
e75530e435 cleanup: automatic code styling with uncrustify_clean.sh 2014-10-09 13:52:13 +02:00
bc99752aa2 closed some memory leaks when calculating shard mass and after fracture (C++ cell struct) 2014-10-08 21:27:11 +02:00
ee936bc922 added new setting for fracturing with particle sources, in most cases you want to use the particle
birth coordinates as pointsource, but you can override this to get the coordinates of the current particle simulation state. But as the particle cache is kinda broken and shows wrong positions at beginning if simulation has been run before, this can lead to errors. Best practice is to keep this option enabled, only disable if you really need to !
2014-10-08 13:02:08 +02:00
255fe8a9b1 cleanup: removed unused code and quiet some warnings 2014-10-08 11:01:41 +02:00
aeaf5d2967 crash fix for fracturing with particles, missed proper initialization of voro++ interface struct (in case no computation takes place we need to zeroize the structs in the array though) and usage of particle_state instead of particle_birth coordinates, to be able to use particles not directly at birth position (after particle simulation has run a while) 2014-10-07 23:20:45 +02:00
78c9142163 crash fix for: appending objects with fracture modifier from library blends without their respective scenes and attempting to fracture then to build up the modifier structures 2014-10-07 16:54:34 +02:00
78a1999a2b windows compile fix for inner shard unwrapping, used C99 standard array before there 2014-10-06 10:59:22 +02:00
556c4ae27f scons compiling fixes 2014-10-05 20:35:59 +02:00
36fa6826a8 cleanup, removed old unused code (old access method with filepointer) 2014-10-05 20:35:26 +02:00
249ccbdca7 rewrote access to voro++ to direct memory access, no file descriptors needed any more, needs test under win / mac as well 2014-10-05 15:54:18 +02:00
6812ad4a82 Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier_oldsim
Conflicts:
	source/blender/modifiers/SConscript
2014-10-03 17:41:41 +02:00
c6c495d7bf forgot copying cluster count when copying modifier settings 2014-10-03 16:38:30 +02:00
3a4344a9fa attempts to fix one small memleak in read_struct, but fail.... grrr where on earth this is supposed to be freed again ? 2014-10-03 11:55:04 +02:00
07a4b5c8e2 set voronoi + boolean as default fracture algorithm 2014-10-02 18:33:32 +02:00
96c15edf23 quick fix: copy modifier settings when copying the object 2014-10-02 16:33:29 +02:00
d8f0f75896 memory leak fixes while fracturing, but small leak while loading still present 2014-10-02 15:47:40 +02:00
de4e6a8c74 re-enabled a bullet(!) assertion which earlier caused frequent crashes in fracture modifier, its not acceptable to disable it (and probably wont help much, either) 2014-10-01 19:45:18 +02:00
86dc5b4e91 fix for compiler errors due to obviously missing includes 2014-09-30 11:03:09 +02:00
0320a2818a pre-review cleanup part 2 (style, comment cleanup) 2014-09-30 11:02:27 +02:00
454f6f7790 pre-review cleanup part 1 (until object.c, rest will follow in part 2) 2014-09-29 20:26:06 +02:00
fbed421177 removed some old demolition remainders (that was accidentally merged in before) 2014-09-25 12:47:16 +02:00
c9db5f28a5 merge related compile fix 2014-09-24 20:22:49 +02:00
249a962bf4 Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier_oldsim
Conflicts:
	source/blender/bmesh/intern/bmesh_operators.c
2014-09-24 18:38:59 +02:00
174b4e3c39 Merge pull request #4 from JT-a/fracture_modifier_oldsim
Updated and added GPL headers w/Scorpion81 as contributor.
2014-09-24 18:22:54 +02:00
JT Nelson
39a080a238 Updated and added GPL headers w/Scorpion81 as contributor.
NOTE: did not assign author as copyright holder.  BF is assigned as copyright holder.
2014-09-19 08:26:21 -07:00
f323034489 preset update (covering newer settings) and inner vgroup now usable without inner material; but not very useful, hmm (because at higher shardcounts the entire object is selected, due to vgroup selection mechanism) 2014-09-09 21:09:20 +02:00
fa9e582898 inner faces are added to the existing active UVMap now 2014-09-09 08:58:28 +02:00
e5ff9cb892 first attempt of adding UVs to inner faces, need to pack them correctly still and put into separate UV Map.... 2014-09-08 15:00:02 +02:00
1a39125f7b fix for percentage (0 means deactivated again if not weighted) and used minimum again for weights 2014-09-05 00:02:20 +02:00
5a5cfba4a6 some bugfixes related to cleanup and taking averages for island weights again 2014-09-04 23:37:45 +02:00
837d3430bc constraint crash fix and breaking conditions fix (were evaluated incorrectly) 2014-09-04 01:48:21 +02:00
fb95e45983 take minimum of island weight instead of average as threshold modifier 2014-09-04 00:10:44 +02:00
d5e20f82c2 cleanup related compile fixes 2014-09-03 23:32:23 +02:00
c9e7a26d2a Cleanup for master, part 1, WARNING: Incompatible to older blends to to changes in DNA / loader 2014-09-03 22:41:46 +02:00
8a78bce10b added weighted percentage, distance, angle 2014-09-02 22:46:56 +02:00
1f1573019c fix attempt for own / extra vertices (was wrong transformation) 2014-09-01 13:03:34 +02:00
8bebaf6e29 fix for: customdata related crash in conjunction with split shards to islands 2014-08-31 23:11:18 +02:00
151d42c4bc fix for: fix normals (will be stored and loaded now, and transferred to convert objects too, BUT: split shards to islands has a bug there still) and convert to objects (get rid of all modifiers before fracture in stack, so the result wont be messed up) 2014-08-31 13:32:30 +02:00
21a070ec33 marking inner edges as sharp for boolean and bisect fill, additional option to fix normals (with edgesplit modifier) 2014-08-30 22:09:43 +02:00
77a2313ee6 fix for bake to keyframes 2014-08-30 11:21:44 +02:00
a955cb0fe8 attempt for customdata warning fix 2014-08-29 22:15:17 +02:00
bb8f482b27 own particles transform fix (forgot to multiply with imat) 2014-08-29 20:41:57 +02:00
689909d027 added fast bisect + fill algorithm 2014-08-29 15:09:34 +02:00
9874aa532d memory leak fix (autohide) 2014-08-28 23:00:23 +02:00
f8d4e67c4c some depgraph fix (related to fracture modifier, and scene_sort_group() 2014-08-28 22:26:46 +02:00
fe30202984 some depgraph attempts... WARNING: unstable ! 2014-08-28 21:33:13 +02:00
1d8c635499 fix for calculate mass crash, and attempt for edgebased fracture with voronoi (disabled, not working yet) 2014-08-28 18:18:32 +02:00
b2d7241473 crash fix when loading blend (due to new autohide option) 2014-08-26 11:54:55 +02:00
9f0017e426 added autohide distance, by default 0 and deactivated, as it slows down the sim and causes a big memory leak, also crashes randomly sometimes 2014-08-26 02:33:24 +02:00
149c6ed4b5 using inner material for finding inner vertex group now, other direct attempt was not successful 2014-08-24 13:21:54 +02:00
e79f713a66 float breaking angle and automatic deactivation (manual re-activation) of auto-execute when sim is started 2014-08-22 21:35:59 +02:00
8f9b3ee41b fix: mesh shape related memory leak and rebuild constraints after refracture 2014-08-19 23:59:06 +02:00
9486eee9bf attempt to create sub-objects by referencing a group of "child" objects within the modifier, but customdata transfer (like textures) wont work for some reason 2014-08-17 16:08:24 +02:00
1bec8ebf5c fix for inner vertexgroup, it worked on 1 shard only because it was always deleted and recreated for each shard, instead of sharing it (split shard to islands needs an inner material still) 2014-08-13 09:37:24 +02:00
5c7774e166 memory leak reduction, there still is a smaller one in readfile.c somewhere, sigh... 2014-07-30 11:05:32 +02:00
c605ce3974 fix for crash at changing mass when not at frame 1 2014-07-29 19:51:18 +02:00
924fbed8bc delete constraints always now before deleting meshislands, may crash otherwise 2014-07-28 16:50:44 +02:00
10b03edbc1 allow convert to object for modifier on non mesh objects too 2014-07-27 20:28:45 +02:00
6accd5ec1d typo: used SURF instead of SURFACE, prevented panels showing up correctly 2014-07-27 17:27:00 +02:00
870c06a9f5 added possibility to fracture text directly 2014-07-27 17:21:21 +02:00
765d2addc2 fix for editmode selection bug, added new option "auto execute" -> enable for editing, disable for simulation 2014-07-27 12:36:52 +02:00
7d6f7b161b crash fix for pressing "use constraints" prior to execute fracture 2014-07-26 18:47:30 +02:00
9a4ab59f33 another fix for the update bug, this time it really should work... 2014-07-26 13:33:01 +02:00
7e3190a51f added support for inner vertex group... WARNING: this is still UNSTABLE 2014-07-26 11:57:23 +02:00
f21c0c9a4b forgot to change one BLI_temporary_dir() call to BLI_temp_dir_base() 2014-07-25 23:57:10 +02:00
aaf82e554c change: rebuilding constraints should work now, BUT you have to put a modifier on all rigidbody objects now, otherwise the regular active rigidbody object will be reset when continuing an interrupted simulation, need to investigate why... 2014-07-25 21:16:01 +02:00
6301adb673 fix for re-enabling the constraints, takes now all objects into account in the first sim step 2014-07-25 20:32:39 +02:00
36ed23d6d5 fix for constraint update bug, all constraints must be re-enabled after a fracturing run if they are not recreated 2014-07-25 16:55:57 +02:00
391c09519c removed compound shape from RNA (did not work with modifier) 2014-07-25 16:55:15 +02:00
39945517e4 crash fix with other pointsources, forgot to initialize counts to 0... 2014-07-25 12:08:41 +02:00
a3b7f55d56 fix for losing texture images after load (pink object) but this still adds the image to the inner faces unintendedly, only should affect viewport and viewport render, glsl and rendering looks ok 2014-07-23 21:28:43 +02:00
9933f8ce80 convert to objects fix: now should take textures into account too 2014-07-21 10:29:02 +02:00
6b428cfb09 windows compile fix: replace BLI_temporary_dir() by BLI_temp_dir_base() 2014-07-21 08:37:35 +02:00
2101aaef83 fix for: fix normals, can use modifiers before fracture now too to get correct result 2014-07-21 08:36:57 +02:00
ed27f45665 revert last change again, was just a test 2014-07-20 21:00:15 +02:00
ead157ff39 gitmodules test 2014-07-20 20:43:18 +02:00
e67bba1100 merge related compile fixes 2014-07-20 10:13:57 +02:00
f1d6d5ab95 Merge branch 'master' into fracture_modifier_oldsim
Conflicts:
	extern/CMakeLists.txt
	source/blender/blenkernel/intern/rigidbody.c
	source/blender/editors/interface/interface_templates.c
	source/blender/editors/object/object_edit.c
	source/creator/CMakeLists.txt
2014-07-20 06:34:51 +02:00
79888418c7 forgot to initialize totvert variable prior to building a kdtree 2014-05-27 19:02:43 +02:00
1ccf1b3e8b fix attempt for halving case, passive groups didnt work properly there 2014-05-27 16:42:00 +02:00
1f2077a8e4 added inner material support for boolean and bisect fill 2014-05-27 14:55:25 +02:00
eace5891ec added a fix normals option to let cracks in smooth objects nearly disappear, also rotates the vertex normals with the verts... WIP... because i need somehow to get the derivedmesh of the previous modifier in stack if there is one 2014-05-26 22:58:42 +02:00
feee2a4a77 added vertweight display for fracture modifier, and attempt to update data in case vgroups are changed, but this doesnt work, seems to require a refracture to interpolate data again 2014-05-26 16:15:06 +02:00
5bac249193 added vertex group support to mark passive areas of an object (which remain static)
also rudimentary ground toggle / ground connect toggle operators
2014-05-25 22:05:46 +02:00
c1515ce482 compile fixes after merge 2014-05-17 13:32:39 +02:00
21c06c40f4 Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier_oldsim
Conflicts:
	source/blender/blenkernel/intern/DerivedMesh.c
	source/blender/blenkernel/intern/rigidbody.c
	source/blender/blenkernel/intern/smoke.c
	source/blender/editors/space_buttons/buttons_context.c
2014-05-17 12:56:31 +02:00
1e8aca99a8 just crash prevention, but mesh can still be messed up when attempting to move mesh out of fracture point location, especially with greasepencil 2014-05-14 23:47:42 +02:00
dd957e2be3 bah, other pointsources than uniform tend to crash, this is a fix attempt for greasepencil (but generally, dont try to move the object after fracturing with greasepencil by hand.... 2014-05-14 23:37:38 +02:00
65b6952a6f small gui fix in regular rigidbody constraints panel 2014-05-14 10:36:40 +02:00
f533d01fc8 well, a crash "prevention" with autosmooth, but it doesnt work anymore with the fracture modifier this way. 2014-05-13 23:22:40 +02:00
3b8eccb58f added threshold vertexgroup support (a single vertexgroup with weightpainting) 2014-05-13 17:23:06 +02:00
d1bbe76be8 reactivated modifier editmode "support" (but well, it doesnt really work...) and removed fracture edit mode (didnt work at all) 2014-05-13 09:28:54 +02:00
bfd5143aa2 added fracture preset storage and fix for loading files -> mesh was doubled there 2014-05-13 01:07:33 +02:00
576c3c5f94 re-added contact distance and mass dep. thresholds, also fixed a python gui error -> override solver iterations in scene 2014-05-12 23:07:06 +02:00
3a9261dbdf fix for automatical recreation of constraints after loading 2014-05-12 13:35:23 +02:00
a0ed785e78 fix for not updating fractured mesh with constraints enabled 2014-05-12 13:07:43 +02:00
dc96f8014d fix attempt for messed up bake data after linking objects 2014-05-11 20:35:49 +02:00
c9e920de81 copy rigidbody world when linking objects to scenes (if it exists) 2014-05-11 19:10:26 +02:00
92b42ef2aa can copy rb bakedata now with scene 2014-05-11 18:15:57 +02:00
4e5c2af871 crash fix for loading data with halving applied only (and no fracture) 2014-05-11 11:01:05 +02:00
04b00078d8 progress bar display fix attempt, still glitchy... 2014-05-10 16:54:59 +02:00
9f83814cb5 partial fix for progress display (can still exceed progressbar) and fix of a memoryleak when halving only 2014-05-10 14:19:21 +02:00
fb7ef3aed4 copied derivedmesh was not freed after usage 2014-05-09 20:55:46 +02:00
c9ad3c2da2 and even more gui cleanup 2014-05-08 19:34:12 +02:00
35cfca7a2c further gui cleanup 2014-05-08 14:16:34 +02:00
4396f9df88 fracture gui cleanup 2014-05-08 01:09:59 +02:00
4e59fa1b4b another crash fix attempt for refreshing constraint data on running / cancelled fracture 2014-05-07 18:31:55 +02:00
9687cb268c partial fix for crash at refresh constraints during fracture, or after cancelling it 2014-05-07 17:43:30 +02:00
f4ff8ff505 prevent fracture modifier removal when job is running 2014-05-07 10:52:39 +02:00
2cced6f6ff added running flag to prevent main thread from modifier execution when job runs, avoids crashes 2014-05-07 10:16:10 +02:00
27ef95a4b9 added (as experimental setting) the possibility to execute the fracture process as separate threaded job, but this crashes still very often, need to copy the modifier and stuff to a separate context and copy back afterwards 2014-05-07 01:59:48 +02:00
5f286bde0c some code cleanup, and attempt to find memoryleaks, but some are still present, sigh... again customdata related... 2014-05-06 14:38:36 +02:00
f158870a9a avoid crash when refresh after split to islands was missing and file was saved, but this is inconsistent sometimes, requiring an additional refresh possibly (due to memoryleaks possibly) 2014-05-05 23:33:08 +02:00
43e4a5b71e customdata fix for split islands 2014-05-05 13:02:26 +02:00
9df14f9c67 storage of split islands should work now... 2014-05-05 12:55:58 +02:00
202fd41d1a halving "improvement" made it only much worse performancewise, so keep the old one 2014-05-04 17:38:13 +02:00
44d97d0f47 added split shards to islands option... but with complex objects you need gazillions of constraints to hold this together... very very slow... 2014-05-04 14:47:58 +02:00
b986107829 another pointcache interpolation fix.... 2014-05-04 11:11:21 +02:00
3279e9227f possible fix for pointcache interpolation error with rigidbodies and subframes 2014-05-04 02:45:04 +02:00
cad0e8f07e hmm motionblur did work now ? strange... so commiting this as well 2014-05-02 20:10:45 +02:00
991100912a attempt to enable deform motionblur, FAIL... (object is not rendered at all) 2014-05-02 20:03:54 +02:00
e47b30595f enabled dependsOnTime... 2014-05-02 17:50:04 +02:00
1cdc116566 fixed the halving again 2014-05-02 16:18:47 +02:00
3453390bad deactivate plain voronoi fracture 2014-05-02 15:16:30 +02:00
ed2c7c7322 crash fix, return null if visible mesh is null 2014-05-02 14:23:52 +02:00
cffb510e65 some constraint change crash fixes 2014-05-02 13:46:09 +02:00
caf9d082cd some memory leak hunting, but some are still there 2014-05-02 11:22:33 +02:00
d7bbdab2f4 removed "fracture level" stuff, did not work properly under windows... 2014-05-02 10:37:23 +02:00
0da7bcb78c fix for warning; unnecessary semicolon... 2014-05-01 19:45:00 +02:00
13b97bbc0b crash fix attempt for loading fractured blends 2014-05-01 19:15:40 +02:00
82ff09ef1a attempt for saving / loading and texture preservation 2014-05-01 17:45:30 +02:00
0f80a3faaf split the processing loops to an openmp one and an openmp free, due to crappy windows compiler error 2014-04-30 23:59:41 +02:00
94c50f1277 removed additional customdata markings, added openmp again (first was not working with textures) 2014-04-30 16:10:05 +02:00
2decc0c647 doubled the shard count internally for fast bisect so input count and output count match 2014-04-30 14:04:57 +02:00
3f8806d394 using malloc instead of calloc for bisect fracture 2014-04-30 12:38:01 +02:00
3e26dfc02e nullify noisemap, for now to prevent crash on loaded file, modifier free 2014-04-30 11:32:25 +02:00
e3adc6e820 changed qsort to BLI_qsort_r 2014-04-30 00:32:50 +02:00
90e500c918 added a fast but inaccurate bisection method 2014-04-29 22:03:34 +02:00
5697d6f26d attempt to speedup bisect, but cant use OpenMP now, so a bit slower... but less cpu load... 2014-04-29 12:46:47 +02:00
f5e17e1f59 extended the critical section, hopefully this stabilizes it a bit 2014-04-27 16:45:16 +02:00
9877852266 tried to increase speed by openmp, but crashes more often now, especially when freeing things (double free...) hrm 2014-04-27 14:59:00 +02:00
fb2198dfe3 some cleanup ... 2014-04-26 23:30:21 +02:00
c2382339d2 all "optimizations" made it actually slower, so using full copy now... 2014-04-26 23:21:00 +02:00
26d7665c09 hrm bisect does not get faster... 2014-04-26 22:13:07 +02:00
4ab0f421a7 attempt to accelerate bisect fracture, but no real success... 2014-04-26 18:26:12 +02:00
8d20bf15c5 mac does not support memorystreams (fmemopen and open_memorystream) as well... using regular file there too 2014-04-24 11:12:39 +02:00
f487116c32 was merged incorrectly as well... 2014-04-24 09:52:39 +02:00
5208108373 those were merged incorrectly from and older branch, error was visible in windows. (crashes) 2014-04-24 01:16:07 +02:00
cef5642825 removed incorrect include stdbool.h 2014-04-24 00:53:56 +02:00
3f87907478 argh, Windows did not support memorystreams, so had to add regular file as fallback 2014-04-23 23:43:59 +02:00
9f34788ad6 memory leak hunting, there is still one unfixable related to customdata behavior (need to alloc twice there somehow, grr...) 2014-04-23 14:51:04 +02:00
9831a6b3e2 attempt to store fracture result and read it, failed, so deactivated for now 2014-04-22 20:21:16 +02:00
74d486b56e fix for crash at removing modifier 2014-04-22 17:46:00 +02:00
2c77a4da8c fix : dont create meshislands for empty shards, causes trouble with rigidbody sim 2014-04-22 17:36:11 +02:00
b34d1f8f8b rigidbody should work without fracture now too 2014-04-22 15:10:12 +02:00
6eb641b93a some more crash fixes 2014-04-22 11:47:17 +02:00
4777e74694 some fixes and a bit performance optimization 2014-04-22 02:17:42 +02:00
2b718bda3f small crash fix in case fracturing goes wrong (sometimes 0 shards...) 2014-04-21 22:58:41 +02:00
6d27993ad8 removed temporary material coloring of clusters and added support for uvs (boolean) 2014-04-21 22:41:44 +02:00
90d22621f5 fix for saving and loading 2014-04-21 13:55:44 +02:00
fe9c308bb1 sim should work again now 2014-04-21 00:46:50 +02:00
22dea61d55 hopefully simulation fixes... 2014-04-20 18:28:18 +02:00
0aa4f1d594 compile fixes... 2014-04-20 15:37:48 +02:00
462f1436c3 Merge branch 'refs/heads/rigid_fracture' into fracture_modifier_oldsim
Conflicts:
	extern/CMakeLists.txt
	extern/voro++/CMakeLists.txt
	extern/voro++/src/Doxyfile
	extern/voro++/src/c_interface.cc
	extern/voro++/src/c_interface.hh
	extern/voro++/src/c_loops.hh
	extern/voro++/src/container.cc
	extern/voro++/src/container.hh
	extern/voro++/src/container_prd.hh
	extern/voro++/src/wall.cc
	extern/voro++/src/worklist_gen.pl
	intern/rigidbody/RBI_api.h
	release/scripts/startup/bl_ui/properties_physics_softbody.py
	source/blender/blenkernel/BKE_rigidbody.h
	source/blender/blenkernel/intern/curve.c
	source/blender/blenkernel/intern/gpencil.c
	source/blender/blenkernel/intern/mask.c
	source/blender/blenkernel/intern/node.c
	source/blender/blenkernel/intern/object.c
	source/blender/blenkernel/intern/pointcache.c
	source/blender/blenkernel/intern/rigidbody.c
	source/blender/blenloader/CMakeLists.txt
	source/blender/blenloader/intern/readfile.c
	source/blender/blenloader/intern/writefile.c
	source/blender/editors/animation/anim_markers.c
	source/blender/editors/animation/keyframing.c
	source/blender/editors/armature/armature_edit.c
	source/blender/editors/curve/editcurve.c
	source/blender/editors/include/UI_view2d.h
	source/blender/editors/interface/interface_handlers.c
	source/blender/editors/interface/interface_templates.c
	source/blender/editors/interface/view2d_ops.c
	source/blender/editors/mask/mask_ops.c
	source/blender/editors/mask/mask_select.c
	source/blender/editors/object/object_edit.c
	source/blender/editors/object/object_modifier.c
	source/blender/editors/physics/physics_fracture.c
	source/blender/editors/physics/physics_intern.h
	source/blender/editors/screen/area.c
	source/blender/editors/sculpt_paint/paint_hide.c
	source/blender/editors/space_action/action_edit.c
	source/blender/editors/space_clip/tracking_ops.c
	source/blender/editors/space_graph/graph_edit.c
	source/blender/editors/space_sequencer/sequencer_edit.c
	source/blender/editors/space_sequencer/sequencer_select.c
	source/blender/editors/uvedit/uvedit_ops.c
	source/blender/makesdna/DNA_modifier_types.h
	source/blender/makesdna/DNA_rigidbody_types.h
	source/blender/makesdna/intern/makesdna.c
	source/blender/makesrna/intern/rna_modifier.c
	source/blender/modifiers/CMakeLists.txt
	source/blender/modifiers/MOD_modifiertypes.h
	source/blender/modifiers/intern/MOD_explode.c
	source/blender/modifiers/intern/MOD_util.c
	source/blender/windowmanager/intern/wm_event_system.c
	source/blenderplayer/CMakeLists.txt
2014-04-20 14:43:14 +02:00
1972f7bd01 clustering for fracture 2014-04-20 12:41:40 +02:00
7bb6bf21d2 added point sources and seed 2014-04-17 12:13:19 +02:00
f49ddd310d bisect fix, geometry disappeared before 2014-04-16 13:25:56 +02:00
35e4e8a4fd missing brace caused compile errors... 2014-04-16 12:18:52 +02:00
15f50655e8 fixing compile.... 2014-04-16 11:20:05 +02:00
a04214d107 Merge remote-tracking branch 'refs/remotes/origin/master' into fracture_modifier
Conflicts:
	extern/carve/carve-capi.cc
	extern/carve/carve-capi.h
	extern/carve/carve-util.cc
	extern/carve/carve-util.h
	extern/carve/patches/series
	intern/bsp/intern/BSP_CSGException.h
	release/datafiles/locale
	source/blender/blenkernel/BKE_mesh.h
	source/blender/editors/space_view3d/view3d_select.c
	source/blender/makesrna/intern/rna_fracture.c
	source/blender/modifiers/intern/MOD_boolean_util.c
	source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLLight.h
2014-04-16 11:05:38 +02:00
cc8bb235b9 pick attempts, fail 2014-04-16 10:32:24 +02:00
82285878f4 stuck / failing attempt for picking shards :( 2014-02-09 13:53:36 +01:00
de70b4e317 added (empty) fracture edit mode 2014-02-09 12:40:50 +01:00
e15f781ffd integrated latest crash fix (empty mesh at union operands) from sergey 2014-02-07 10:56:05 +01:00
413a80f966 small typo fix from sergeys patch 2014-02-06 11:06:34 +01:00
af818d32b3 Better handling of flipped face normals coming from voro++.
Instead of flipping the normals on the derived mesh, produce the face
loops in the correct order for shards.
2014-02-05 19:27:58 +01:00
5b4caa03ac Allow the fracture modifier to apply in editmode. 2014-02-05 18:51:48 +01:00
0daab1ef32 Fix for last terminator in voro++ output: this is just a single char. 2014-02-05 18:09:58 +01:00
310514c14e Simplified neighbor parsing from voro++ output.
Number of neighbors is exactly the same as number of faces - each face
has one neighbor. Moved this into the face section of voro++ output too,
since it's essentially face data.
2014-02-05 17:57:52 +01:00
d20aec59bd Fix for voro++ output parsing.
Use available print options from voro++ to get number of verts and loops
in advance, to avoid realloc. Also fixed bad mesh results with missing
vertices.
2014-02-05 17:16:59 +01:00
a3b452d752 Removed old dummy code for fracture. 2014-02-05 16:00:05 +01:00
9ca13f6e0e Added fracture_util.h to keep internal utility function declarations
out of the actual blenkernel header.
2014-02-05 15:02:29 +01:00
2befce02af a bit reduction of allocs, but still needed for loops (cant determine loop count fast / reliable for now in advance) 2014-02-04 20:37:01 +01:00
cbe0972d99 fix attempt for boolean 2014-02-04 13:54:17 +01:00
063d438054 Use a memstream again instead of a temporary file. But to avoid crappy
performance when directly parsing the stream, use a read-only string
stream afterward to do the actual parsing on the resulting char buffer.
2014-02-04 09:07:26 +01:00
bf59c1bc66 Use void argument to avoid compiler warning. 2014-02-04 08:54:12 +01:00
40fb7592f9 Applied diffs 837 and 838 from D274. 2014-02-03 13:25:42 +01:00
165bfecbc1 Merge branch 'master' into fracture 2014-02-03 12:39:30 +01:00
e66d3e5d0c Merge branch 'arcpatch-D274' into fracture
Conflicts:
	extern/carve/carve-util.h
	intern/bsp/extern/CSG_BooleanOps.h
	intern/bsp/intern/BOP_CarveInterface.cpp
2014-02-03 11:56:42 +01:00
9675ba189f Merge branch 'master' into fracture
The previous master merge was squashed, this has been reverted to avoid
unnecessary conflicts.

Conflicts:
	extern/carve/patches/series
2014-02-03 11:39:03 +01:00
4aeb8ea28f Revert "Merge remote-tracking branch 'refs/remotes/origin/master' into boolean_fracture"
This reverts commit ecc10dbe29.
2014-02-03 11:37:38 +01:00
15bb397fbb Rework carve integration into boolean modifier
Goal of this commit is to support NGons for boolean modifier
(currently mesh is being tessellated before performing boolean
operation) and also solve the limitation of loosing edge custom
data layers after boolean operation is performed.

Main idea is to make it so boolean modifier uses Carve library
directly via it's C-API, avoiding BSP intermediate level which
was doubling amount of memory needed for the operation and which
also used quite reasonable amount of overhead time.

Reviewers: lukastoenne, campbellbarton

CC: scorpion81, karja, jsm

Differential Revision: https://developer.blender.org/D274
2014-02-03 10:50:01 +01:00
c7a3a79da1 new boolean patch by sergey and small fracture bisect fix (need unity_m4 obmat instead of ob->obmat) 2014-02-02 20:30:03 +01:00
ecc10dbe29 Merge remote-tracking branch 'refs/remotes/origin/master' into boolean_fracture
Conflicts:
	extern/carve/patches/series
2014-02-01 15:53:38 +01:00
56beb2effe testing new boolean patch, CRASH ! in intersect.cpp, line 438 from carve 2014-02-01 15:24:29 +01:00
c2edd4cf8c memory leaks fixed 2014-02-01 13:11:52 +01:00
fe93f08d57 made fill optional with bisect 2014-01-31 23:31:56 +01:00
94c111072b tested different bisect fill algorithms; triangle fill on triangulated input turns out to be best 2014-01-31 22:12:58 +01:00
ae25dc66df changed memorystream back to real file, what a performance boost ! 2014-01-31 19:33:00 +01:00
0de34dcda1 added shard count / shard id to gui, tested performance, its very lousy compared to my earlier modifiers 2014-01-31 18:10:24 +01:00
cd6a1f503a made fracture algorithm selectable 2014-01-31 12:50:55 +01:00
87f2b86cd8 added bisect as second fracture algorithm 2014-01-31 12:23:25 +01:00
bffce8c727 tiny fix, boolean works without flipping the loops as well (except suzanne) 2014-01-31 10:08:38 +01:00
c20718e9d5 boolean fracture works ! (atleast partially, suzanne produces still errors) 2014-01-30 22:36:28 +01:00
5f8997a7a4 still a "negative" result, somewhere the normals need to be flipped, but how ?? 2014-01-30 21:03:11 +01:00
98e0ec4850 Merge branch 'refs/heads/boolean_fracture' into fracture
Conflicts:
	intern/bsp/extern/CSG_BooleanOps.h
	intern/bsp/intern/BOP_CarveInterface.cpp
2014-01-30 19:08:35 +01:00
2993b02b8e some fix attempts for flipping the face orientation, fail... 2014-01-26 23:56:30 +01:00
653a951ea3 first attempt of direct communication between blender<->carve layer and fracmesh, fail because normals are inverted.... 2014-01-26 22:53:32 +01:00
b257850ce2 saving fracture to blend and loading from it 2014-01-26 13:48:05 +01:00
de2e6a7004 Removed the vertco member in Shard, this was previously used for
simulation but is not needed any longer.
2014-01-26 12:05:15 +01:00
98ae9b083b Extended the BKE_create_fracture_shard funktion with a 'copy' argument,
so we can pass over arrays without having to do double alloc.
2014-01-26 11:58:09 +01:00
dd278f6a50 some memory leaks fixed, but some left, and attempt for writefile 2014-01-26 11:50:29 +01:00
57f8d0721f parsing and createdm makes valid mesh now 2014-01-26 11:13:26 +01:00
d1393032a2 parsing of voro++ data should work now, but a crappy mesh appears, hmm 2014-01-26 01:42:17 +01:00
7ff93f27ea attempt to parse voro++ data from string, not working yet 2014-01-25 23:36:03 +01:00
ca0b5ca635 Fix for point cloud construction: Use a point struct to avoid difficult
float arrays.
Also added Frac prefixes to prevent potential name collisions.
2014-01-25 20:41:03 +01:00
64e9066f4f A few small fixes for the voro++ C API, which seem to have fixed a
freezing issue when building with clang.

Also min/max initialization for point cloud construction.
2014-01-25 20:29:13 +01:00
f91218cbdf cmake cleanup: removed the ++ suffix from VORO cmake variables and
defines.
2014-01-25 20:02:03 +01:00
a511e86ebf Stub code for voro++ integration.
Not functional yet, but needs testing for potential voro++ bug.
2014-01-25 19:26:05 +01:00
34c07eed51 Removed the ShardList return value of the fracture function.
This is not used atm and it's a bit ugly to return such allocated
values. If necessary this can be added back later.
2014-01-25 17:28:53 +01:00
f86d71b025 Updated the pseudo-fracture method to new Mesh types. 2014-01-25 16:29:58 +01:00
3c310d565a New method for constructing the DerivedMesh for the fracture modifier.
Uses a simple union of all the shard mesh data.
2014-01-25 15:52:31 +01:00
f5e624aaad Create the initial fracmesh geometry by copying the input DerivedMesh
as a single shard.
2014-01-25 15:23:31 +01:00
fa1ace9f2d Removed the BMesh reference from FracMesh.
With the new Mesh data types this will no longer be needed.
2014-01-25 15:03:08 +01:00
5c21d96e5c Use plain Mesh types (MVert, MPoly, MLoop) in shards instead of copying
BMesh element arrays.

This will make Shard work more like a mini-Mesh struct and allow storing
of mesh data in blend files.

Larger construction methods currently disabled, TODO.
2014-01-25 14:36:30 +01:00
77cfd4e2f8 Partial revert of previous commit: DerivedMesh should be released by
setting needsFree and then calling dm->release.
2014-01-25 13:43:55 +01:00
414352fced fixed majority of memory leaks (of fracture) 2014-01-25 13:24:06 +01:00
090016f9d1 Moved the render_mesh DerivedMesh from FracMesh into the
FractureModifierData.

This keeps the derived mesh inside the modifier system and is more
in line with common principles in other modifiers.

Also did lots of style cleanup.
2014-01-24 17:15:22 +01:00
7e50455b8d basic foundation for fracture modifier / operator laid; todo fix memoryleaks... 2014-01-18 22:01:24 +01:00
d832011b82 modifier initial setup 2014-01-18 15:23:54 +01:00
c0907a6aa7 initial commit for new fracture system 2014-01-18 10:30:57 +01:00
30467f8e5c Code cleanup: As Sergey stated on bf-committers one should use id_us_min() if the user counter has to be decremented and not decrement the counter by hand. 2013-11-25 21:54:58 +01:00
3f8bd4fe15 Correct fix for T37617, (own recent regression) 2013-11-25 21:37:07 +01:00
375b6f5a57 Fix T37617: "Add plane" was adding a 2*2 grid
Was a regression from rBaa3c06b41ca9, hope this time all things are OK again (note the X/Y subdivision values still are different than before (-1 for same result), but imho they make more sense this way).
2013-11-25 21:27:35 +01:00
3f661c6355 Code Cleanup: rename vars for detecting change to be more consistent
rename change/is_change/is_changed/modified -> changed
also use bools over int/short/char and once accidental float.
2013-11-25 21:27:35 +01:00
a3050d4b2d fix: marking edges as sharp in modifier did not work any more 2013-11-25 20:09:53 +01:00
f3007c42fc partial fix for fracturing meshes where origin is not in bounds center 2013-11-25 20:09:53 +01:00
c1ae472a10 some hacks to keep baked files with clipping working... 2013-11-25 20:09:53 +01:00
f6b0828870 hopefully fixed atleast the fracture with text converted to mesh/remeshed and objects whose origin is not at bounds center 2013-11-25 20:09:53 +01:00
81fb6d5261 changed (i think corrected) the centroid calculation for fractured objects with boolean 2013-11-25 20:09:53 +01:00
b7a772f567 fixing crash at refreshing fractured text, cause was improper handling of the necessary temp object for boolean function (yuck) 2013-11-25 20:09:53 +01:00
d612fd67b4 attempt to make text and curves work with rigidbody modifiers too, still failing (flying apart... crashes...) 2013-11-25 20:09:53 +01:00
8d25904e52 fix for autorefresh and depgraph callback, strangely did only work for the testblend and not for others... 2013-11-25 20:09:53 +01:00
fb6afeedce using direct function for dissolve in object conversion too 2013-11-25 20:09:53 +01:00
d58cbd01dd using dissolve function now directly to circumvent (hopefully) the va_arg problems under windows 2013-11-25 20:09:53 +01:00
29766b78c3 cosmetical update in gui 2013-11-25 20:09:53 +01:00
f35868f1b3 fix for use_animation and no autorefresh, mesh was reset to initial state always... 2013-11-25 20:09:52 +01:00
75bd4dabbe making ngons in boolean case now too 2013-11-25 20:09:52 +01:00
a926f7afe7 attempt to fix strange misbehavior of va_list / va_arg under windows by passing it as pointer to BM_op_vinitf instead of as value 2013-11-25 20:09:52 +01:00
7e0258de36 using bool variables (true, false) instead of int TRUE/FALSE now 2013-11-25 20:09:52 +01:00
0a62a7f52d making real ngons in convert to object as well now 2013-11-25 20:09:52 +01:00
e62419008f added depgraph callback for autorefresh 2013-11-25 20:09:52 +01:00
0bd32da174 crash fix and graphical error fix when rigidbody modifier is used with autorefresh, for now must disable autorefresh manually to make sim work again 2013-11-25 20:09:52 +01:00
91d018bb76 added autorefresh for explode modifier and particle selection mask (still crashing with rigidbody modifier attached, hmm) 2013-11-25 20:09:52 +01:00
ac6b1d923d added solver iterations override and proportional solver iterations options 2013-11-25 20:09:52 +01:00
80f71bf21c dont convert unnecessarily in clipping mode as well 2013-11-25 20:09:52 +01:00
f718c1cdbe fixes for making explode "applyable" again, did not work anymore 2013-11-25 20:09:52 +01:00
6b7ab62c94 increased cache playback speed by atleast 10fps (from 14 to 24 in a 5000 shard testcube) by eliminating unnecessary bmesh conversions in explode modifier 2013-11-25 20:09:52 +01:00
70e1988a1c some attempt to reduce memory usage, but no luck, hrm. 2013-11-25 20:09:52 +01:00
d76ead8e13 fix for null-pointer crash when attempting to create a cached derivedmesh from nonexistent bmesh 2013-11-25 20:09:52 +01:00
ab4ddd008f free vertices_cached if present before re-allocating -> prevent memory leak 2013-11-25 20:09:52 +01:00
3be53ebfde init explode modifier right after addition 2013-11-25 20:09:51 +01:00
1291b54616 changed visible mesh to derivedmesh, some performance gain, but still need to copy it in modifier 2013-11-25 20:09:51 +01:00
1de7452ba5 made parenting to empty default, it also cleans up the outliner a bit, so removed the 2nd operator button and the operator property again, was confusing 2013-11-25 20:09:51 +01:00
6f6bf095d6 added "convenience" support for blender destructability editor -> convert with parenting, usable together with addon in "Loose Parts" mode 2013-11-25 20:09:51 +01:00
a584f90abc crash fix for bake to keyframes 2013-11-25 20:09:51 +01:00
b95df881af partial crash fix for outer constraints, convert to objects takes mass / dist dependent thresholds into account now 2013-11-25 20:09:51 +01:00
353892bb14 better refresh manually after duplicating objects with modifiers 2013-11-25 20:09:51 +01:00
728db50b65 some (failing) attempts to fix boolean intersection (often has "inverted" results) 2013-11-25 20:09:51 +01:00
a4f7e80d76 remove gitignore files from commits 2013-11-25 20:09:51 +01:00
9c9e8808c2 making ngons and marking edges as sharp for object convert operator 2013-11-25 20:09:51 +01:00
29d8e09c4c another attempt to fix baking, doesnt show negative side effects up to now 2013-11-25 20:09:51 +01:00
7d320da003 fix for baking regular rigidbodies, (hopefully) 2013-11-25 20:09:51 +01:00
48e8faeac9 hide the constraint empties after bake to keyframes, make sure you select the constraints as well prior to bake to keyframes or blender crashes afterwards (because of stray constraints not being removed properly) 2013-11-25 20:09:51 +01:00
5d4538ab29 fix for converting classic explode modifier to objects, objects had holes 2013-11-25 20:09:51 +01:00
169033992d compile fixes due to merge 2013-11-25 20:09:51 +01:00
24cf767e15 convert to objects takes textures into account now and makes ngons 2013-11-25 20:09:50 +01:00
b2459b805c crash fix for bake to keyframes and crash at quitting blender 2013-11-25 20:09:50 +01:00
a2d10e9848 throw away whole Rigidbodyworld and recreate when converting to objects to circumvent crashes 2013-11-25 20:09:50 +01:00
c2b0603e7a attempt for selecting the shards, doesnt work for some reason... hmm 2013-11-25 20:09:50 +01:00
69db68e8eb added experimental "convert to objects" operator, doesnt take textures into account yet 2013-11-25 20:09:50 +01:00
94a039ac52 fixed a memory leak; framemap was not deleted in some cases 2013-11-25 20:09:50 +01:00
e631dbb9af crash fix for using baked data with compounds 2013-11-25 20:09:50 +01:00
030423e7e2 mark edges from faces with inner material as sharp (for usage with smooth shading and edgesplit modifier to hide the fracture cracks) 2013-11-25 20:09:50 +01:00
11d23a9f61 silently ignore refresh requests when not on startframe now, otherwise internally (bullet userpointers) get freed but not nulled which can lead to crashes 2013-11-25 20:09:50 +01:00
99e70a6faf fix: clusters did not work with booleans 2013-11-25 20:09:50 +01:00
3c1701d498 activate collision between intact/destroyed compounds when compound shape is chosen 2013-11-25 20:09:50 +01:00
869ad992de use normal breaking threshold with cluster size 1 (means no clustering at all) 2013-11-25 20:09:50 +01:00
e90872ca24 fix (attempt) for cluster refreshing, clusters fall apart without this unexpectedly 2013-11-25 20:09:50 +01:00
6886a42d7f added cluster size and cluster percentage in explode modifier, and a new inner-cluster threshold in rigidbody modifier, removed map delay and emit continously options (they were misleading) 2013-11-25 20:09:49 +01:00
0f21491fa2 apply clustering with "Map Delay" to rigidbody modifier as well, by comparing particle indexes, need still a threshold value entry for "inside" the clusters 2013-11-25 20:09:49 +01:00
298b8a25e9 compile fix 2013-11-25 20:09:49 +01:00
3a838c01f6 crash fix for compound shape and making particle animation work again 2013-11-25 20:09:49 +01:00
506edfefb9 modifiers need to say whether they depend on normals, update due to changes in solidify modifier and normal calculation 2013-11-25 20:09:49 +01:00
90892008bd crash fix for compound shape 2013-11-25 20:09:49 +01:00
c262e138e6 crash fix when moving object interactively and only one object is in list (did not fall) 2013-11-25 20:09:49 +01:00
90b777c18a crash fix after merge, NULL seems to be invalid here now 2013-11-25 20:09:49 +01:00
4d60d54fa8 compile fixes 2013-11-25 20:09:49 +01:00
ce044b6740 crash fix (hopefully) for NULL cache_offset_map 2013-11-25 20:09:49 +01:00
776da90407 recenter fix (again) car roof was clipped away and refresh logic fix, hopefully 2013-11-25 20:09:49 +01:00
2857a137f5 crash fix for uninitialized modifiers 2013-11-25 20:09:49 +01:00
070162b490 make compounds of different objects collide with each other 2013-11-25 20:09:49 +01:00
85351b8bd8 fix for unwanted rigidbody settings reset (with modifiers) when simulation is recalculated 2013-11-25 20:09:49 +01:00
5eb9a24efa do not construct modifiers automatically after loading, can cause crashes in case of important related objects not loaded yet, but need to refresh manually each time after loading 2013-11-25 20:09:49 +01:00
c99f531ae9 object recenter fix, need to refresh to correct wrong translation of object in case of changing the origin 2013-11-25 20:09:48 +01:00
31eabfc221 copying rigidbody objects before modifiers now, in case of rigidbody modifiers changes should be taken into account 2013-11-25 20:09:48 +01:00
afdd86826e fixes for crash after loading file with classic explode and rigidbody and fix for memory leak 2013-11-25 20:09:48 +01:00
b208c6730d using classical explode retains its shapes in rigidbody modfier, only centroids seem not completely correct yet 2013-11-25 20:09:48 +01:00
3a3fa959b9 fix attempt for corrupt Memory blocks with cache_index_map / cache_offset_map 2013-11-25 20:09:48 +01:00
79934f6bdc refresh on modifiers works over a whole selection now 2013-11-25 20:09:48 +01:00
b7aed3b37f crash fix for duplicating objects with explo and rigidbody modifier 2013-11-25 20:09:48 +01:00
b91192d454 long faces support, part 2, still have double faces 2013-11-25 20:09:48 +01:00
ddac6fbea1 hmm, there is a bug in MOD_rigidbody.c but fixing it causes worse behavior, so keeping it for now 2013-11-25 20:09:48 +01:00
f5f1515fe9 first step of adding "long face" support 2013-11-25 20:09:48 +01:00
947653bbf3 added option to enable/disable self collision of constrained objects, does not affect compounds yet (led to strange results there) 2013-11-25 20:09:48 +01:00
fa1ac8c040 keep using neighborhood info with VERTS target if explomodifier is available, need this for correct wood bar, compounds wont really work with scaled objects yet. 2013-11-25 20:09:48 +01:00
4af38f7067 dont use neighborhood info for boolean any more, use bounds center for convex hull compounds without constraints 2013-11-25 20:09:48 +01:00
0854457667 some fix for scaled objects, cell grid was not aligned with object 2013-11-25 20:09:48 +01:00
ecc278fe46 further attempt to get scaling with compounds correctly working, still no luck, hrm. 2013-11-25 20:09:47 +01:00
17c81aac12 partial fix for using compounds on scaled objects, but not solved fully yet 2013-11-25 20:09:47 +01:00
87d693e112 fix for non-compound case, was not working with baking anymore 2013-11-25 20:09:47 +01:00
ed619166da small fix against possible corrupt end block (reallocating NULL pointer) 2013-11-25 20:09:47 +01:00
e3ff45781c baking with compounds should work now, finally... 2013-11-25 20:09:47 +01:00
007e2507c3 baking almost fixed... 2013-11-25 20:09:47 +01:00
da2014727e little progress only, breaking in baked mode, but some rigidbodies or so still missing 2013-11-25 20:09:47 +01:00
8cc646b531 stupid baking does not work after save and load yet... means compounds wont disintegrate visually, hrm. 2013-11-25 20:09:47 +01:00
53db50a9b4 damn baking errors, not fully solved yet... 2013-11-25 20:09:47 +01:00
4bb76122d2 missing some properties to copy 2013-11-25 20:09:47 +01:00
4977e05c53 not using old cell neighborhood anymore in case of compound usage 2013-11-25 20:09:47 +01:00
3563f48435 bmesh asserts do not occur anymore, yay ! 2013-11-25 20:09:47 +01:00
77e8608d73 small fix: use_experimental did invalidate cache, which is nonsense in this case 2013-11-25 20:09:47 +01:00
d3736eefd6 fix for explo and rigidbody modifier combination: simple fractured cube did not fall any more 2013-11-25 20:09:47 +01:00
3c89a23c2b crash fix for missing particlesystem and changes being made to explo modifier while rigidbodymodifier is enabled too 2013-11-25 20:09:47 +01:00
a1b1750253 partial fix for bmesh asserts, still got a lot of them, need to investigate further 2013-11-25 20:09:46 +01:00
06a30364b8 rigidbody modifier gui cleanup 2013-11-25 20:09:46 +01:00
61977f80cb fix for windows crash, tried to write at freed location, gcc must have "optimized" that out 2013-11-25 20:09:46 +01:00
04cdf953dd small hack for reducing clipping time and hopefully a fix for windows crashes... 2013-11-25 20:09:46 +01:00
b08b930a8b accelerated clipping by 50 % total, and it does increase less then linear for more cells now 2013-11-25 20:09:46 +01:00
ba1c830df1 auto-recenter should work now 2013-11-25 20:09:46 +01:00
c960f7eb89 accelerated clipping by approximately 30%(in a smaller testfile), not so much but its noticeable 2013-11-25 20:09:46 +01:00
4e8c7adeb3 windows crash fix (hopefully) for removing cells (was a warning in linux only) 2013-11-25 20:09:46 +01:00
94b265a2e2 increased voronoi container size, sometimes it is too small (when bbox is too small!!) 2013-11-25 20:09:46 +01:00
9bbfc0623e attempt for acceleration of clipping, failed due to incorrectness (holes appear), and was not so much faster at all 2013-11-25 20:09:46 +01:00
df92812fdc hole problem solved by 98 % or so, only 2 wrong triangles at whole car !! 2013-11-25 20:09:46 +01:00
4c21dd4e6f hole problem seems to be solved, need more tests still 2013-11-25 20:09:46 +01:00
8cafbff1c2 creating hole filling shapes separately from mesh 2013-11-25 20:09:46 +01:00
e0eaff4a78 successful test with clipping and car 2013-11-25 20:09:46 +01:00
2e377fb40d hole problem almost solved, need to deal with a special case still (wrong vert selected..) 2013-11-25 20:09:46 +01:00
cbb385043a clipping works mostly, mesh has some leftover holes, hmm 2013-11-25 20:09:45 +01:00
d9d6d13f39 first steps towards mesh clipping 2013-11-25 20:09:45 +01:00
4f41011f66 fix for compound creation, was throwing unnecessary error there 2013-11-25 20:09:45 +01:00
2901a846ee fix for wrong compound rotation 2013-11-25 20:09:45 +01:00
b79c97163d fix for crash while changing contact dist, changing back collision condition 2013-11-25 20:09:45 +01:00
a42e2efb3b improved refresh logic, can do updates with rigidbody constraint refresh mostly, which is called automatically on value changes as well 2013-11-25 20:09:45 +01:00
eade7e9baa small collision tweak for compounds (no implosions) 2013-11-25 20:09:45 +01:00
0e0cc39079 added compound shapes and disabled collision between compound/compound and compound/shard, reduces the "explosions" 2013-11-25 20:09:45 +01:00
3babd5a0f0 windows NAN fix, better do this elsewhere... 2013-11-25 20:09:45 +01:00
05c4b50d1d cache should work now mostly, but still need full refresh to do it properly, hmm, maybe reset the frame data... 2013-11-25 20:09:45 +01:00
c54e7bfd54 compound sim need still refresh constraints, cache works only partially because compound parents disappear from simulation (better deactivate them only or so) 2013-11-25 20:09:45 +01:00
b996b71df2 compound needs some work still, but becomes usable step by step 2013-11-25 20:09:45 +01:00
d6d0931d91 still working on proper compound / constraint cooperation 2013-11-25 20:09:44 +01:00
085975ad4a compound basic principle working, but very uncomfortable to control still, needs to be rebuilt once broken correctly 2013-11-25 20:09:44 +01:00
a6d3d775b0 first attempt for cell based simulation, not very good yet, needs improvement 2013-11-25 20:09:44 +01:00
019d927188 fix for last commit, still accelerating but correctly now 2013-11-25 20:09:44 +01:00
068ee02ed8 accelerated the check for existing constraints 2013-11-25 20:09:44 +01:00
13d5400054 added separate constraint update operator (only updating constraints) for quicker workflow 2013-11-25 20:09:44 +01:00
be39771bc7 opticall separation of values which need refresh and which dont 2013-11-25 20:09:44 +01:00
53515ddec4 changes for cell calculation, but this mode does not really work, still (just in for testing purposes) 2013-11-25 20:09:44 +01:00
7cc1fe1f45 added cell/centroid based approach again, delivers only the most necessary constraints in good time 2013-11-25 20:09:44 +01:00
c57a476494 added new cellbased search, performance not so ok... 2013-11-25 20:09:44 +01:00
0137ee3038 calculation fix for cell/meshisland assignment 2013-11-25 20:09:44 +01:00
801ab516c0 attempt for cellbased search, but loss of performance instead of gain, hrm. 2013-11-25 20:09:44 +01:00
4cbc15449f breking threshold 0 means undestructible now 2013-11-25 20:09:44 +01:00
11132108b9 added time printouts in seconds 2013-11-25 20:09:44 +01:00
72a46c10c0 fix for 0 limit and prop checked, was creating 0 constraints instead of "all" 2013-11-25 20:09:44 +01:00
972a73b316 added proportional limit and proportional distance for reducing number of neighborhood lookups in dense areas with many small parts 2013-11-25 20:09:43 +01:00
6adf68d8b5 expose bullet activation state and use it to deactivate both constraint partners in case of one is deactivated (avoids objects jittering around) 2013-11-25 20:09:43 +01:00
b399d9ce6c reset cache on moving objects and reenable all constraints 2013-11-25 20:09:43 +01:00
da029a6d97 fix for: canceling transforms with rigidbody modifier, was not done properly before 2013-11-25 20:09:43 +01:00
787a49d4fc ensure updateability of noise (when it changes) 2013-11-25 20:09:43 +01:00
a29cf33e61 yes! baking fixed finally now, need to rebake once to include a noisemap, which will be applied instead of generating new noise 2013-11-25 20:09:43 +01:00
ec9d5a45a2 added 3 more breakup options: breaking percentage, breaking angle and breaking distance 2013-11-25 20:09:43 +01:00
d482007dfd fix mass and centroid calculation for 1 vertex objects 2013-11-25 20:09:43 +01:00
408f931dd9 fix for separation method, did not work correctly if an unsuccessful halve occurred 2013-11-25 20:09:43 +01:00
1eb3d85e13 fix for crash when deleting objects with modifier (and cache is valid) 2013-11-25 20:09:43 +01:00
a5363ff015 fix for crash at object deletion when cache is valid 2013-11-25 20:09:43 +01:00
7e7b4708f3 sim startup time with applied array modifiers (on 20x20x20 test cube) reduced, removed unnecessary bmesh conversions 2013-11-25 20:09:43 +01:00
aa11c52611 fixed baking (to earlier state, with old errors, but works again), added mass calculation again was omitted testwise (long sim startup time) 2013-11-25 20:09:43 +01:00
999441106f pointcache and crash fix 2013-11-25 20:09:43 +01:00
3ce0957f1b cache index lookup speedup, WARNING, buggy 2013-11-25 20:09:42 +01:00
d4b41cf4a6 now properly deleted objects in open scenes as well, there were remainders in depsgraph causing crashes after incomplete delete 2013-11-25 20:09:42 +01:00
3b18a17010 added threshold and solver iterations, but its all still crash prone (when exchanging objects after simulation, DAG_tag updates makes this visible, probably object is STILL not properly deleted... 2013-11-25 20:09:42 +01:00
8fdc3b10d5 rotation and scale was not taken into account, fixed that 2013-11-25 20:09:42 +01:00
26c2fd49f5 further attempts to restore recent functionality of modifiers 2013-11-25 20:09:42 +01:00
db8a69f076 fracture works sorta, but cleaning up own mess in new run not. Very hard to get rid of objects actually. 2013-11-25 20:09:42 +01:00
512598da0a first steps to make operators from modifiers 2013-11-25 20:09:42 +01:00
e467249f35 hrm, fix for volume calculation and mass setting 2013-11-25 20:09:42 +01:00
0af63c9859 add a test for 0 length in volume calculation and set a minimum mass for 0 mass active objects 2013-11-25 20:09:42 +01:00
7a7d7165d2 do not abort at 0 verts, its too early, potential constraints are skipped 2013-11-25 20:09:42 +01:00
1713964d69 abort with 0 shared verts 2013-11-25 20:09:42 +01:00
13644afe9a fix for vertexbased constraint lookup: bboxtest continues loop instead of breaking it, and atleast 1 vertex is enough now for a constraint 2013-11-25 20:09:42 +01:00
1c4106ada2 fix for crash with missing particle texture (and no fracture mesh available) 2013-11-25 20:09:42 +01:00
d9a39262c4 added old constraint code (vertex distances) again, maybe it turns out to be useful in some cases 2013-11-25 20:09:42 +01:00
6803ed3265 forgot to add function to header 2013-11-25 20:09:42 +01:00
1deafe9d6d added dist dependent Threshold, but does it really help ? 2013-11-25 20:09:41 +01:00
ab004e58ee fix for crash applying/deleting explo modifier with rigidbody modifier below 2013-11-25 20:09:41 +01:00
26edda3db4 changed physics mesh from bmesh to derived mesh, reduces memory usage 2013-11-25 20:09:41 +01:00
030ce80a73 changed select linked walker method from island to shell, works on non manifolds too 2013-11-25 20:09:41 +01:00
f09d82a541 some fix for bigger undividable islands 2013-11-25 20:09:41 +01:00
501785846d regular explode modifier and rigidbody should not crash anymore 2013-11-25 20:09:41 +01:00
c060f042dc another fix for missed unvisited seed vertices and check if island is dividable 2013-11-25 20:09:41 +01:00
4dd4479970 Halving approach fixed now, still very fast compared to before 2013-11-25 20:09:41 +01:00
51fad3521a Halving Approach successfully implemented, very fast and correct now 2013-11-25 20:09:41 +01:00
b4eb9fe87d first attempt of halving method, fast but still incorrect 2013-11-25 20:09:41 +01:00
b649feaf59 mainly performance optimization attempts and some cleanup 2013-11-25 20:09:41 +01:00
ed6726c9f3 automerge quick fix 2013-11-25 20:09:41 +01:00
6a35f695ef performance fix, if array and subsurf modifiers before rigidbody were in a certain sequence, performance was extremely bad due to incorrect mesh_separate_tagged function 2013-11-25 20:09:41 +01:00
76620e8d53 crash fix for cache_offset_map (needed to nullify) 2013-11-25 20:09:41 +01:00
460bfa85dd oddly, in rigidbody.c not everywhere MEM_ functions were used, fixed that due to odd crash 2013-11-25 20:09:40 +01:00
5090b47a03 fixes to allow other constraint types and (mostly) correct outer constraints again 2013-11-25 20:09:40 +01:00
37aa3b1d0c cache_offset_map, store offset instead of calculating, but only 1fps speed gain, hrm 2013-11-25 20:09:40 +01:00
1ba6e997f5 memory leaks fixed 2013-11-25 20:09:40 +01:00
4b71477299 automerge fix applied again (was not working any more) 2013-11-25 20:09:40 +01:00
eb1fce1cd1 attempt for fixing bake error, unfortunately no luck yet 2013-11-25 20:09:40 +01:00
dc388537ab some stabilization (refreshing modifiers crashed before) but still error with baked data and memory leak 2013-11-25 20:09:40 +01:00
3151004efe seems to run faster now, but still have a big memory leak 2013-11-25 20:09:40 +01:00
9875537458 further work at speedup, automerge needs to be tackled still 2013-11-25 20:09:40 +01:00
d52a57ee9d partial success with speedup attempt, but automerge still slow and wrong 2013-11-25 20:09:40 +01:00
36c17c46fe minor correctional fixes, enable automerge workaround again 2013-11-25 20:09:40 +01:00
edbe775ebe some attempts to increase performance, only a bit faster now 2013-11-25 20:09:40 +01:00
d03b5110bb first attempt to increase performance: disable storage of fracture results, this costs more performance instead improving it, and added a boundbox test for constraints calculation (but often those intersect each other, so not much performance gain, also need to fix for not touching islands which possibly should act as fixed too (using higher contact distance) 2013-11-25 20:09:40 +01:00
4335d31689 merge related compile fix 2013-11-25 20:09:39 +01:00
0ffa93618f correction: calculate only (many) fixed constraints faster, the other outer constraint types connect to 1 shard basically and work incorrectly if calculation stops at 0 shared vertices. 2013-11-25 20:09:39 +01:00
4cce73db0f small performance plus when building constraints, stop when 0 shared vertices occur (because meshislands are sorted by distance, kdtree) 2013-11-25 20:09:39 +01:00
665ae32809 adapt change from BMesh Operator "recalc face normals", removed some printouts 2013-11-25 20:09:39 +01:00
0d36d920aa merge related fixes 2013-11-25 20:09:39 +01:00
e69f1e80f5 can move constrained objects now during sim, will be autorefreshed next time, a bit more overall stability, but especially with constraint groups still bullet assertions possible when moving objects 2013-11-25 20:09:39 +01:00
c83727f844 some minor cleanup 2013-11-25 20:09:39 +01:00
71106384d7 a bit more stabilization for outer constraints, but cache shows still unexpected behavior 2013-11-25 20:09:39 +01:00
5787989733 disable auto-refresh in rigidbody modifier (can be very slow, but ... always remember to hit refresh before starting the sim now !) 2013-11-25 20:09:39 +01:00
ee239cce8f fix for scrubbing around in timeline while cache is not full yet -> did reshape too often (at saving, not at loading) accidentally 2013-11-25 20:09:39 +01:00
d6ae5785b7 a bit code cleanup 2013-11-25 20:09:39 +01:00
5f6659b35e re-introduce Group Contact Distance (has effect for fixed type only) fix for changing passive to active unexpectedly 2013-11-25 20:09:39 +01:00
bccb1971ab allow explode/voronoi modifer usage of previous modifier data 2013-11-25 20:09:39 +01:00
f77608aca2 fix for outer constraints, should work more reliably now 2013-11-25 20:09:39 +01:00
db73e4e4da closed some memory leaks 2013-11-25 20:09:39 +01:00
fe0dbf7ea2 crash fix for using customdata like e.g. textures, need manual refresh after load ! 2013-11-25 20:09:38 +01:00
36933e4bc2 compile fixes related to merge 2013-11-25 20:09:38 +01:00
6f8fa4182e fix for ownVertices, extraParticles (noise and coordinate correction) 2013-11-25 20:09:38 +01:00
ebf21db092 small fix for crash with outer constraints between more than 2 objects (after duplicating object with modifier) 2013-11-25 20:09:38 +01:00
a68f7159f9 added more constraint types for outer (and inner) constraints and outer constraint location (still subject to change) 2013-11-25 20:09:38 +01:00
5372591d0f additional test whether modifier is active (and not only there) when running rigidbody sim 2013-11-25 20:09:38 +01:00
60d80857d3 crash fix for selecting own verts on default cube 2013-11-25 20:09:38 +01:00
2ec4973d69 crash fix for constraint groups in conjunction with automerge 2013-11-25 20:09:38 +01:00
b76ab4e343 crash fix for loading files with constraint group enabled 2013-11-25 20:09:38 +01:00
a9f33f51d7 merge related compile fixes 2013-11-25 20:09:38 +01:00
9c20a46f5a small tweak for automerge 2013-11-25 20:09:38 +01:00
8f86353b88 storing vertco now, crash fix for adding new rigidbody modifier, attempt to fix glitch when simulation is interrupted and continued before cache is full (everything gets reset->why ?) 2013-11-25 20:09:38 +01:00
5e48a020d5 copying object with modifiers active should not crash anymore now 2013-11-25 20:09:38 +01:00
78a0670728 crash fixes for saving and loading, some tweaks for automerge 2013-11-25 20:09:38 +01:00
5242899aad added automerge distance, the whole automerge still needs tweaking, not reliable enough yet 2013-11-25 20:09:37 +01:00
093f437356 crash fixes for running sim / saving / undo after applying modifier 2013-11-25 20:09:37 +01:00
cba006d52e missed some null pointer checks 2013-11-25 20:09:37 +01:00
9ac7ac04ac 4th attempt, memory leaks eliminated 2013-11-25 20:09:37 +01:00
92928c0b00 3rd attempt, saving /loading working now, need to test still with customdata and undo 2013-11-25 20:09:37 +01:00
cd345412c8 second attempt for storing fracture result, its incorrect and slower than regenerating, so deactivated as well, but might be usable as reference later 2013-11-25 20:09:37 +01:00
add28fe4ce first attempt for storing fracture results, deactivated for now 2013-11-25 20:09:37 +01:00
7ce7f8a453 added null test for meshisland again, workaround when removing mesh islands and cache data is still there (would crash otherwise) 2013-11-25 20:09:37 +01:00
c8ad1ba65a added limited dissolve, crash fix when less constraints than expected 2013-11-25 20:09:37 +01:00
ba6e6a932d improved version of automerge, taking constraints into account 2013-11-25 20:09:37 +01:00
1f34dfef18 automerging inner geometry if object has not been hit, works for very low threshold only (settable via group contact property) and for now globally only, its possibly easier to fake an intact rigidbody with traceable settings or cycles nodes 2013-11-25 20:09:37 +01:00
3391e7a84c additional NULL check (but sometimes that area isnt NULL, just FREE, need still to investigate) 2013-11-25 20:09:37 +01:00
8711e3c6d8 allow modifier settings to be copied (when duplicating objects) 2013-11-25 20:09:37 +01:00
73f0b2d22d some code cleanup 2013-11-25 20:09:37 +01:00
3359d02d12 calling updateCell now in each case->evade corner case for one frame lag 2013-11-25 20:09:36 +01:00
964bdd434a catch possible NULL pointers 2013-11-25 20:09:36 +01:00
41fc551a86 fix for frame-lag when using kinematic fractured objects 2013-11-25 20:09:36 +01:00
46e81cf749 some code cleanup 2013-11-25 20:09:36 +01:00
0ce1f2b886 properly syncing shards now with RNA rigidbody settings of object, should allow correct animation now 2013-11-25 20:09:36 +01:00
194816da67 added (internally) a collision callback, allows partial activation of fractured deactivated objects 2013-11-25 20:09:36 +01:00
2ceb96f479 attempt for testing for group slave (deactivated in code) 2013-11-25 20:09:36 +01:00
02573fe35d -option for mass dependent threshold (constraint with max mass gets set threshold, the others are relative to that mass) -attempt for automating the refresh process (needs manual refreshes still now, even more) 2013-11-25 20:09:36 +01:00
7dcc5e692a some stabilization attempts for constraint groups, but still crashy and not intuitive enough 2013-11-25 20:09:36 +01:00
9212bd6832 compile fix (hopefully, at least here it works) 2013-11-25 20:09:36 +01:00
816e67e537 added group breaking threshold and group contact distance, now evalulating each modifiers settings in group constraints when overriding 2013-11-25 20:09:36 +01:00
91bba9bcbb added feature: Can connect multiple fractured rigidbody objects together automatically, fixed constraint for now only. To Use add another fractured object into constraint group of "parent" object (where others will be attached to) 2013-11-25 20:09:36 +01:00
31248db13c forgot to free some memory blocks 2013-11-25 20:09:36 +01:00
89aa38094c fixed wrong calculation and memory handling of point clouds, which led to often crashes. made explode a single modifier (removed copy), added outliner icon for rigidbody modifier 2013-11-25 20:09:35 +01:00
313adc270d fixing attempt for crash when using no pointsource and boolean intersection, change how noise is applied (memory access) 2013-11-25 20:09:35 +01:00
f2ec6d41ca added noise / percentage for pointsource, replaced child options by a group selection, made only one breaking threshold, removal of unused options, rename of Use Rigidbody, added refresh operator for explode voronoi mode (behavior still a bit inconsistent) 2013-11-25 20:09:35 +01:00
1a83942915 support smooth shards (if atleast one original object face is smooth), but looks bad still 2013-11-25 20:09:35 +01:00
c97f0437ad added some null checks, a bit cleanup 2013-11-25 20:09:35 +01:00
4a464602f9 calculating shard mass at creation/change, coordinate calculation fixes with own verts and greasepencil 2013-11-25 20:09:35 +01:00
433126d856 removing invalid faces in (very small area and less than 3 verts) in explode modifier (geometry fix) 2013-11-25 20:09:35 +01:00
8d89c7d8be small correction for constraints, atleast 3 shared vertices are needed to build a constraint fixes for incorrect meshes with radial point clouds step 1 (still non-manifold edges/faces) 2013-11-25 20:09:35 +01:00
083cc275fd ignore symlinks 2013-11-25 20:09:35 +01:00
c7d6fded16 child vertex wrong coordinate fix, but still problems with radial pointclouds (triangles miss, tessface fails ?) 2013-11-25 20:09:35 +01:00
fbe4d474ea make constraints optional, its very slow to set them up between many shards 2013-11-25 20:09:35 +01:00
ec8cacf7ae correction for cluster calculation 2013-11-25 20:09:35 +01:00
e9c1b187ce its possible to set inner and outer breaking threshold now for shard constraints 2013-11-25 20:09:35 +01:00
80c81856dd inner constraints work now basically, but need to have user interface to define strengths yet. 2013-11-25 20:09:34 +01:00
48663dd9df first steps with inner constraints, but moving the object when we have cached frames crashes bullet 2013-11-25 20:09:34 +01:00
d162008d5d small cleanup 2013-11-25 20:09:34 +01:00
3375afa3fe using polygons instead of tessfaces for voronoi cells now, but still faces miss 2013-11-25 20:09:34 +01:00
9439e57fc4 attempt for fixing missing faces problem (due to bm->dm->bm conversion ?) 2013-11-25 20:09:34 +01:00
80b6e52c09 fix for freeing NULL pointer, fix for visual errors with kinematic objects and interactive rotation and wrong mass calculation for shards 2013-11-25 20:09:34 +01:00
d635f222a1 correctly initializing ob->imat before using it, fixes bug where object was positioned at camera after render 2013-11-25 20:09:34 +01:00
29a64d71f2 scaling problem should be fixed now 2013-11-25 20:09:34 +01:00
d5e87fc445 fix for uneven scaling (mesh was distorted at collision before) 2013-11-25 20:09:34 +01:00
3d0795b044 attempt for getting scale properly to work, no success yet 2013-11-25 20:09:34 +01:00
4f47f0fc68 partial fix for scaling problem, but scaled fractured objects still lead to display errors, workaround: apply scale before fracture 2013-11-25 20:09:34 +01:00
4ad2bd8c0e fix for animation "jump" bug when rigidbody modifier is on animated object 2013-11-25 20:09:34 +01:00
ad7e1c124b attempt for fix for MeshIsland Null Pointer in Pointcache (index calculation fix) 2013-11-25 20:09:34 +01:00
ca216d9e7e crash fix when selected no point source, fix for using child vertices 2013-11-25 20:09:34 +01:00
1d195e6362 Fix NULL checks when dealing with pointcache
This needs to be cleaned up further but should be at least correct.
2013-11-25 20:09:34 +01:00
94eeeb9c4b Style and warning fixes 2013-11-25 20:09:33 +01:00
4ff02f7fc3 there should be only one rigidbody modifier per object, so it must not be copyable as well 2013-11-25 20:09:33 +01:00
862d098125 small fix, attempted to free some NULL pointers before. 2013-11-25 20:09:33 +01:00
055c5c91a7 ok, values are passed through now at once to shards at change (tested with kinematic) 2013-11-25 20:09:33 +01:00
2e1de279d3 first attempt to apply settings to each shard and calculate mass, maybe better move this into modifier/refresh ? 2013-11-25 20:09:33 +01:00
91eea4a3de fixed a rotation bug (each shard was rotated differently) and a small memory leak, although rotating objects during simulation (by hand) yields still an error (objects breaks apart at once) 2013-11-25 20:09:33 +01:00
54517891d8 fix for wrong pos calculation after moving objects 2013-11-25 20:09:33 +01:00
cd806601fb added refresh operator for rigidbody modifier to recalculate rigidbodies when mesh changes 2013-11-25 20:09:33 +01:00
3f2658bb99 calculating centers of mass now correctly for shards 2013-11-25 20:09:33 +01:00
d5aea12969 small fix for grabbing and moving objects during the sim 2013-11-25 20:09:33 +01:00
7b53f675bd this fix resets the simulation on esc properly 2013-11-25 20:09:33 +01:00
e39fc2c8ab added new rigidbody modifier doing the mesh island handling, instead of explode modifier 2013-11-25 20:09:33 +01:00
e81c5cec0a crash fix (wrong cache mapping) and white space cleanup (tabs only) 2013-11-25 20:09:33 +01:00
c593241cc7 fixes for: moving the object during rigidbody sim (no crash anymore) and one piece was always stuck in the air (wrong calculation in cache) 2013-11-25 20:09:32 +01:00
c8a4744ca5 some cache fixes to allow multiple (duplicated) rigidbodies with modifiers on them 2013-11-25 20:09:32 +01:00
e509a65885 added use rigidbody as new option, some smaller fixes 2013-11-25 20:09:32 +01:00
5516678889 can run simulation backwards now too (update mesh from cache, but still sometimes crashes) 2013-11-25 20:09:32 +01:00
1a77e9f316 very basic collision works, but unreliably for now (sometime cache crashes, center of mass still wrong 2013-11-25 20:09:32 +01:00
a89196af1b sorta optical feedback (but massively wrong) 2013-11-25 20:09:32 +01:00
776cd94b77 crash fixes, wip 2013-11-25 20:09:32 +01:00
c0ab26b8a7 attempts for integrating fractured objects into rigidbody sim, still wrong and incomplete 2013-11-25 20:09:32 +01:00
427783a3ac adapting rigidbody sim to accept mesh shards too (in progress) 2013-11-25 20:09:32 +01:00
0508f7be8d small build and link fixes 2013-11-25 20:09:32 +01:00
fbea1a566c update and merge code branches - voronoi modifier 2013-11-25 20:09:32 +01:00
e48616d08a test commit 2013-11-25 20:09:32 +01:00
277 changed files with 68782 additions and 1069 deletions

View File

@@ -234,12 +234,16 @@ option(WITH_BULLET "Enable Bullet (Physics Engine)" ON)
option(WITH_SYSTEM_BULLET "Use the systems bullet library (currently unsupported due to missing features in upstream!)" )
mark_as_advanced(WITH_SYSTEM_BULLET)
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLORIO})
option(WITH_VORO "Enable Voronoi Fracture based on Voro++" ON)
# Compositor
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" ${_init_OPENSUBDIV})
option(WITH_OPENSUBDIV_MODIFIER "Use OpenSubdiv for CPU side of Subsurf/Multires modifiers" OFF)
mark_as_advanced(WITH_OPENSUBDIV_MODIFIER)
option(WITH_OPENVDB "Enable features relying on OpenVDB" OFF)
option(WITH_OPENVDB_BLOSC "Enable blosc compression for OpenVDB, only enable if OpenVDB was built with blosc support" OFF)
option(WITH_OPENVDB_3_ABI_COMPATIBLE "Assume OpenVDB library has been compiled with version 3 ABI compatibility" OFF)
@@ -300,6 +304,7 @@ endif()
# Modifiers
option(WITH_MOD_FLUID "Enable Elbeem Modifier (Fluid Simulation)" ON)
option(WITH_MOD_SMOKE "Enable Smoke Modifier (Smoke Simulation)" ON)
option(WITH_MOD_BOOLEAN "Enable Boolean Modifier" ON)
option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
# option(WITH_MOD_CLOTH_ELTOPO "Enable Experimental cloth solver" OFF) # this is now only available in a branch
# mark_as_advanced(WITH_MOD_CLOTH_ELTOPO)
@@ -654,8 +659,9 @@ if(NOT WITH_BOOST)
set_and_warn(WITH_INTERNATIONAL OFF)
set_and_warn(WITH_OPENVDB OFF)
set_and_warn(WITH_OPENCOLORIO OFF)
set_and_warn(WITH_MOD_BOOLEAN OFF)
elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_INTERNATIONAL OR
WITH_OPENVDB OR WITH_OPENCOLORIO)
WITH_OPENVDB OR WITH_OPENCOLORIO OR WITH_MOD_BOOLEAN)
# Keep enabled
else()
# Disable boost if not needed.
@@ -1659,6 +1665,7 @@ if(FIRST_RUN)
info_cfg_option(WITH_CYCLES)
info_cfg_option(WITH_FREESTYLE)
info_cfg_option(WITH_OPENCOLORIO)
info_cfg_option(WITH_VORO)
info_cfg_option(WITH_OPENVDB)
info_cfg_option(WITH_ALEMBIC)
@@ -1710,6 +1717,7 @@ if(FIRST_RUN)
endif()
info_cfg_text("Modifiers:")
info_cfg_option(WITH_MOD_BOOLEAN)
info_cfg_option(WITH_MOD_REMESH)
info_cfg_option(WITH_MOD_FLUID)
info_cfg_option(WITH_MOD_OCEANSIM)

View File

@@ -31,6 +31,7 @@ set(WITH_INTERNATIONAL ON CACHE BOOL "" FORCE)
set(WITH_JACK ON CACHE BOOL "" FORCE)
set(WITH_LZMA ON CACHE BOOL "" FORCE)
set(WITH_LZO ON CACHE BOOL "" FORCE)
set(WITH_MOD_BOOLEAN ON CACHE BOOL "" FORCE)
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
set(WITH_MOD_REMESH ON CACHE BOOL "" FORCE)
set(WITH_MOD_SMOKE ON CACHE BOOL "" FORCE)

View File

@@ -0,0 +1,65 @@
# Turn everything ON that's expected for an official release builds.
#
# Example usage:
# cmake -C../blender/build_files/cmake/config/blender_full.cmake ../blender
#
set(WITH_ALEMBIC ON CACHE BOOL "" FORCE)
set(WITH_BUILDINFO ON CACHE BOOL "" FORCE)
set(WITH_BULLET ON CACHE BOOL "" FORCE)
set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
set(WITH_LIBMV ON CACHE BOOL "" FORCE)
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS ON CACHE BOOL "" FORCE)
set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
set(WITH_GHOST_XDND ON CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE)
set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE)
set(WITH_INTERNATIONAL ON CACHE BOOL "" FORCE)
set(WITH_JACK ON CACHE BOOL "" FORCE)
set(WITH_LZMA ON CACHE BOOL "" FORCE)
set(WITH_LZO ON CACHE BOOL "" FORCE)
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
set(WITH_MOD_REMESH ON CACHE BOOL "" FORCE)
set(WITH_MOD_SMOKE ON CACHE BOOL "" FORCE)
set(WITH_MOD_OCEANSIM ON CACHE BOOL "" FORCE)
set(WITH_AUDASPACE ON CACHE BOOL "" FORCE)
set(WITH_OPENAL ON CACHE BOOL "" FORCE)
set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE)
set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE)
set(WITH_OPENMP ON CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
set(WITH_RAYOPTIMIZATION ON CACHE BOOL "" FORCE)
set(WITH_SDL ON CACHE BOOL "" FORCE)
set(WITH_X11_XINPUT ON CACHE BOOL "" FORCE)
set(WITH_X11_XF86VMODE ON CACHE BOOL "" FORCE)
set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
# platform dependent options
if(UNIX AND NOT APPLE)
set(WITH_JACK ON CACHE BOOL "" FORCE)
set(WITH_DOC_MANPAGE ON CACHE BOOL "" FORCE)
elseif(WIN32)
set(WITH_JACK OFF CACHE BOOL "" FORCE)
elseif(APPLE)
set(WITH_JACK ON CACHE BOOL "" FORCE)
# include("${CMAKE_CURRENT_SOURCE_DIR}/../platform/platform_apple_xcode.cmake")
endif()

View File

@@ -36,6 +36,7 @@ set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE)
set(WITH_JACK OFF CACHE BOOL "" FORCE)
set(WITH_LZMA OFF CACHE BOOL "" FORCE)
set(WITH_LZO OFF CACHE BOOL "" FORCE)
set(WITH_MOD_BOOLEAN OFF CACHE BOOL "" FORCE)
set(WITH_MOD_FLUID OFF CACHE BOOL "" FORCE)
set(WITH_MOD_REMESH OFF CACHE BOOL "" FORCE)
set(WITH_MOD_SMOKE OFF CACHE BOOL "" FORCE)

View File

@@ -0,0 +1,54 @@
# turn everything OFF except for python which defaults to ON
# and is needed for the UI
#
# Example usage:
# cmake -C../blender/build_files/cmake/config/blender_lite.cmake ../blender
#
set(WITH_INSTALL_PORTABLE ON CACHE BOOL "" FORCE)
set(WITH_SYSTEM_GLEW ON CACHE BOOL "" FORCE)
set(WITH_ALEMBIC OFF CACHE BOOL "" FORCE)
set(WITH_BOOST OFF CACHE BOOL "" FORCE)
set(WITH_BUILDINFO OFF CACHE BOOL "" FORCE)
set(WITH_BULLET OFF CACHE BOOL "" FORCE)
set(WITH_CODEC_AVI OFF CACHE BOOL "" FORCE)
set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_OSL OFF CACHE BOOL "" FORCE)
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
set(WITH_LIBMV OFF CACHE BOOL "" FORCE)
set(WITH_LLVM OFF CACHE BOOL "" FORCE)
set(WITH_COMPOSITOR OFF CACHE BOOL "" FORCE)
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
set(WITH_GHOST_XDND OFF CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE)
set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_DDS OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_HDR OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENEXR OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENJPEG OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_TIFF OFF CACHE BOOL "" FORCE)
set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE)
set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE)
set(WITH_JACK OFF CACHE BOOL "" FORCE)
set(WITH_LZMA OFF CACHE BOOL "" FORCE)
set(WITH_LZO OFF CACHE BOOL "" FORCE)
set(WITH_MOD_FLUID OFF CACHE BOOL "" FORCE)
set(WITH_MOD_REMESH OFF CACHE BOOL "" FORCE)
set(WITH_MOD_SMOKE OFF CACHE BOOL "" FORCE)
set(WITH_MOD_OCEANSIM OFF CACHE BOOL "" FORCE)
set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
set(WITH_OPENCOLORIO OFF CACHE BOOL "" FORCE)
set(WITH_OPENIMAGEIO OFF CACHE BOOL "" FORCE)
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
set(WITH_RAYOPTIMIZATION OFF CACHE BOOL "" FORCE)
set(WITH_SDL OFF CACHE BOOL "" FORCE)
set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
set(WITH_X11_XF86VMODE OFF CACHE BOOL "" FORCE)

View File

@@ -32,6 +32,7 @@ set(WITH_INTERNATIONAL ON CACHE BOOL "" FORCE)
set(WITH_JACK ON CACHE BOOL "" FORCE)
set(WITH_LZMA ON CACHE BOOL "" FORCE)
set(WITH_LZO ON CACHE BOOL "" FORCE)
set(WITH_MOD_BOOLEAN ON CACHE BOOL "" FORCE)
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
set(WITH_MOD_REMESH ON CACHE BOOL "" FORCE)
set(WITH_MOD_SMOKE ON CACHE BOOL "" FORCE)

View File

@@ -0,0 +1,67 @@
# Turn everything ON that's expected for an official release builds.
#
# Example usage:
# cmake -C../blender/build_files/cmake/config/blender_release.cmake ../blender
#
set(WITH_ALEMBIC ON CACHE BOOL "" FORCE)
set(WITH_ASSERT_ABORT OFF CACHE BOOL "" FORCE)
set(WITH_BUILDINFO ON CACHE BOOL "" FORCE)
set(WITH_BULLET ON CACHE BOOL "" FORCE)
set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
set(WITH_LIBMV ON CACHE BOOL "" FORCE)
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS ON CACHE BOOL "" FORCE)
set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
set(WITH_GHOST_XDND ON CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE)
set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE)
set(WITH_INTERNATIONAL ON CACHE BOOL "" FORCE)
set(WITH_JACK ON CACHE BOOL "" FORCE)
set(WITH_LZMA ON CACHE BOOL "" FORCE)
set(WITH_LZO ON CACHE BOOL "" FORCE)
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
set(WITH_MOD_REMESH ON CACHE BOOL "" FORCE)
set(WITH_MOD_SMOKE ON CACHE BOOL "" FORCE)
set(WITH_MOD_OCEANSIM ON CACHE BOOL "" FORCE)
set(WITH_AUDASPACE ON CACHE BOOL "" FORCE)
set(WITH_OPENAL ON CACHE BOOL "" FORCE)
set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE)
set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE)
set(WITH_OPENMP ON CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
set(WITH_RAYOPTIMIZATION ON CACHE BOOL "" FORCE)
set(WITH_SDL ON CACHE BOOL "" FORCE)
set(WITH_X11_XINPUT ON CACHE BOOL "" FORCE)
set(WITH_X11_XF86VMODE ON CACHE BOOL "" FORCE)
set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
set(CYCLES_CUDA_BINARIES_ARCH sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61;sm_70;sm_75 CACHE STRING "" FORCE)
# platform dependent options
if(UNIX AND NOT APPLE)
set(WITH_JACK ON CACHE BOOL "" FORCE)
set(WITH_DOC_MANPAGE ON CACHE BOOL "" FORCE)
elseif(WIN32)
set(WITH_JACK OFF CACHE BOOL "" FORCE)
elseif(APPLE)
set(WITH_JACK ON CACHE BOOL "" FORCE)
# include("${CMAKE_CURRENT_SOURCE_DIR}/../platform/platform_apple_xcode.cmake")
endif()

View File

@@ -739,6 +739,10 @@ function(SETUP_BLENDER_SORTED_LIBS)
list(APPEND BLENDER_SORTED_LIBS bf_intern_itasc)
endif()
if(WITH_MOD_BOOLEAN)
list(APPEND BLENDER_SORTED_LIBS extern_carve)
endif()
if(WITH_GHOST_XDND)
list(APPEND BLENDER_SORTED_LIBS extern_xdnd)
endif()
@@ -763,6 +767,10 @@ function(SETUP_BLENDER_SORTED_LIBS)
list(APPEND BLENDER_SORTED_LIBS bf_intern_gpudirect)
endif()
if(WITH_VORO)
list(APPEND BLENDER_SORTED_LIBS extern_voro)
endif()
if(WITH_OPENVDB)
list(APPEND BLENDER_SORTED_LIBS bf_intern_openvdb)
endif()

View File

@@ -73,10 +73,18 @@ if(WITH_CYCLES OR WITH_COMPOSITOR OR WITH_OPENSUBDIV)
endif()
endif()
if(WITH_MOD_BOOLEAN)
add_subdirectory(carve)
endif()
if(WITH_X11 AND WITH_GHOST_XDND)
add_subdirectory(xdnd)
endif()
if(WITH_VORO)
add_subdirectory(voro++)
endif()
if(WITH_LIBMV)
add_subdirectory(ceres)
endif()

170
extern/carve/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,170 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2006, Blender Foundation
# All rights reserved.
#
# The Original Code is: all of this file.
#
# Contributor(s): Jacques Beaurai, Erwin Coumans
#
# ***** END GPL LICENSE BLOCK *****
# NOTE: This file is automatically generated by bundle.sh script
# If you're doing changes in this file, please update template
# in that script too
set(INC
include
)
set(INC_SYS
)
set(SRC
carve-capi.cc
carve-util.cc
lib/carve.cpp
lib/convex_hull.cpp
lib/csg_collector.cpp
lib/csg.cpp
lib/face.cpp
lib/geom2d.cpp
lib/geom3d.cpp
lib/intersect_classify_edge.cpp
lib/intersect_classify_group.cpp
lib/intersect.cpp
lib/intersect_debug.cpp
lib/intersect_face_division.cpp
lib/intersect_group.cpp
lib/intersect_half_classify_group.cpp
lib/intersection.cpp
lib/math.cpp
lib/mesh.cpp
lib/octree.cpp
lib/pointset.cpp
lib/polyhedron.cpp
lib/polyline.cpp
lib/tag.cpp
lib/timing.cpp
lib/triangulator.cpp
carve-capi.h
carve-util.h
lib/csg_collector.hpp
lib/csg_data.hpp
lib/csg_detail.hpp
lib/intersect_classify_common.hpp
lib/intersect_classify_common_impl.hpp
lib/intersect_common.hpp
lib/intersect_debug.hpp
include/carve/aabb.hpp
include/carve/aabb_impl.hpp
include/carve/carve.hpp
include/carve/cbrt.h
include/carve/classification.hpp
include/carve/collection.hpp
include/carve/collection_types.hpp
include/carve/collection/unordered/boost_impl.hpp
include/carve/collection/unordered/fallback_impl.hpp
include/carve/collection/unordered.hpp
include/carve/collection/unordered/libstdcpp_impl.hpp
include/carve/collection/unordered/std_impl.hpp
include/carve/collection/unordered/tr1_impl.hpp
include/carve/collection/unordered/vcpp_impl.hpp
include/carve/colour.hpp
include/carve/convex_hull.hpp
include/carve/csg.hpp
include/carve/csg_triangulator.hpp
include/carve/debug_hooks.hpp
include/carve/djset.hpp
include/carve/edge_decl.hpp
include/carve/edge_impl.hpp
include/carve/exact.hpp
include/carve/face_decl.hpp
include/carve/face_impl.hpp
include/carve/faceloop.hpp
include/carve/geom2d.hpp
include/carve/geom3d.hpp
include/carve/geom.hpp
include/carve/geom_impl.hpp
include/carve/gnu_cxx.h
include/carve/heap.hpp
include/carve/input.hpp
include/carve/interpolator.hpp
include/carve/intersection.hpp
include/carve/iobj.hpp
include/carve/kd_node.hpp
include/carve/math_constants.hpp
include/carve/math.hpp
include/carve/matrix.hpp
include/carve/mesh.hpp
include/carve/mesh_impl.hpp
include/carve/mesh_ops.hpp
include/carve/mesh_simplify.hpp
include/carve/octree_decl.hpp
include/carve/octree_impl.hpp
include/carve/pointset_decl.hpp
include/carve/pointset.hpp
include/carve/pointset_impl.hpp
include/carve/pointset_iter.hpp
include/carve/poly_decl.hpp
include/carve/polyhedron_base.hpp
include/carve/polyhedron_decl.hpp
include/carve/polyhedron_impl.hpp
include/carve/poly.hpp
include/carve/poly_impl.hpp
include/carve/polyline_decl.hpp
include/carve/polyline.hpp
include/carve/polyline_impl.hpp
include/carve/polyline_iter.hpp
include/carve/rescale.hpp
include/carve/rtree.hpp
include/carve/spacetree.hpp
include/carve/tag.hpp
include/carve/timing.hpp
include/carve/tree.hpp
include/carve/triangle_intersection.hpp
include/carve/triangulator.hpp
include/carve/triangulator_impl.hpp
include/carve/util.hpp
include/carve/vcpp_config.h
include/carve/vector.hpp
include/carve/vertex_decl.hpp
include/carve/vertex_impl.hpp
include/carve/win32.h
)
if(WITH_BOOST)
if(NOT MSVC)
# Boost is setting as preferred collections library in the Carve code when using MSVC compiler
add_definitions(
-DHAVE_BOOST_UNORDERED_COLLECTIONS
)
endif()
add_definitions(
-DCARVE_SYSTEM_BOOST
-DHAVE_BOOST_LIBRARY
)
list(APPEND INC_SYS
${BOOST_INCLUDE_DIR}
)
endif()
blender_add_lib(extern_carve "${SRC}" "${INC}" "${INC_SYS}")

361
extern/carve/LICENSE.GPL2 vendored Normal file
View File

@@ -0,0 +1,361 @@
GNU GENERAL PUBLIC LICENSE
The Qt GUI Toolkit is Copyright (C) 1994-2008 Trolltech ASA.
You may use, distribute and copy the Qt GUI Toolkit under the terms of
GNU General Public License version 2, which is displayed below.
-------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
-------------------------------------------------------------------------
In addition, as a special exception, Trolltech gives permission to link the
code of its release of Qt with the OpenSSL project's "OpenSSL" library (or
modified versions of it that use the same license as the "OpenSSL"
library), and distribute the linked executables. You must comply with the GNU
General Public License version 2 or the GNU General Public License version 3
in all respects for all of the code used other than the "OpenSSL" code. If
you modify this file, you may extend this exception to your version of the
file, but you are not obligated to do so. If you do not wish to do so,
delete this exception statement from your version of this file.

674
extern/carve/LICENSE.GPL3 vendored Normal file
View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

4
extern/carve/README.blender vendored Normal file
View File

@@ -0,0 +1,4 @@
Project: Carve, CSG library
URL: https://code.google.com/archive/p/carve/
Upstream version 9a85d733a43d
Local modifications: See patches/ folder

105
extern/carve/bundle.sh vendored Executable file
View File

@@ -0,0 +1,105 @@
#!/bin/sh
if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then
echo Proceeding as requested by command line ...
else
echo "*** Please run again with --i-really-know-what-im-doing ..."
exit 1
fi
tmp=`mktemp -d`
hg clone https://code.google.com/p/carve/ $tmp/carve
for p in `cat ./patches/series`; do
echo "Applying patch $p..."
cat ./patches/$p | patch -d $tmp/carve -p1
done
find include -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
find lib -type f -not -iwholename '*.svn*' -exec rm -rf {} \;
cat "files.txt" | while read f; do
mkdir -p `dirname $f`
cp $tmp/carve/$f $f
done
rm -rf $tmp
sources=`find ./lib -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | sort -d`
headers=`find ./lib -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/' | sort -d`
includes=`find ./include -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/' | sort -d`
cp patches/files/config.h include/carve/config.h
mkdir -p include/carve/random
cp patches/files/random.h include/carve/random/random.h
cat > CMakeLists.txt << EOF
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2006, Blender Foundation
# All rights reserved.
#
# The Original Code is: all of this file.
#
# Contributor(s): Jacques Beaurai, Erwin Coumans
#
# ***** END GPL LICENSE BLOCK *****
# NOTE: This file is automatically generated by bundle.sh script
# If you're doing changes in this file, please update template
# in that script too
set(INC
include
)
set(INC_SYS
)
set(SRC
carve-capi.cc
carve-util.cc
${sources}
carve-capi.h
carve-util.h
${headers}
${includes}
)
if(WITH_BOOST)
if(NOT MSVC)
# Boost is setting as preferred collections library in the Carve code when using MSVC compiler
add_definitions(
-DHAVE_BOOST_UNORDERED_COLLECTIONS
)
endif()
add_definitions(
-DCARVE_SYSTEM_BOOST
-DHAVE_BOOST_LIBRARY
)
list(APPEND INC_SYS
\${BOOST_INCLUDE_DIR}
)
endif()
blender_add_lib(extern_carve "\${SRC}" "\${INC}" "\${INC_SYS}")
EOF

994
extern/carve/carve-capi.cc vendored Normal file
View File

@@ -0,0 +1,994 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "carve-capi.h"
#include "carve-util.h"
#include <carve/interpolator.hpp>
#include <carve/rescale.hpp>
#include <carve/csg_triangulator.hpp>
#include <carve/mesh_simplify.hpp>
using carve::mesh::MeshSet;
typedef std::pair<int, int> OrigIndex;
typedef std::pair<MeshSet<3>::vertex_t *, MeshSet<3>::vertex_t *> VertexPair;
typedef carve::interpolate::VertexAttr<OrigIndex> OrigVertMapping;
typedef carve::interpolate::FaceAttr<OrigIndex> OrigFaceMapping;
typedef carve::interpolate::SwapableFaceEdgeAttr<OrigIndex> OrigFaceEdgeMapping;
typedef carve::interpolate::SimpleFaceEdgeAttr<bool> FaceEdgeTriangulatedFlag;
typedef struct CarveMeshDescr {
// Stores mesh data itself.
MeshSet<3> *poly;
// N-th element of the vector indicates index of an original mesh loop.
std::unordered_map<std::pair<int, int>, int> orig_loop_index_map;
// Mapping from carve face to an original face index in DM.
std::unordered_map<const MeshSet<3>::face_t *, int> orig_poly_index_map;
// The folloving mapping is only filled in for output mesh.
// Mapping from the face verts back to original vert index.
OrigVertMapping orig_vert_mapping;
// Mapping from the face edges back to (original edge index, original loop index).
OrigFaceEdgeMapping orig_face_edge_mapping;
FaceEdgeTriangulatedFlag face_edge_triangulated_flag;
// Mapping from the faces back to original poly index.
OrigFaceMapping orig_face_mapping;
} CarveMeshDescr;
namespace {
template <typename T1, typename T2>
void edgeIndexMap_put(std::unordered_map<std::pair<T1, T1>, T2> *edge_map,
const T1 &v1,
const T1 &v2,
const T2 &index)
{
if (v1 < v2) {
(*edge_map)[std::make_pair(v1, v2)] = index;
}
else {
(*edge_map)[std::make_pair(v2, v1)] = index;
}
}
template <typename T1, typename T2>
const T2 &edgeIndexMap_get(const std::unordered_map<std::pair<T1, T1>, T2> &edge_map,
const T1 &v1,
const T1 &v2)
{
typedef std::unordered_map<std::pair<T1, T1>, T2> Map;
typename Map::const_iterator found;
if (v1 < v2) {
found = edge_map.find(std::make_pair(v1, v2));
}
else {
found = edge_map.find(std::make_pair(v2, v1));
}
assert(found != edge_map.end());
return found->second;
}
template <typename T1, typename T2>
bool edgeIndexMap_get_if_exists(const std::unordered_map<std::pair<T1, T1>, T2> &edge_map,
const T1 &v1,
const T1 &v2,
T2 *out)
{
typedef std::unordered_map<std::pair<T1, T1>, T2> Map;
typename Map::const_iterator found;
if (v1 < v2) {
found = edge_map.find(std::make_pair(v1, v2));
}
else {
found = edge_map.find(std::make_pair(v2, v1));
}
if (found == edge_map.end()) {
return false;
}
*out = found->second;
return true;
}
template <typename T1, typename T2>
bool edgeIndexMap_exists(const std::unordered_map<std::pair<T1, T1>, T2> &edge_map,
const T1 &v1,
const T1 &v2)
{
typedef std::unordered_map<std::pair<T1, T1>, T2> Map;
typename Map::const_iterator found;
if (v1 < v2) {
found = edge_map.find(std::make_pair(v1, v2));
}
else {
found = edge_map.find(std::make_pair(v2, v1));
}
return found != edge_map.end();
}
template <typename T>
inline int indexOf(const T *element, const std::vector<T> &vector_from)
{
return element - &vector_from.at(0);
}
void initOrigIndexMeshFaceMapping(CarveMeshDescr *mesh,
int which_mesh,
std::unordered_map<std::pair<int, int>, int> &orig_loop_index_map,
std::unordered_map<const MeshSet<3>::face_t*, int> &orig_poly_index_map,
OrigVertMapping *orig_vert_mapping,
OrigFaceEdgeMapping *orig_face_edge_mapping,
FaceEdgeTriangulatedFlag *face_edge_triangulated_flag,
OrigFaceMapping *orig_face_attr)
{
MeshSet<3> *poly = mesh->poly;
std::vector<MeshSet<3>::vertex_t>::iterator vertex_iter =
poly->vertex_storage.begin();
for (int i = 0;
vertex_iter != poly->vertex_storage.end();
++i, ++vertex_iter)
{
MeshSet<3>::vertex_t *vertex = &(*vertex_iter);
orig_vert_mapping->setAttribute(vertex,
std::make_pair(which_mesh, i));
}
MeshSet<3>::face_iter face_iter = poly->faceBegin();
for (int i = 0, loop_map_index = 0;
face_iter != poly->faceEnd();
++face_iter, ++i)
{
const MeshSet<3>::face_t *face = *face_iter;
// Mapping from carve face back to original poly index.
int orig_poly_index = orig_poly_index_map[face];
orig_face_attr->setAttribute(face, std::make_pair(which_mesh, orig_poly_index));
for (MeshSet<3>::face_t::const_edge_iter_t edge_iter = face->begin();
edge_iter != face->end();
++edge_iter, ++loop_map_index)
{
int v1 = indexOf(edge_iter->v1(), poly->vertex_storage);
int v2 = indexOf(edge_iter->v2(), poly->vertex_storage);
int orig_loop_index;
if (!edgeIndexMap_get_if_exists(orig_loop_index_map,
v1, v2,
&orig_loop_index))
{
orig_loop_index = -1;
}
if (orig_loop_index != -1) {
// Mapping from carve face edge back to original loop index.
orig_face_edge_mapping->setAttribute(face,
edge_iter.idx(),
std::make_pair(which_mesh,
orig_loop_index));
}
else {
face_edge_triangulated_flag->setAttribute(face,
edge_iter.idx(),
true);
}
}
}
}
void initOrigIndexMapping(CarveMeshDescr *left_mesh,
CarveMeshDescr *right_mesh,
OrigVertMapping *orig_vert_mapping,
OrigFaceEdgeMapping *orig_face_edge_mapping,
FaceEdgeTriangulatedFlag *face_edge_triangulated_flag,
OrigFaceMapping *orig_face_mapping)
{
initOrigIndexMeshFaceMapping(left_mesh,
CARVE_MESH_LEFT,
left_mesh->orig_loop_index_map,
left_mesh->orig_poly_index_map,
orig_vert_mapping,
orig_face_edge_mapping,
face_edge_triangulated_flag,
orig_face_mapping);
initOrigIndexMeshFaceMapping(right_mesh,
CARVE_MESH_RIGHT,
right_mesh->orig_loop_index_map,
right_mesh->orig_poly_index_map,
orig_vert_mapping,
orig_face_edge_mapping,
face_edge_triangulated_flag,
orig_face_mapping);
}
void origEdgeMappingForFace(MeshSet<3>::face_t *face,
OrigFaceEdgeMapping *orig_face_edge_mapping,
std::unordered_map<VertexPair, OrigIndex> *edge_origindex_map)
{
OrigIndex origindex_none = std::make_pair((int)CARVE_MESH_NONE, -1);
MeshSet<3>::edge_t *edge = face->edge;
for (int i = 0;
i < face->nEdges();
++i, edge = edge->next)
{
MeshSet<3>::vertex_t *v1 = edge->v1();
MeshSet<3>::vertex_t *v2 = edge->v2();
OrigIndex orig_edge_index =
orig_face_edge_mapping->getAttribute(edge->face, i, origindex_none);
edgeIndexMap_put(edge_origindex_map, v1, v2, orig_edge_index);
}
}
void dissolveTriangulatedEdges(MeshSet<3>::mesh_t *mesh,
const std::set< std::pair<int, int> > &open_edges,
FaceEdgeTriangulatedFlag *face_edge_triangulated_flag,
OrigFaceEdgeMapping *orig_face_edge_mapping)
{
typedef std::unordered_set<MeshSet<3>::edge_t *> edge_set_t;
typedef std::unordered_set<MeshSet<3>::face_t *> face_set_t;
edge_set_t triangulated_face_edges;
for (int face_index = 0; face_index < mesh->faces.size(); ++face_index) {
MeshSet<3>::face_t *face = mesh->faces[face_index];
MeshSet<3>::edge_t *edge = face->edge;
for (int edge_index = 0;
edge_index < face->nEdges();
++edge_index, edge = edge->next)
{
if (edge->rev) {
const bool is_triangulated_edge =
face_edge_triangulated_flag->getAttribute(face,
edge_index,
false);
if (is_triangulated_edge) {
MeshSet<3>::edge_t *e1 = std::min(edge, edge->rev);
int v1 = indexOf(e1->v1(), mesh->meshset->vertex_storage),
v2 = indexOf(e1->v2(), mesh->meshset->vertex_storage);
bool is_open = false;
if (v1 < v2) {
is_open = open_edges.find(std::make_pair(v1, v2)) != open_edges.end();
}
else {
is_open = open_edges.find(std::make_pair(v2, v1)) != open_edges.end();
}
if (is_open == false) {
triangulated_face_edges.insert(e1);
}
}
}
}
}
if (triangulated_face_edges.size()) {
face_set_t triangulated_faces;
std::unordered_map<VertexPair, OrigIndex> edge_origindex_map;
for (edge_set_t::iterator it = triangulated_face_edges.begin();
it != triangulated_face_edges.end();
++it)
{
MeshSet<3>::edge_t *edge = *it;
origEdgeMappingForFace(edge->face,
orig_face_edge_mapping,
&edge_origindex_map);
triangulated_faces.insert(edge->face);
origEdgeMappingForFace(edge->rev->face,
orig_face_edge_mapping,
&edge_origindex_map);
triangulated_faces.insert(edge->rev->face);
}
carve::mesh::MeshSimplifier simplifier;
simplifier.dissolveMeshEdges(mesh, triangulated_face_edges);
for (int face_index = 0; face_index < mesh->faces.size(); face_index++) {
MeshSet<3>::face_t *face = mesh->faces[face_index];
if (triangulated_faces.find(face) != triangulated_faces.end()) {
MeshSet<3>::edge_t *edge = face->edge;
for (int edge_index = 0;
edge_index < face->nEdges();
++edge_index, edge = edge->next)
{
MeshSet<3>::vertex_t *v1 = edge->v1();
MeshSet<3>::vertex_t *v2 = edge->v2();
OrigIndex orig_edge_index =
edgeIndexMap_get(edge_origindex_map,
v1,
v2);
orig_face_edge_mapping->setAttribute(face, edge_index, orig_edge_index);
}
}
}
}
}
void dissolveTriangulatedEdges(CarveMeshDescr *mesh_descr)
{
MeshSet<3> *poly = mesh_descr->poly;
FaceEdgeTriangulatedFlag *face_edge_triangulated_flag =
&mesh_descr->face_edge_triangulated_flag;
std::set< std::pair<int, int> > open_edges;
for (int mesh_index = 0;
mesh_index < poly->meshes.size();
++mesh_index)
{
const MeshSet<3>::mesh_t *mesh = poly->meshes[mesh_index];
for (int edge_index = 0;
edge_index < mesh->open_edges.size();
++edge_index)
{
const MeshSet<3>::edge_t *edge = mesh->open_edges[edge_index];
int v1 = indexOf(edge->v1(), poly->vertex_storage),
v2 = indexOf(edge->v2(), poly->vertex_storage);
if (v1 < v2) {
open_edges.insert(std::make_pair(v1, v2));
}
else {
open_edges.insert(std::make_pair(v2, v1));
}
}
}
for (int mesh_index = 0; mesh_index < poly->meshes.size(); ++mesh_index) {
MeshSet<3>::mesh_t *mesh = poly->meshes[mesh_index];
dissolveTriangulatedEdges(mesh,
open_edges,
face_edge_triangulated_flag,
&mesh_descr->orig_face_edge_mapping);
}
}
void clipEar(MeshSet<3>::edge_t *ear)
{
MeshSet<3>::edge_t *p_edge = ear->prev;
MeshSet<3>::edge_t *n_edge = ear->next;
p_edge->next = n_edge;
n_edge->prev = p_edge;
if (ear->face->edge == ear) {
ear->face->edge = n_edge;
}
ear->face->n_edges--;
delete ear;
}
MeshSet<3>::edge_t *findDegenerateEar(MeshSet<3>::face_t *face)
{
for (MeshSet<3>::face_t::edge_iter_t edge_iter = face->begin();
edge_iter != face->end();
++edge_iter)
{
MeshSet<3>::edge_t &edge = *edge_iter;
if (edge.vert == edge.next->next->vert) {
return edge.next->next;
}
}
return NULL;
}
class EarClipper : public carve::csg::CSG::Hook {
public:
virtual ~EarClipper() {
}
virtual void processOutputFace(std::vector<MeshSet<3>::face_t *> &faces,
const MeshSet<3>::face_t *orig,
bool flipped) {
for (size_t face_index = 0; face_index < faces.size(); ++face_index) {
carve::mesh::MeshSet<3>::face_t *face = faces[face_index];
// There's no ears in quads and tris.
if (face->nVertices() <= 4) {
continue;
}
MeshSet<3>::edge_t *ear;
while ((ear = findDegenerateEar(face)) != NULL) {
clipEar(ear);
}
}
}
};
class HoleResolver : public carve::csg::CarveHoleResolver {
void removeDuplicatedFaces(std::vector<MeshSet<3>::face_t *> &faces) {
std::vector<MeshSet<3>::face_t *> out_faces;
std::vector<MeshSet<3>::face_t *> duplicated_faces;
for (size_t face_index = 0; face_index < faces.size(); ++face_index) {
carve::mesh::MeshSet<3>::face_t *face = faces[face_index];
face->canonicalize();
}
for (size_t i = 0; i < faces.size(); ++i) {
carve::mesh::MeshSet<3>::face_t *face = faces[i];
bool found = false;
for (size_t j = i + 1; j < faces.size() && found == false; ++j) {
MeshSet<3>::face_t *cur_face = faces[j];
if (cur_face->nEdges() == face->nEdges() &&
cur_face->edge->vert == face->edge->vert)
{
MeshSet<3>::edge_t *cur_edge = cur_face->edge,
*forward_edge = face->edge,
*backward_edge = face->edge;
bool forward_matches = true, backward_matches = true;
for (int a = 0; a < cur_face->nEdges(); ++a) {
if (forward_edge->vert != cur_edge->vert) {
forward_matches = false;
if (backward_matches == false) {
break;
}
}
if (backward_edge->vert != cur_edge->vert) {
backward_matches = false;
if (forward_matches == false) {
break;
}
}
cur_edge = cur_edge->next;
forward_edge = forward_edge->next;
backward_edge = backward_edge->prev;
}
if (forward_matches || backward_matches) {
found = true;
break;
}
}
}
if (found) {
duplicated_faces.push_back(face);
}
else {
out_faces.push_back(face);
}
}
for (int i = 0; i < duplicated_faces.size(); ++i) {
delete duplicated_faces[i];
}
std::swap(faces, out_faces);
}
public:
virtual ~HoleResolver() {
}
virtual void processOutputFace(std::vector<MeshSet<3>::face_t *> &faces,
const MeshSet<3>::face_t *orig,
bool flipped) {
carve::csg::CarveHoleResolver::processOutputFace(faces, orig, flipped);
if (faces.size() > 1) {
removeDuplicatedFaces(faces);
}
}
};
template <typename Interpolator>
void copyFaceEdgeAttrs(const MeshSet<3> *poly,
Interpolator *old_interpolator,
Interpolator *new_interpolator)
{
for (MeshSet<3>::const_face_iter face_iter = poly->faceBegin();
face_iter != poly->faceEnd();
++face_iter)
{
const MeshSet<3>::face_t *face = *face_iter;
for (int edge_index = 0;
edge_index < face->nEdges();
++edge_index)
{
new_interpolator->copyAttribute(face,
edge_index,
old_interpolator);
}
}
}
template <typename Interpolator>
void cleanupFaceEdgeAttrs(const MeshSet<3> *left,
const MeshSet<3> *right,
Interpolator *interpolator)
{
Interpolator new_interpolator;
copyFaceEdgeAttrs(left, interpolator, &new_interpolator);
copyFaceEdgeAttrs(right, interpolator, &new_interpolator);
interpolator->swapAttributes(&new_interpolator);
}
void cleanupFaceEdgeAttrsCallback(const MeshSet<3> *left,
const MeshSet<3> *right,
void *descr_v)
{
CarveMeshDescr *descr = (CarveMeshDescr *) descr_v;
cleanupFaceEdgeAttrs(left,
right,
&descr->face_edge_triangulated_flag);
cleanupFaceEdgeAttrs(left,
right,
&descr->orig_face_edge_mapping);
}
void copyVertexAttrsCallback(const carve::mesh::MeshSet<3>::vertex_t *orig_vert,
const carve::mesh::MeshSet<3>::vertex_t *new_vert,
void *descr_v)
{
CarveMeshDescr *descr = (CarveMeshDescr *) descr_v;
if (!descr->orig_vert_mapping.hasAttribute(orig_vert)) {
return;
}
if (descr->orig_vert_mapping.hasAttribute(new_vert)) {
return;
}
OrigIndex attr = descr->orig_vert_mapping.getAttribute(orig_vert);
descr->orig_vert_mapping.setAttribute(new_vert, attr);
descr->orig_vert_mapping.removeAttribute(orig_vert);
}
} // namespace
CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
CarveMeshImporter *mesh_importer)
{
#define MAX_STATIC_VERTS 64
CarveMeshDescr *mesh_descr = new CarveMeshDescr;
// Import verices from external mesh to Carve.
int num_verts = mesh_importer->getNumVerts(import_data);
std::vector<MeshSet<3>::vertex_t> vertex_storage;
vertex_storage.reserve(num_verts);
for (int i = 0; i < num_verts; i++) {
float position[3];
mesh_importer->getVertCoord(import_data, i, position);
vertex_storage.push_back(carve::geom::VECTOR(position[0],
position[1],
position[2]));
}
// Import polys from external mesh to Carve.
int verts_of_poly_static[MAX_STATIC_VERTS];
int *verts_of_poly_dynamic = NULL;
int verts_of_poly_dynamic_size = 0;
int num_polys = mesh_importer->getNumPolys(import_data);
int loop_index = 0;
std::vector<int> face_indices;
TrianglesStorage triangles_storage;
std::vector<MeshSet<3>::face_t *> faces;
std::vector<MeshSet<3>::vertex_t *> face_vertices;
faces.reserve(num_polys);
for (int i = 0; i < num_polys; i++) {
int verts_per_poly =
mesh_importer->getNumPolyVerts(import_data, i);
int *verts_of_poly;
if (verts_per_poly <= MAX_STATIC_VERTS) {
verts_of_poly = verts_of_poly_static;
}
else {
if (verts_of_poly_dynamic_size < verts_per_poly) {
if (verts_of_poly_dynamic != NULL) {
delete [] verts_of_poly_dynamic;
}
verts_of_poly_dynamic = new int[verts_per_poly];
verts_of_poly_dynamic_size = verts_per_poly;
}
verts_of_poly = verts_of_poly_dynamic;
}
mesh_importer->getPolyVerts(import_data, i, verts_of_poly);
carve::math::Matrix3 axis_matrix;
if (!carve_checkPolyPlanarAndGetNormal(vertex_storage,
verts_per_poly,
verts_of_poly,
&axis_matrix)) {
face_indices.clear();
int num_triangles = carve_triangulatePoly(import_data,
mesh_importer,
vertex_storage,
verts_per_poly,
verts_of_poly,
axis_matrix,
&face_indices,
&triangles_storage);
for (int j = 0; j < num_triangles; ++j) {
MeshSet<3>::face_t *face = new MeshSet<3>::face_t(
&vertex_storage[face_indices[j * 3]],
&vertex_storage[face_indices[j * 3 + 1]],
&vertex_storage[face_indices[j * 3 + 2]]);
mesh_descr->orig_poly_index_map[face] = i;
faces.push_back(face);
}
}
else {
face_vertices.clear();
face_vertices.reserve(verts_per_poly);
for (int j = 0; j < verts_per_poly; ++j) {
face_vertices.push_back(&vertex_storage[verts_of_poly[j]]);
}
MeshSet<3>::face_t *face =
new MeshSet<3>::face_t(face_vertices.begin(),
face_vertices.end());
mesh_descr->orig_poly_index_map[face] = i;
faces.push_back(face);
}
for (int j = 0; j < verts_per_poly; ++j) {
int v1 = verts_of_poly[j];
int v2 = verts_of_poly[(j + 1) % verts_per_poly];
edgeIndexMap_put(&mesh_descr->orig_loop_index_map, v1, v2, loop_index++);
}
}
if (verts_of_poly_dynamic != NULL) {
delete [] verts_of_poly_dynamic;
}
std::vector<MeshSet<3>::mesh_t *> meshes;
MeshSet<3>::mesh_t::create(faces.begin(), faces.end(), meshes, carve::mesh::MeshOptions());
mesh_descr->poly = new MeshSet<3> (vertex_storage, meshes);
return mesh_descr;
#undef MAX_STATIC_VERTS
}
void carve_deleteMesh(CarveMeshDescr *mesh_descr)
{
delete mesh_descr->poly;
delete mesh_descr;
}
bool carve_performBooleanOperation(CarveMeshDescr *left_mesh,
CarveMeshDescr *right_mesh,
int operation,
CarveMeshDescr **output_mesh)
{
*output_mesh = NULL;
carve::csg::CSG::OP op;
switch (operation) {
#define OP_CONVERT(the_op) \
case CARVE_OP_ ## the_op: \
op = carve::csg::CSG::the_op; \
break;
OP_CONVERT(UNION)
OP_CONVERT(INTERSECTION)
OP_CONVERT(A_MINUS_B)
default:
return false;
#undef OP_CONVERT
}
CarveMeshDescr *output_descr = new CarveMeshDescr;
output_descr->poly = NULL;
try {
MeshSet<3> *left = left_mesh->poly, *right = right_mesh->poly;
carve::geom3d::Vector min, max;
// TODO(sergey): Make importer/exporter to care about re-scale
// to save extra mesh iteration here.
carve_getRescaleMinMax(left, right, &min, &max);
carve::rescale::rescale scaler(min.x, min.y, min.z, max.x, max.y, max.z);
carve::rescale::fwd fwd_r(scaler);
carve::rescale::rev rev_r(scaler);
left->transform(fwd_r);
right->transform(fwd_r);
// Initialize attributes for maping from boolean result mesh back to
// original geometry indices.
initOrigIndexMapping(left_mesh, right_mesh,
&output_descr->orig_vert_mapping,
&output_descr->orig_face_edge_mapping,
&output_descr->face_edge_triangulated_flag,
&output_descr->orig_face_mapping);
carve::csg::CSG csg;
csg.hooks.registerHook(new HoleResolver,
carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT);
csg.hooks.registerHook(new EarClipper,
carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT);
output_descr->orig_vert_mapping.installHooks(csg);
output_descr->orig_face_edge_mapping.installHooks(csg);
output_descr->face_edge_triangulated_flag.installHooks(csg);
output_descr->orig_face_mapping.installHooks(csg);
// Prepare operands for actual boolean operation.
//
// It's needed because operands might consist of several intersecting
// meshes and in case of another operands intersect an edge loop of
// intersecting that meshes tessellation of operation result can't be
// done properly. The only way to make such situations working is to
// union intersecting meshes of the same operand.
carve_unionIntersections(&csg, &left, &right,
copyVertexAttrsCallback,
cleanupFaceEdgeAttrsCallback,
(void *) output_descr);
left_mesh->poly = left;
right_mesh->poly = right;
if (left->meshes.size() == 0 || right->meshes.size() == 0) {
// Normally shouldn't happen (zero-faces objects are handled by
// modifier itself), but unioning intersecting meshes which doesn't
// have consistent normals might lead to empty result which
// wouldn't work here.
return false;
}
output_descr->poly = csg.compute(left,
right,
op,
NULL,
carve::csg::CSG::CLASSIFY_EDGE);
if (output_descr->poly) {
output_descr->poly->transform(rev_r);
dissolveTriangulatedEdges(output_descr);
}
}
catch (carve::exception e) {
std::cerr << "CSG failed, exception " << e.str() << std::endl;
}
catch (...) {
std::cerr << "Unknown error in Carve library" << std::endl;
}
*output_mesh = output_descr;
return output_descr->poly != NULL;
}
static int exportMesh_handle_edges_list(MeshSet<3> *poly,
const std::vector<MeshSet<3>::edge_t*> &edges,
int start_edge_index,
CarveMeshExporter *mesh_exporter,
struct ExportMeshData *export_data,
std::unordered_map<VertexPair, OrigIndex> &edge_origindex_map,
std::unordered_map<VertexPair, int> *edge_map)
{
int num_exported_edges = 0;
for (int i = 0, edge_index = start_edge_index;
i < edges.size();
++i)
{
MeshSet<3>::edge_t *edge = edges.at(i);
MeshSet<3>::vertex_t *v1 = edge->v1();
MeshSet<3>::vertex_t *v2 = edge->v2();
if (edgeIndexMap_exists(*edge_map, v1, v2)) {
continue;
}
const OrigIndex &orig_edge_index = edgeIndexMap_get(edge_origindex_map,
v1,
v2);
mesh_exporter->setEdge(export_data,
edge_index,
indexOf(v1, poly->vertex_storage),
indexOf(v2, poly->vertex_storage),
orig_edge_index.first,
orig_edge_index.second);
edgeIndexMap_put(edge_map, v1, v2, edge_index);
++edge_index;
++num_exported_edges;
}
return num_exported_edges;
}
void carve_exportMesh(CarveMeshDescr *mesh_descr,
CarveMeshExporter *mesh_exporter,
struct ExportMeshData *export_data)
{
OrigIndex origindex_none = std::make_pair((int)CARVE_MESH_NONE, -1);
MeshSet<3> *poly = mesh_descr->poly;
int num_vertices = poly->vertex_storage.size();
int num_edges = 0, num_loops = 0, num_polys = 0;
// Get mapping from edge denoted by vertex pair to original edge index,
//
// This is needed because internally Carve interpolates data for per-face
// edges rather then having some global edge storage.
std::unordered_map<VertexPair, OrigIndex> edge_origindex_map;
for (MeshSet<3>::face_iter face_iter = poly->faceBegin();
face_iter != poly->faceEnd();
++face_iter)
{
MeshSet<3>::face_t *face = *face_iter;
for (MeshSet<3>::face_t::edge_iter_t edge_iter = face->begin();
edge_iter != face->end();
++edge_iter)
{
MeshSet<3>::edge_t &edge = *edge_iter;
int edge_iter_index = edge_iter.idx();
const OrigIndex &orig_loop_index =
mesh_descr->orig_face_edge_mapping.getAttribute(face,
edge_iter_index,
origindex_none);
OrigIndex orig_edge_index;
if (orig_loop_index.first != CARVE_MESH_NONE) {
orig_edge_index.first = orig_loop_index.first;
orig_edge_index.second =
mesh_exporter->mapLoopToEdge(export_data,
orig_loop_index.first,
orig_loop_index.second);
}
else {
orig_edge_index.first = CARVE_MESH_NONE;
orig_edge_index.second = -1;
}
MeshSet<3>::vertex_t *v1 = edge.v1();
MeshSet<3>::vertex_t *v2 = edge.v2();
edgeIndexMap_put(&edge_origindex_map, v1, v2, orig_edge_index);
}
}
num_edges = edge_origindex_map.size();
// Count polys and loops from all manifolds.
for (MeshSet<3>::face_iter face_iter = poly->faceBegin();
face_iter != poly->faceEnd();
++face_iter, ++num_polys)
{
MeshSet<3>::face_t *face = *face_iter;
num_loops += face->nEdges();
}
// Initialize arrays for geometry in exported mesh.
mesh_exporter->initGeomArrays(export_data,
num_vertices,
num_edges,
num_loops,
num_polys);
// Export all the vertices.
std::vector<MeshSet<3>::vertex_t>::iterator vertex_iter = poly->vertex_storage.begin();
for (int i = 0; vertex_iter != poly->vertex_storage.end(); ++i, ++vertex_iter) {
MeshSet<3>::vertex_t *vertex = &(*vertex_iter);
OrigIndex orig_vert_index =
mesh_descr->orig_vert_mapping.getAttribute(vertex, origindex_none);
float coord[3];
coord[0] = vertex->v[0];
coord[1] = vertex->v[1];
coord[2] = vertex->v[2];
mesh_exporter->setVert(export_data, i, coord,
orig_vert_index.first,
orig_vert_index.second);
}
// Export all the edges.
std::unordered_map<VertexPair, int> edge_map;
for (int i = 0, edge_index = 0; i < poly->meshes.size(); ++i) {
carve::mesh::Mesh<3> *mesh = poly->meshes[i];
// Export closed edges.
edge_index += exportMesh_handle_edges_list(poly,
mesh->closed_edges,
edge_index,
mesh_exporter,
export_data,
edge_origindex_map,
&edge_map);
// Export open edges.
edge_index += exportMesh_handle_edges_list(poly,
mesh->open_edges,
edge_index,
mesh_exporter,
export_data,
edge_origindex_map,
&edge_map);
}
// Export all the loops and polys.
MeshSet<3>::face_iter face_iter = poly->faceBegin();
for (int loop_index = 0, poly_index = 0;
face_iter != poly->faceEnd();
++face_iter, ++poly_index)
{
int start_loop_index = loop_index;
MeshSet<3>::face_t *face = *face_iter;
const OrigIndex &orig_face_index =
mesh_descr->orig_face_mapping.getAttribute(face, origindex_none);
for (MeshSet<3>::face_t::edge_iter_t edge_iter = face->begin();
edge_iter != face->end();
++edge_iter, ++loop_index)
{
MeshSet<3>::edge_t &edge = *edge_iter;
const OrigIndex &orig_loop_index =
mesh_descr->orig_face_edge_mapping.getAttribute(face,
edge_iter.idx(),
origindex_none);
mesh_exporter->setLoop(export_data,
loop_index,
indexOf(edge.vert, poly->vertex_storage),
edgeIndexMap_get(edge_map, edge.v1(), edge.v2()),
orig_loop_index.first,
orig_loop_index.second);
}
mesh_exporter->setPoly(export_data,
poly_index, start_loop_index, face->nEdges(),
orig_face_index.first, orig_face_index.second);
}
}

164
extern/carve/carve-capi.h vendored Normal file
View File

@@ -0,0 +1,164 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __CARVE_CAPI_H__
#define __CARVE_CAPI_H__
#ifdef __cplusplus
extern "C" {
#endif
struct CarveMeshDescr;
//
// Importer from external storage to Carve module
//
struct ImportMeshData;
// Get number of vertices.
typedef int (*CarveImporter_GetNumVerts) (struct ImportMeshData *import_data);
// Get number of edges.
typedef int (*CarveImporter_GetNumEdges) (struct ImportMeshData *import_data);
// Get number of loops.
typedef int (*CarveImporter_GetNumLoops) (struct ImportMeshData *import_data);
// Get number of polys.
typedef int (*CarveImporter_GetNumPolys) (struct ImportMeshData *import_data);
// Get 3D coordinate of vertex with given index.
typedef void (*CarveImporter_GetVertCoord) (struct ImportMeshData *import_data, int vert_index, float coord[3]);
// Get index of vertices which are adjacent to edge specified by its index.
typedef void (*CarveImporter_GetEdgeVerts) (struct ImportMeshData *import_data, int edge_index, int *v1, int *v2);
// Get number of adjacent vertices to the poly specified by its index.
typedef int (*CarveImporter_GetPolyNumVerts) (struct ImportMeshData *import_data, int poly_index);
// Get list of adjacent vertices to the poly specified by its index.
typedef void (*CarveImporter_GetPolyVerts) (struct ImportMeshData *import_data, int poly_index, int *verts);
// Triangulate 2D polygon.
typedef int (*CarveImporter_Triangulate2DPoly) (struct ImportMeshData *import_data,
const float (*vertices)[2], int num_vertices,
unsigned int (*triangles)[3]);
typedef struct CarveMeshImporter {
CarveImporter_GetNumVerts getNumVerts;
CarveImporter_GetNumEdges getNumEdges;
CarveImporter_GetNumLoops getNumLoops;
CarveImporter_GetNumPolys getNumPolys;
CarveImporter_GetVertCoord getVertCoord;
CarveImporter_GetEdgeVerts getEdgeVerts;
CarveImporter_GetPolyNumVerts getNumPolyVerts;
CarveImporter_GetPolyVerts getPolyVerts;
CarveImporter_Triangulate2DPoly triangulate2DPoly;
} CarveMeshImporter;
//
// Exporter from Carve module to external storage
//
struct ExportMeshData;
// Initialize arrays for geometry.
typedef void (*CarveExporter_InitGeomArrays) (struct ExportMeshData *export_data,
int num_verts, int num_edges,
int num_loops, int num_polys);
// Set coordinate of vertex with given index.
typedef void (*CarveExporter_SetVert) (struct ExportMeshData *export_data,
int vert_index, float coord[3],
int which_orig_mesh, int orig_vert_index);
// Set vertices which are adjacent to the edge specified by its index.
typedef void (*CarveExporter_SetEdge) (struct ExportMeshData *export_data,
int edge_index, int v1, int v2,
int which_orig_mesh, int orig_edge_index);
// Set adjacent loops to the poly specified by its index.
typedef void (*CarveExporter_SetPoly) (struct ExportMeshData *export_data,
int poly_index, int start_loop, int num_loops,
int which_orig_mesh, int orig_poly_index);
// Set list vertex and edge which are adjacent to loop with given index.
typedef void (*CarveExporter_SetLoop) (struct ExportMeshData *export_data,
int loop_index, int vertex, int edge,
int which_orig_mesh, int orig_loop_index);
// Get edge index from a loop index for a given original mesh.
//
// A bit of a bummer to access original operands data on export stage,
// but Blender side still does have this information in derived meshes
// and we use API to get this data instead of duplicating it in Carve
// API side. This is because of optimizations reasons.
typedef int (*CarveExporter_MapLoopToEdge) (struct ExportMeshData *export_data,
int which_mesh, int loop_index);
typedef struct CarveMeshExporter {
CarveExporter_InitGeomArrays initGeomArrays;
CarveExporter_SetVert setVert;
CarveExporter_SetEdge setEdge;
CarveExporter_SetPoly setPoly;
CarveExporter_SetLoop setLoop;
CarveExporter_MapLoopToEdge mapLoopToEdge;
} CarveMeshExporter;
enum {
CARVE_OP_UNION,
CARVE_OP_INTERSECTION,
CARVE_OP_A_MINUS_B,
};
enum {
CARVE_MESH_NONE,
CARVE_MESH_LEFT,
CARVE_MESH_RIGHT
};
struct CarveMeshDescr *carve_addMesh(struct ImportMeshData *import_data,
CarveMeshImporter *mesh_importer);
void carve_deleteMesh(struct CarveMeshDescr *mesh_descr);
bool carve_performBooleanOperation(struct CarveMeshDescr *left_mesh,
struct CarveMeshDescr *right_mesh,
int operation,
struct CarveMeshDescr **output_mesh);
void carve_exportMesh(struct CarveMeshDescr *mesh_descr,
CarveMeshExporter *mesh_exporter,
struct ExportMeshData *export_data);
void carve_unionIntersections(struct CarveMeshDescr **left_mesh_r, struct CarveMeshDescr **right_mesh_r);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __CARVE_CAPI_H__

838
extern/carve/carve-util.cc vendored Normal file
View File

@@ -0,0 +1,838 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "carve-util.h"
#include "carve-capi.h"
#include <cfloat>
#include <carve/csg.hpp>
#include <carve/csg_triangulator.hpp>
#include <carve/rtree.hpp>
using carve::csg::Intersections;
using carve::geom::aabb;
using carve::geom::RTreeNode;
using carve::geom3d::Vector;
using carve::math::Matrix3;
using carve::mesh::Face;
using carve::mesh::MeshSet;
using carve::triangulate::tri_idx;
using carve::triangulate::triangulate;
typedef std::map< MeshSet<3>::mesh_t*, RTreeNode<3, Face<3> *> * > RTreeCache;
typedef std::map< MeshSet<3>::mesh_t*, bool > IntersectCache;
namespace {
// Functions adopted from BLI_math.h to use Carve Vector and Matrix.
void transpose_m3__bli(double mat[3][3])
{
double t;
t = mat[0][1];
mat[0][1] = mat[1][0];
mat[1][0] = t;
t = mat[0][2];
mat[0][2] = mat[2][0];
mat[2][0] = t;
t = mat[1][2];
mat[1][2] = mat[2][1];
mat[2][1] = t;
}
void ortho_basis_v3v3_v3__bli(double r_n1[3], double r_n2[3], const double n[3])
{
const double eps = FLT_EPSILON;
const double f = (n[0] * n[0]) + (n[1] * n[1]);
if (f > eps) {
const double d = 1.0f / sqrt(f);
r_n1[0] = n[1] * d;
r_n1[1] = -n[0] * d;
r_n1[2] = 0.0f;
r_n2[0] = -n[2] * r_n1[1];
r_n2[1] = n[2] * r_n1[0];
r_n2[2] = n[0] * r_n1[1] - n[1] * r_n1[0];
}
else {
/* degenerate case */
r_n1[0] = (n[2] < 0.0f) ? -1.0f : 1.0f;
r_n1[1] = r_n1[2] = r_n2[0] = r_n2[2] = 0.0f;
r_n2[1] = 1.0f;
}
}
void axis_dominant_v3_to_m3__bli(Matrix3 *r_mat, const Vector &normal)
{
memcpy(r_mat->m[2], normal.v, sizeof(double[3]));
ortho_basis_v3v3_v3__bli(r_mat->m[0], r_mat->m[1], r_mat->m[2]);
transpose_m3__bli(r_mat->m);
}
void meshset_minmax(const MeshSet<3> *mesh,
Vector *min,
Vector *max)
{
for (size_t i = 0; i < mesh->vertex_storage.size(); ++i) {
min->x = std::min(min->x, mesh->vertex_storage[i].v.x);
min->y = std::min(min->y, mesh->vertex_storage[i].v.y);
min->z = std::min(min->z, mesh->vertex_storage[i].v.z);
max->x = std::max(max->x, mesh->vertex_storage[i].v.x);
max->y = std::max(max->y, mesh->vertex_storage[i].v.y);
max->z = std::max(max->z, mesh->vertex_storage[i].v.z);
}
}
} // namespace
void carve_getRescaleMinMax(const MeshSet<3> *left,
const MeshSet<3> *right,
Vector *min,
Vector *max)
{
min->x = max->x = left->vertex_storage[0].v.x;
min->y = max->y = left->vertex_storage[0].v.y;
min->z = max->z = left->vertex_storage[0].v.z;
meshset_minmax(left, min, max);
meshset_minmax(right, min, max);
// Make sure we don't scale object with zero scale.
if (std::abs(min->x - max->x) < carve::EPSILON) {
min->x = -1.0;
max->x = 1.0;
}
if (std::abs(min->y - max->y) < carve::EPSILON) {
min->y = -1.0;
max->y = 1.0;
}
if (std::abs(min->z - max->z) < carve::EPSILON) {
min->z = -1.0;
max->z = 1.0;
}
}
namespace {
struct UnionIntersectionContext {
VertexAttrsCallback vertex_attr_callback;
void *user_data;
};
void copyMeshes(const std::vector<MeshSet<3>::mesh_t*> &meshes,
std::vector<MeshSet<3>::mesh_t*> *new_meshes)
{
std::vector<MeshSet<3>::mesh_t*>::const_iterator it = meshes.begin();
new_meshes->reserve(meshes.size());
for (; it != meshes.end(); it++) {
MeshSet<3>::mesh_t *mesh = *it;
MeshSet<3>::mesh_t *new_mesh = new MeshSet<3>::mesh_t(mesh->faces);
new_meshes->push_back(new_mesh);
}
}
struct NewMeshMapping {
std::map<const MeshSet<3>::edge_t*, MeshSet<3>::vertex_t*> orig_edge_vert;
};
void prepareNewMeshMapping(const std::vector<MeshSet<3>::mesh_t*> &meshes,
NewMeshMapping *mapping)
{
for (size_t m = 0; m < meshes.size(); ++m) {
MeshSet<3>::mesh_t *mesh = meshes[m];
for (size_t f = 0; f < mesh->faces.size(); ++f) {
MeshSet<3>::face_t *face = mesh->faces[f];
MeshSet<3>::edge_t *edge = face->edge;
do {
mapping->orig_edge_vert[edge] = edge->vert;
edge = edge->next;
} while (edge != face->edge);
}
}
}
void runNewMeshSetHooks(UnionIntersectionContext *ctx,
NewMeshMapping *mapping,
MeshSet<3> *mesh_set)
{
for (size_t m = 0; m < mesh_set->meshes.size(); ++m) {
MeshSet<3>::mesh_t *mesh = mesh_set->meshes[m];
for (size_t f = 0; f < mesh->faces.size(); ++f) {
MeshSet<3>::face_t *face = mesh->faces[f];
MeshSet<3>::edge_t *edge = face->edge;
do {
const MeshSet<3>::vertex_t *orig_vert = mapping->orig_edge_vert[edge];
const MeshSet<3>::vertex_t *new_vert = edge->vert;
ctx->vertex_attr_callback(orig_vert, new_vert, ctx->user_data);
edge = edge->next;
} while (edge != face->edge);
}
}
}
MeshSet<3> *newMeshSetFromMeshesWithAttrs(
UnionIntersectionContext *ctx,
std::vector<MeshSet<3>::mesh_t*> &meshes)
{
NewMeshMapping mapping;
prepareNewMeshMapping(meshes, &mapping);
MeshSet<3> *mesh_set = new MeshSet<3>(meshes);
runNewMeshSetHooks(ctx, &mapping, mesh_set);
return mesh_set;
}
MeshSet<3> *meshSetFromMeshes(UnionIntersectionContext *ctx,
const std::vector<MeshSet<3>::mesh_t*> &meshes)
{
std::vector<MeshSet<3>::mesh_t*> new_meshes;
copyMeshes(meshes, &new_meshes);
return newMeshSetFromMeshesWithAttrs(ctx, new_meshes);
}
MeshSet<3> *meshSetFromTwoMeshes(UnionIntersectionContext *ctx,
const std::vector<MeshSet<3>::mesh_t*> &left_meshes,
const std::vector<MeshSet<3>::mesh_t*> &right_meshes)
{
std::vector<MeshSet<3>::mesh_t*> new_meshes;
copyMeshes(left_meshes, &new_meshes);
copyMeshes(right_meshes, &new_meshes);
return newMeshSetFromMeshesWithAttrs(ctx, new_meshes);
}
bool checkEdgeFaceIntersections_do(Intersections &intersections,
MeshSet<3>::face_t *face_a,
MeshSet<3>::edge_t *edge_b)
{
if (intersections.intersects(edge_b, face_a))
return true;
carve::mesh::MeshSet<3>::vertex_t::vector_t _p;
if (face_a->simpleLineSegmentIntersection(carve::geom3d::LineSegment(edge_b->v1()->v, edge_b->v2()->v), _p))
return true;
return false;
}
bool checkEdgeFaceIntersections(Intersections &intersections,
MeshSet<3>::face_t *face_a,
MeshSet<3>::face_t *face_b)
{
MeshSet<3>::edge_t *edge_b;
edge_b = face_b->edge;
do {
if (checkEdgeFaceIntersections_do(intersections, face_a, edge_b))
return true;
edge_b = edge_b->next;
} while (edge_b != face_b->edge);
return false;
}
inline bool facesAreCoplanar(const MeshSet<3>::face_t *a, const MeshSet<3>::face_t *b)
{
carve::geom3d::Ray temp;
// XXX: Find a better definition. This may be a source of problems
// if floating point inaccuracies cause an incorrect answer.
return !carve::geom3d::planeIntersection(a->plane, b->plane, temp);
}
bool checkMeshSetInterseciton_do(Intersections &intersections,
const RTreeNode<3, Face<3> *> *a_node,
const RTreeNode<3, Face<3> *> *b_node,
bool descend_a = true)
{
if (!a_node->bbox.intersects(b_node->bbox)) {
return false;
}
if (a_node->child && (descend_a || !b_node->child)) {
for (RTreeNode<3, Face<3> *> *node = a_node->child; node; node = node->sibling) {
if (checkMeshSetInterseciton_do(intersections, node, b_node, false)) {
return true;
}
}
}
else if (b_node->child) {
for (RTreeNode<3, Face<3> *> *node = b_node->child; node; node = node->sibling) {
if (checkMeshSetInterseciton_do(intersections, a_node, node, true)) {
return true;
}
}
}
else {
for (size_t i = 0; i < a_node->data.size(); ++i) {
MeshSet<3>::face_t *fa = a_node->data[i];
aabb<3> aabb_a = fa->getAABB();
if (aabb_a.maxAxisSeparation(b_node->bbox) > carve::EPSILON) {
continue;
}
for (size_t j = 0; j < b_node->data.size(); ++j) {
MeshSet<3>::face_t *fb = b_node->data[j];
aabb<3> aabb_b = fb->getAABB();
if (aabb_b.maxAxisSeparation(aabb_a) > carve::EPSILON) {
continue;
}
std::pair<double, double> a_ra = fa->rangeInDirection(fa->plane.N, fa->edge->vert->v);
std::pair<double, double> b_ra = fb->rangeInDirection(fa->plane.N, fa->edge->vert->v);
if (carve::rangeSeparation(a_ra, b_ra) > carve::EPSILON) {
continue;
}
std::pair<double, double> a_rb = fa->rangeInDirection(fb->plane.N, fb->edge->vert->v);
std::pair<double, double> b_rb = fb->rangeInDirection(fb->plane.N, fb->edge->vert->v);
if (carve::rangeSeparation(a_rb, b_rb) > carve::EPSILON) {
continue;
}
if (!facesAreCoplanar(fa, fb)) {
if (checkEdgeFaceIntersections(intersections, fa, fb)) {
return true;
}
}
}
}
}
return false;
}
bool checkMeshSetInterseciton(RTreeNode<3, Face<3> *> *rtree_a, RTreeNode<3, Face<3> *> *rtree_b)
{
Intersections intersections;
return checkMeshSetInterseciton_do(intersections, rtree_a, rtree_b);
}
void getIntersectedOperandMeshes(std::vector<MeshSet<3>::mesh_t*> *meshes,
const MeshSet<3>::aabb_t &otherAABB,
std::vector<MeshSet<3>::mesh_t*> *operandMeshes,
RTreeCache *rtree_cache,
IntersectCache *intersect_cache)
{
std::vector<MeshSet<3>::mesh_t*>::iterator it = meshes->begin();
std::vector< RTreeNode<3, Face<3> *> *> meshRTree;
while (it != meshes->end()) {
MeshSet<3>::mesh_t *mesh = *it;
bool isAdded = false;
RTreeNode<3, Face<3> *> *rtree;
bool intersects;
RTreeCache::iterator rtree_found = rtree_cache->find(mesh);
if (rtree_found != rtree_cache->end()) {
rtree = rtree_found->second;
}
else {
rtree = RTreeNode<3, Face<3> *>::construct_STR(mesh->faces.begin(), mesh->faces.end(), 4, 4);
(*rtree_cache)[mesh] = rtree;
}
IntersectCache::iterator intersect_found = intersect_cache->find(mesh);
if (intersect_found != intersect_cache->end()) {
intersects = intersect_found->second;
}
else {
intersects = rtree->bbox.intersects(otherAABB);
(*intersect_cache)[mesh] = intersects;
}
if (intersects) {
bool isIntersect = false;
std::vector<MeshSet<3>::mesh_t*>::iterator operand_it = operandMeshes->begin();
std::vector<RTreeNode<3, Face<3> *> *>::iterator tree_it = meshRTree.begin();
for (; operand_it!=operandMeshes->end(); operand_it++, tree_it++) {
RTreeNode<3, Face<3> *> *operandRTree = *tree_it;
if (checkMeshSetInterseciton(rtree, operandRTree)) {
isIntersect = true;
break;
}
}
if (!isIntersect) {
operandMeshes->push_back(mesh);
meshRTree.push_back(rtree);
it = meshes->erase(it);
isAdded = true;
}
}
if (!isAdded) {
//delete rtree;
it++;
}
}
std::vector<RTreeNode<3, Face<3> *> *>::iterator tree_it = meshRTree.begin();
for (; tree_it != meshRTree.end(); tree_it++) {
//delete *tree_it;
}
}
MeshSet<3> *getIntersectedOperand(UnionIntersectionContext *ctx,
std::vector<MeshSet<3>::mesh_t*> *meshes,
const MeshSet<3>::aabb_t &otherAABB,
RTreeCache *rtree_cache,
IntersectCache *intersect_cache)
{
std::vector<MeshSet<3>::mesh_t*> operandMeshes;
getIntersectedOperandMeshes(meshes, otherAABB, &operandMeshes, rtree_cache, intersect_cache);
if (operandMeshes.size() == 0)
return NULL;
return meshSetFromMeshes(ctx, operandMeshes);
}
MeshSet<3> *unionIntersectingMeshes(carve::csg::CSG *csg,
MeshSet<3> *poly,
const MeshSet<3> *other_poly,
const MeshSet<3>::aabb_t &otherAABB,
VertexAttrsCallback vertex_attr_callback,
UnionIntersectionsCallback callback,
void *user_data)
{
if (poly->meshes.size() <= 1) {
return poly;
}
std::vector<MeshSet<3>::mesh_t*> orig_meshes =
std::vector<MeshSet<3>::mesh_t*>(poly->meshes.begin(), poly->meshes.end());
RTreeCache rtree_cache;
IntersectCache intersect_cache;
UnionIntersectionContext ctx;
ctx.vertex_attr_callback = vertex_attr_callback;
ctx.user_data = user_data;
MeshSet<3> *left = getIntersectedOperand(&ctx,
&orig_meshes,
otherAABB,
&rtree_cache,
&intersect_cache);
if (!left) {
// No maniforlds which intersects another object at all.
return poly;
}
while (orig_meshes.size()) {
MeshSet<3> *right = getIntersectedOperand(&ctx,
&orig_meshes,
otherAABB,
&rtree_cache,
&intersect_cache);
if (!right) {
// No more intersecting manifolds which intersects other object
break;
}
try {
if (left->meshes.size()==0) {
delete left;
left = right;
}
else {
MeshSet<3> *result = csg->compute(left, right,
carve::csg::CSG::UNION,
NULL, carve::csg::CSG::CLASSIFY_EDGE);
callback(result, other_poly, user_data);
delete left;
delete right;
left = result;
}
}
catch (carve::exception e) {
std::cerr << "CSG failed, exception " << e.str() << std::endl;
MeshSet<3> *result = meshSetFromTwoMeshes(&ctx,
left->meshes,
right->meshes);
callback(result, other_poly, user_data);
delete left;
delete right;
left = result;
}
catch (...) {
delete left;
delete right;
throw "Unknown error in Carve library";
}
}
for (RTreeCache::iterator it = rtree_cache.begin();
it != rtree_cache.end();
it++)
{
delete it->second;
}
// Append all meshes which doesn't have intersection with another operand as-is.
if (orig_meshes.size()) {
MeshSet<3> *result = meshSetFromTwoMeshes(&ctx,
left->meshes,
orig_meshes);
delete left;
left = result;
}
return left;
}
} // namespace
// TODO(sergey): This function is to be totally re-implemented to make it
// more clear what's going on and hopefully optimize it as well.
void carve_unionIntersections(carve::csg::CSG *csg,
MeshSet<3> **left_r,
MeshSet<3> **right_r,
VertexAttrsCallback vertex_attr_callback,
UnionIntersectionsCallback callback,
void *user_data)
{
MeshSet<3> *left = *left_r, *right = *right_r;
if (left->meshes.size() == 1 && right->meshes.size() == 0) {
return;
}
MeshSet<3>::aabb_t leftAABB = left->getAABB();
MeshSet<3>::aabb_t rightAABB = right->getAABB();;
left = unionIntersectingMeshes(csg, left, right, rightAABB,
vertex_attr_callback, callback, user_data);
right = unionIntersectingMeshes(csg, right, left, leftAABB,
vertex_attr_callback, callback, user_data);
if (left != *left_r) {
delete *left_r;
}
if (right != *right_r) {
delete *right_r;
}
*left_r = left;
*right_r = right;
}
static inline void add_newell_cross_v3_v3v3(const Vector &v_prev,
const Vector &v_curr,
Vector *n)
{
(*n)[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]);
(*n)[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]);
(*n)[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]);
}
// Axis matrix is being set for non-flat ngons only.
bool carve_checkPolyPlanarAndGetNormal(const std::vector<MeshSet<3>::vertex_t> &vertex_storage,
const int verts_per_poly,
const int *verts_of_poly,
Matrix3 *axis_matrix_r)
{
if (verts_per_poly == 3) {
// Triangles are always planar.
return true;
}
else if (verts_per_poly == 4) {
// Presumably faster than using generig n-gon check for quads.
const Vector &v1 = vertex_storage[verts_of_poly[0]].v,
&v2 = vertex_storage[verts_of_poly[1]].v,
&v3 = vertex_storage[verts_of_poly[2]].v,
&v4 = vertex_storage[verts_of_poly[3]].v;
Vector vec1, vec2, vec3, cross;
vec1 = v2 - v1;
vec2 = v4 - v1;
vec3 = v3 - v1;
cross = carve::geom::cross(vec1, vec2);
double production = carve::geom::dot(cross, vec3);
// TODO(sergey): Check on whether we could have length-independent
// magnitude here.
double magnitude = 1e-3 * cross.length2();
return fabs(production) < magnitude;
}
else {
const Vector *vert_prev = &vertex_storage[verts_of_poly[verts_per_poly - 1]].v;
const Vector *vert_curr = &vertex_storage[verts_of_poly[0]].v;
Vector normal = carve::geom::VECTOR(0.0, 0.0, 0.0);
for (int i = 0; i < verts_per_poly; i++) {
add_newell_cross_v3_v3v3(*vert_prev, *vert_curr, &normal);
vert_prev = vert_curr;
vert_curr = &vertex_storage[verts_of_poly[(i + 1) % verts_per_poly]].v;
}
if (normal.length2() < FLT_EPSILON) {
// Degenerated face, couldn't triangulate properly anyway.
return true;
}
else {
double magnitude = normal.length2();
normal.normalize();
axis_dominant_v3_to_m3__bli(axis_matrix_r, normal);
Vector first_projected = *axis_matrix_r * vertex_storage[verts_of_poly[0]].v;
double min_z = first_projected[2], max_z = first_projected[2];
for (int i = 1; i < verts_per_poly; i++) {
const Vector &vertex = vertex_storage[verts_of_poly[i]].v;
Vector projected = *axis_matrix_r * vertex;
if (projected[2] < min_z) {
min_z = projected[2];
}
if (projected[2] > max_z) {
max_z = projected[2];
}
}
if (std::abs(min_z - max_z) > FLT_EPSILON * magnitude) {
return false;
}
}
return true;
}
return false;
}
namespace {
int triangulateNGon_carveTriangulator(const std::vector<MeshSet<3>::vertex_t> &vertex_storage,
const int verts_per_poly,
const int *verts_of_poly,
const Matrix3 &axis_matrix,
std::vector<tri_idx> *triangles)
{
// Project vertices to 2D plane.
Vector projected;
std::vector<carve::geom::vector<2> > poly_2d;
poly_2d.reserve(verts_per_poly);
for (int i = 0; i < verts_per_poly; ++i) {
projected = axis_matrix * vertex_storage[verts_of_poly[i]].v;
poly_2d.push_back(carve::geom::VECTOR(projected[0], projected[1]));
}
carve::triangulate::triangulate(poly_2d, *triangles);
carve::triangulate::improve(poly_2d, *triangles);
return triangles->size();
}
int triangulateNGon_importerTriangulator(struct ImportMeshData *import_data,
CarveMeshImporter *mesh_importer,
const std::vector<MeshSet<3>::vertex_t> &vertex_storage,
const int verts_per_poly,
const int *verts_of_poly,
const Matrix3 &axis_matrix,
std::vector<tri_idx> *triangles)
{
typedef float Vector2D[2];
typedef unsigned int Triangle[3];
// Project vertices to 2D plane.
Vector2D *poly_2d = new Vector2D[verts_per_poly];
Vector projected;
for (int i = 0; i < verts_per_poly; ++i) {
projected = axis_matrix * vertex_storage[verts_of_poly[i]].v;
poly_2d[i][0] = projected[0];
poly_2d[i][1] = projected[1];
}
Triangle *api_triangles = new Triangle[verts_per_poly - 2];
int num_triangles =
mesh_importer->triangulate2DPoly(import_data,
poly_2d,
verts_per_poly,
api_triangles);
triangles->reserve(num_triangles);
for (int i = 0; i < num_triangles; ++i) {
triangles->push_back(tri_idx(api_triangles[i][0],
api_triangles[i][1],
api_triangles[i][2]));
}
delete [] poly_2d;
delete [] api_triangles;
return num_triangles;
}
template <typename T>
void sortThreeNumbers(T &a, T &b, T &c)
{
if (a > b)
std::swap(a, b);
if (b > c)
std::swap(b, c);
if (a > b)
std::swap(a, b);
}
bool pushTriangle(int v1, int v2, int v3,
std::vector<int> *face_indices,
TrianglesStorage *triangles_storage)
{
tri_idx triangle(v1, v2, v3);
sortThreeNumbers(triangle.a, triangle.b, triangle.c);
assert(triangle.a < triangle.b);
assert(triangle.b < triangle.c);
if (triangles_storage->find(triangle) == triangles_storage->end()) {
face_indices->push_back(v1);
face_indices->push_back(v2);
face_indices->push_back(v3);
triangles_storage->insert(triangle);
return true;
}
else {
return false;
}
}
} // namespace
int carve_triangulatePoly(struct ImportMeshData *import_data,
CarveMeshImporter *mesh_importer,
const std::vector<MeshSet<3>::vertex_t> &vertex_storage,
const int verts_per_poly,
const int *verts_of_poly,
const Matrix3 &axis_matrix,
std::vector<int> *face_indices,
TrianglesStorage *triangles_storage)
{
int num_triangles = 0;
assert(verts_per_poly > 3);
if (verts_per_poly == 4) {
// Quads we triangulate by 1-3 diagonal, it is an original behavior
// of boolean modifier.
//
// TODO(sergey): Consider using shortest diagonal here. However
// display code in Blende use static 1-3 split, so some experiments
// are needed here.
if (pushTriangle(verts_of_poly[0],
verts_of_poly[1],
verts_of_poly[2],
face_indices,
triangles_storage))
{
num_triangles++;
}
if (pushTriangle(verts_of_poly[0],
verts_of_poly[2],
verts_of_poly[3],
face_indices,
triangles_storage))
{
num_triangles++;
}
}
else {
std::vector<tri_idx> triangles;
triangles.reserve(verts_per_poly - 2);
// Make triangulator callback optional so we could do some tests
// in the future.
if (mesh_importer->triangulate2DPoly) {
triangulateNGon_importerTriangulator(import_data,
mesh_importer,
vertex_storage,
verts_per_poly,
verts_of_poly,
axis_matrix,
&triangles);
}
else {
triangulateNGon_carveTriangulator(vertex_storage,
verts_per_poly,
verts_of_poly,
axis_matrix,
&triangles);
}
for (int i = 0; i < triangles.size(); ++i) {
int v1 = triangles[i].a,
v2 = triangles[i].b,
v3 = triangles[i].c;
// Sanity check of the triangle.
assert(v1 != v2);
assert(v1 != v3);
assert(v2 != v3);
assert(v1 < verts_per_poly);
assert(v2 < verts_per_poly);
assert(v3 < verts_per_poly);
if (pushTriangle(verts_of_poly[v1],
verts_of_poly[v2],
verts_of_poly[v3],
face_indices,
triangles_storage))
{
num_triangles++;
}
}
}
return num_triangles;
}

300
extern/carve/carve-util.h vendored Normal file
View File

@@ -0,0 +1,300 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2014 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __CARVE_UTIL_H__
#define __CARVE_UTIL_H__
#include <carve/csg.hpp>
#include <carve/geom3d.hpp>
#include <carve/interpolator.hpp>
#include <carve/mesh.hpp>
#include <carve/triangulator.hpp>
#include "carve-capi.h"
struct TriIdxCompare {
bool operator() (const carve::triangulate::tri_idx &left,
const carve::triangulate::tri_idx &right) const {
if (left.a < right.a) {
return true;
}
else if (left.a > right.a) {
return false;
}
if (left.b < right.b) {
return true;
}
else if (left.b > right.b) {
return false;
}
if (left.c < right.c) {
return true;
}
else if (left.c > right.c) {
return false;
}
return false;
}
};
typedef std::set<carve::triangulate::tri_idx, TriIdxCompare> TrianglesStorage;
void carve_getRescaleMinMax(const carve::mesh::MeshSet<3> *left,
const carve::mesh::MeshSet<3> *right,
carve::geom3d::Vector *min,
carve::geom3d::Vector *max);
typedef void (*VertexAttrsCallback) (const carve::mesh::MeshSet<3>::vertex_t *orig_vert,
const carve::mesh::MeshSet<3>::vertex_t *new_vert,
void *userdata);
typedef void (*UnionIntersectionsCallback) (const carve::mesh::MeshSet<3> *left,
const carve::mesh::MeshSet<3> *right,
void *userdata);
void carve_unionIntersections(carve::csg::CSG *csg,
carve::mesh::MeshSet<3> **left_r,
carve::mesh::MeshSet<3> **right_r,
VertexAttrsCallback vertex_attr_callback,
UnionIntersectionsCallback callback,
void *user_data);
bool carve_checkPolyPlanarAndGetNormal(const std::vector<carve::mesh::MeshSet<3>::vertex_t> &vertex_storage,
const int verts_per_poly,
const int *verts_of_poly,
carve::math::Matrix3 *axis_matrix_r);
int carve_triangulatePoly(struct ImportMeshData *import_data,
CarveMeshImporter *mesh_importer,
const std::vector<carve::mesh::MeshSet<3>::vertex_t> &vertex_storage,
const int verts_per_poly,
const int *verts_of_poly,
const carve::math::Matrix3 &axis_matrix,
std::vector<int> *face_indices,
TrianglesStorage *triangles_storage);
namespace carve {
namespace interpolate {
template<typename attr_t>
class VertexAttr : public Interpolator {
public:
typedef const meshset_t::vertex_t *key_t;
protected:
typedef std::unordered_map<key_t, attr_t> attrmap_t;
attrmap_t attrs;
virtual void resultFace(const carve::csg::CSG &csg,
const meshset_t::face_t *new_face,
const meshset_t::face_t *orig_face,
bool flipped)
{
typedef meshset_t::face_t::const_edge_iter_t const_edge_iter_t;
for (const_edge_iter_t new_edge_iter = new_face->begin();
new_edge_iter != new_face->end();
++new_edge_iter)
{
typename attrmap_t::const_iterator found =
attrs.find(new_edge_iter->vert);
if (found == attrs.end()) {
for (const_edge_iter_t orig_edge_iter = orig_face->begin();
orig_edge_iter != orig_face->end();
++orig_edge_iter)
{
if ((orig_edge_iter->vert->v - new_edge_iter->vert->v).length2() < 1e-5) {
attrs[new_edge_iter->vert] = attrs[orig_edge_iter->vert];
}
}
}
}
}
public:
bool hasAttribute(const meshset_t::vertex_t *v) {
return attrs.find(v) != attrs.end();
}
const attr_t &getAttribute(const meshset_t::vertex_t *v, const attr_t &def = attr_t()) {
typename attrmap_t::const_iterator found = attrs.find(v);
if (found != attrs.end()) {
return found->second;
}
return def;
}
void setAttribute(const meshset_t::vertex_t *v, const attr_t &attr) {
attrs[v] = attr;
}
void removeAttribute(const meshset_t::vertex_t *v) {
typename attrmap_t::iterator it = attrs.find(v);
if (it != attrs.end()) {
attrs.erase(it);
}
}
};
template<typename attr_t>
class SimpleFaceEdgeAttr : public Interpolator {
public:
typedef std::pair<const meshset_t::face_t *, unsigned> key_t;
protected:
typedef std::pair<const meshset_t::vertex_t *, const meshset_t::vertex_t *> vpair_t;
struct key_hash {
size_t operator()(const key_t &v) const {
return size_t(v.first) ^ size_t(v.second);
}
};
struct vpair_hash {
size_t operator()(const vpair_t &v) const {
return size_t(v.first) ^ size_t(v.second);
}
};
typedef std::unordered_map<key_t, attr_t, key_hash> attrmap_t;
typedef std::unordered_map<vpair_t, key_t, vpair_hash> edgedivmap_t;
attrmap_t attrs;
struct Hook : public Interpolator::Hook {
public:
virtual unsigned hookBits() const {
return carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT;
}
Hook(Interpolator *_interpolator, const carve::csg::CSG &_csg) : Interpolator::Hook(_interpolator, _csg) {
}
virtual ~Hook() {
}
};
virtual Interpolator::Hook *makeHook(carve::csg::CSG &csg) {
return new Hook(this, csg);
}
virtual void processOutputFace(const carve::csg::CSG &csg,
std::vector<carve::mesh::MeshSet<3>::face_t *> &new_faces,
const meshset_t::face_t *orig_face,
bool flipped) {
edgedivmap_t undiv;
for (meshset_t::face_t::const_edge_iter_t e = orig_face->begin(); e != orig_face->end(); ++e) {
key_t k(orig_face, e.idx());
typename attrmap_t::const_iterator attr_i = attrs.find(k);
if (attr_i == attrs.end()) {
continue;
} else {
undiv[vpair_t(e->v1(), e->v2())] = k;
}
}
for (size_t fnum = 0; fnum < new_faces.size(); ++fnum) {
const carve::mesh::MeshSet<3>::face_t *new_face = new_faces[fnum];
for (meshset_t::face_t::const_edge_iter_t e = new_face->begin(); e != new_face->end(); ++e) {
key_t k(new_face, e.idx());
vpair_t vp;
if (!flipped) {
vp = vpair_t(e->v1(), e->v2());
} else {
vp = vpair_t(e->v2(), e->v1());
}
typename edgedivmap_t::const_iterator vp_i;
if ((vp_i = undiv.find(vp)) != undiv.end()) {
attrs[k] = attrs[vp_i->second];
}
}
}
}
public:
bool hasAttribute(const meshset_t::face_t *f, unsigned e) {
return attrs.find(std::make_pair(f, e)) != attrs.end();
}
attr_t getAttribute(const meshset_t::face_t *f, unsigned e, const attr_t &def = attr_t()) {
typename attrmap_t::const_iterator fv = attrs.find(std::make_pair(f, e));
if (fv != attrs.end()) {
return (*fv).second;
}
return def;
}
void setAttribute(const meshset_t::face_t *f, unsigned e, const attr_t &attr) {
attrs[std::make_pair(f, e)] = attr;
}
void copyAttribute(const meshset_t::face_t *face,
unsigned edge,
SimpleFaceEdgeAttr<attr_t> *interpolator) {
key_t key(face, edge);
typename attrmap_t::const_iterator fv = interpolator->attrs.find(key);
if (fv != interpolator->attrs.end()) {
attrs[key] = (*fv).second;
}
}
void swapAttributes(SimpleFaceEdgeAttr<attr_t> *interpolator) {
attrs.swap(interpolator->attrs);
}
SimpleFaceEdgeAttr() : Interpolator() {
}
virtual ~SimpleFaceEdgeAttr() {
}
};
template<typename attr_t>
class SwapableFaceEdgeAttr : public FaceEdgeAttr<attr_t> {
public:
typedef carve::mesh::MeshSet<3> meshset_t;
void copyAttribute(const meshset_t::face_t *face,
unsigned edge,
SwapableFaceEdgeAttr<attr_t> *interpolator) {
typename FaceEdgeAttr<attr_t>::key_t key(face, edge);
typename FaceEdgeAttr<attr_t>::attrmap_t::const_iterator fv = interpolator->attrs.find(key);
if (fv != interpolator->attrs.end()) {
this->attrs[key] = (*fv).second;
}
}
void swapAttributes(SwapableFaceEdgeAttr<attr_t> *interpolator) {
this->attrs.swap(interpolator->attrs);
}
};
} // namespace interpolate
} // namespace carve
#endif // __CARVE_UTIL_H__

107
extern/carve/files.txt vendored Normal file
View File

@@ -0,0 +1,107 @@
include/carve/edge_impl.hpp
include/carve/tag.hpp
include/carve/colour.hpp
include/carve/math_constants.hpp
include/carve/csg.hpp
include/carve/heap.hpp
include/carve/vector.hpp
include/carve/djset.hpp
include/carve/mesh_impl.hpp
include/carve/polyline_iter.hpp
include/carve/input.hpp
include/carve/geom2d.hpp
include/carve/aabb_impl.hpp
include/carve/geom.hpp
include/carve/triangulator.hpp
include/carve/pointset_iter.hpp
include/carve/spacetree.hpp
include/carve/vertex_impl.hpp
include/carve/vcpp_config.h
include/carve/octree_decl.hpp
include/carve/rescale.hpp
include/carve/collection_types.hpp
include/carve/faceloop.hpp
include/carve/polyhedron_base.hpp
include/carve/vertex_decl.hpp
include/carve/cbrt.h
include/carve/matrix.hpp
include/carve/tree.hpp
include/carve/debug_hooks.hpp
include/carve/rtree.hpp
include/carve/math.hpp
include/carve/convex_hull.hpp
include/carve/polyline.hpp
include/carve/geom3d.hpp
include/carve/aabb.hpp
include/carve/pointset_decl.hpp
include/carve/intersection.hpp
include/carve/face_impl.hpp
include/carve/collection.hpp
include/carve/poly_impl.hpp
include/carve/exact.hpp
include/carve/timing.hpp
include/carve/poly.hpp
include/carve/mesh.hpp
include/carve/win32.h
include/carve/mesh_simplify.hpp
include/carve/classification.hpp
include/carve/collection/unordered/fallback_impl.hpp
include/carve/collection/unordered/std_impl.hpp
include/carve/collection/unordered/vcpp_impl.hpp
include/carve/collection/unordered/boost_impl.hpp
include/carve/collection/unordered/libstdcpp_impl.hpp
include/carve/collection/unordered/tr1_impl.hpp
include/carve/collection/unordered.hpp
include/carve/pointset.hpp
include/carve/mesh_ops.hpp
include/carve/triangle_intersection.hpp
include/carve/octree_impl.hpp
include/carve/pointset_impl.hpp
include/carve/carve.hpp
include/carve/kd_node.hpp
include/carve/polyhedron_impl.hpp
include/carve/interpolator.hpp
include/carve/edge_decl.hpp
include/carve/face_decl.hpp
include/carve/geom_impl.hpp
include/carve/util.hpp
include/carve/random/random.h
include/carve/gnu_cxx.h
include/carve/polyline_decl.hpp
include/carve/triangulator_impl.hpp
include/carve/iobj.hpp
include/carve/csg_triangulator.hpp
include/carve/polyline_impl.hpp
include/carve/poly_decl.hpp
include/carve/polyhedron_decl.hpp
lib/math.cpp
lib/intersect_classify_edge.cpp
lib/csg_detail.hpp
lib/polyhedron.cpp
lib/csg.cpp
lib/intersect.cpp
lib/csg_data.hpp
lib/intersection.cpp
lib/timing.cpp
lib/intersect_classify_common_impl.hpp
lib/geom2d.cpp
lib/csg_collector.hpp
lib/mesh.cpp
lib/intersect_half_classify_group.cpp
lib/octree.cpp
lib/csg_collector.cpp
lib/intersect_debug.hpp
lib/intersect_classify_common.hpp
lib/geom3d.cpp
lib/intersect_face_division.cpp
lib/face.cpp
lib/triangulator.cpp
lib/tag.cpp
lib/intersect_classify_group.cpp
lib/polyline.cpp
lib/intersect_common.hpp
lib/convex_hull.cpp
lib/intersect_group.cpp
lib/carve.cpp
lib/pointset.cpp
lib/intersect_debug.cpp

156
extern/carve/include/carve/aabb.hpp vendored Normal file
View File

@@ -0,0 +1,156 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom.hpp>
#include <vector>
namespace carve {
namespace geom {
// n-dimensional AABB
template<unsigned ndim>
struct aabb {
typedef vector<ndim> vector_t;
typedef aabb<ndim> aabb_t;
vector_t pos; // the centre of the AABB
vector_t extent; // the extent of the AABB - the vector from the centre to the maximal vertex.
void empty();
bool isEmpty() const;
void fit(const vector_t &v1);
void fit(const vector_t &v1, const vector_t &v2);
void fit(const vector_t &v1, const vector_t &v2, const vector_t &v3);
template<typename iter_t, typename value_type>
void _fit(iter_t begin, iter_t end, value_type);
template<typename iter_t>
void _fit(iter_t begin, iter_t end, vector_t);
template<typename iter_t>
void _fit(iter_t begin, iter_t end, aabb_t);
template<typename iter_t>
void fit(iter_t begin, iter_t end);
template<typename iter_t, typename adapt_t>
void fit(iter_t begin, iter_t end, adapt_t adapt);
void unionAABB(const aabb<ndim> &a);
void expand(double pad);
bool completelyContains(const aabb<ndim> &other) const;
bool containsPoint(const vector_t &v) const;
bool intersectsLineSegment(const vector_t &v1, const vector_t &v2) const;
double axisSeparation(const aabb<ndim> &other, unsigned axis) const;
double maxAxisSeparation(const aabb<ndim> &other) const;
bool intersects(const aabb<ndim> &other) const;
bool intersects(const sphere<ndim> &s) const;
bool intersects(const plane<ndim> &plane) const;
bool intersects(const ray<ndim> &ray) const;
bool intersects(tri<ndim> tri) const;
bool intersects(const linesegment<ndim> &ls) const;
std::pair<double, double> rangeInDirection(const carve::geom::vector<ndim> &v) const;
vector_t min() const;
vector_t mid() const;
vector_t max() const;
double min(unsigned dim) const;
double mid(unsigned dim) const;
double max(unsigned dim) const;
double volume() const;
int compareAxis(const axis_pos &ap) const;
void constrainMax(const axis_pos &ap);
void constrainMin(const axis_pos &ap);
aabb getAABB() const;
aabb(const vector_t &_pos = vector_t::ZERO(),
const vector_t &_extent = vector_t::ZERO());
template<typename iter_t, typename adapt_t>
aabb(iter_t begin, iter_t end, adapt_t adapt);
template<typename iter_t>
aabb(iter_t begin, iter_t end);
aabb(const aabb<ndim> &a, const aabb<ndim> &b);
};
template<unsigned ndim>
bool operator==(const aabb<ndim> &a, const aabb<ndim> &b);
template<unsigned ndim>
bool operator!=(const aabb<ndim> &a, const aabb<ndim> &b);
template<unsigned ndim>
std::ostream &operator<<(std::ostream &o, const aabb<ndim> &a);
template<unsigned ndim>
double distance2(const aabb<3> &a, const vector<ndim> &v);
template<unsigned ndim>
double distance(const aabb<3> &a, const vector<ndim> &v);
template<unsigned ndim, typename obj_t>
struct get_aabb {
aabb<ndim> operator()(const obj_t &obj) const {
return obj.getAABB();
}
};
template<unsigned ndim, typename obj_t>
struct get_aabb<ndim, obj_t *> {
aabb<ndim> operator()(const obj_t *obj) const {
return obj->getAABB();
}
};
}
}
namespace carve {
namespace geom3d {
typedef carve::geom::aabb<3> AABB;
}
}
#include <carve/aabb_impl.hpp>

440
extern/carve/include/carve/aabb_impl.hpp vendored Normal file
View File

@@ -0,0 +1,440 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/vector.hpp>
#include <carve/geom3d.hpp>
#include <carve/geom.hpp>
#include <vector>
namespace carve {
namespace geom {
template<unsigned ndim>
void aabb<ndim>::empty() {
pos.setZero();
extent.setZero();
}
template<unsigned ndim>
bool aabb<ndim>::isEmpty() const {
return extent.exactlyZero();
}
template<unsigned ndim>
template<typename iter_t, typename value_type>
void aabb<ndim>::_fit(iter_t begin, iter_t end, value_type) {
if (begin == end) {
empty();
return;
}
vector_t min, max;
aabb<ndim> a = get_aabb<ndim, value_type>()(*begin); ++begin;
min = a.min();
max = a.max();
while (begin != end) {
aabb<ndim> a = get_aabb<ndim, value_type>()(*begin); ++begin;
assign_op(min, min, a.min(), carve::util::min_functor());
assign_op(max, max, a.max(), carve::util::max_functor());
}
pos = (min + max) / 2.0;
assign_op(extent, max - pos, pos - min, carve::util::max_functor());
}
template<unsigned ndim>
template<typename iter_t>
void aabb<ndim>::_fit(iter_t begin, iter_t end, vector_t) {
if (begin == end) {
empty();
return;
}
vector_t min, max;
bounds(begin, end, min, max);
pos = (min + max) / 2.0;
assign_op(extent, max - pos, pos - min, carve::util::max_functor());
}
template<unsigned ndim>
template<typename iter_t>
void aabb<ndim>::_fit(iter_t begin, iter_t end, aabb_t) {
if (begin == end) {
empty();
return;
}
vector_t min, max;
aabb<ndim> a = *begin++;
min = a.min();
max = a.max();
while (begin != end) {
aabb<ndim> a = *begin; ++begin;
assign_op(min, min, a.min(), carve::util::min_functor());
assign_op(max, max, a.max(), carve::util::max_functor());
}
pos = (min + max) / 2.0;
assign_op(extent, max - pos, pos - min, carve::util::max_functor());
}
template<unsigned ndim>
void aabb<ndim>::fit(const vector_t &v1) {
pos = v1;
extent.setZero();
}
template<unsigned ndim>
void aabb<ndim>::fit(const vector_t &v1, const vector_t &v2) {
vector_t min, max;
assign_op(min, v1, v2, carve::util::min_functor());
assign_op(max, v1, v2, carve::util::max_functor());
pos = (min + max) / 2.0;
assign_op(extent, max - pos, pos - min, carve::util::max_functor());
}
template<unsigned ndim>
void aabb<ndim>::fit(const vector_t &v1, const vector_t &v2, const vector_t &v3) {
vector_t min, max;
min = max = v1;
assign_op(min, min, v2, carve::util::min_functor());
assign_op(max, max, v2, carve::util::max_functor());
assign_op(min, min, v3, carve::util::min_functor());
assign_op(max, max, v3, carve::util::max_functor());
pos = (min + max) / 2.0;
assign_op(extent, max - pos, pos - min, carve::util::max_functor());
}
template<unsigned ndim>
template<typename iter_t, typename adapt_t>
void aabb<ndim>::fit(iter_t begin, iter_t end, adapt_t adapt) {
vector_t min, max;
bounds(begin, end, adapt, min, max);
pos = (min + max) / 2.0;
assign_op(extent, max - pos, pos - min, carve::util::max_functor());
}
template<unsigned ndim>
template<typename iter_t>
void aabb<ndim>::fit(iter_t begin, iter_t end) {
_fit(begin, end, typename std::iterator_traits<iter_t>::value_type());
}
template<unsigned ndim>
void aabb<ndim>::expand(double pad) {
extent += pad;
}
template<unsigned ndim>
void aabb<ndim>::unionAABB(const aabb<ndim> &a) {
vector_t vmin, vmax;
assign_op(vmin, min(), a.min(), carve::util::min_functor());
assign_op(vmax, max(), a.max(), carve::util::max_functor());
pos = (vmin + vmax) / 2.0;
assign_op(extent, vmax - pos, pos - vmin, carve::util::max_functor());
}
template<unsigned ndim>
bool aabb<ndim>::completelyContains(const aabb<ndim> &other) const {
for (unsigned i = 0; i < ndim; ++i) {
if (fabs(other.pos.v[i] - pos.v[i]) + other.extent.v[i] > extent.v[i]) return false;
}
return true;
}
template<unsigned ndim>
bool aabb<ndim>::containsPoint(const vector_t &v) const {
for (unsigned i = 0; i < ndim; ++i) {
if (fabs(v.v[i] - pos.v[i]) > extent.v[i]) return false;
}
return true;
}
template<unsigned ndim>
double aabb<ndim>::axisSeparation(const aabb<ndim> &other, unsigned axis) const {
return fabs(other.pos.v[axis] - pos.v[axis]) - extent.v[axis] - other.extent.v[axis];
}
template<unsigned ndim>
double aabb<ndim>::maxAxisSeparation(const aabb<ndim> &other) const {
double m = axisSeparation(other, 0);
for (unsigned i = 1; i < ndim; ++i) {
m = std::max(m, axisSeparation(other, i));
}
return m;
}
template<unsigned ndim>
bool aabb<ndim>::intersects(const aabb<ndim> &other) const {
return maxAxisSeparation(other) <= 0.0;
}
template<unsigned ndim>
bool aabb<ndim>::intersects(const sphere<ndim> &s) const {
double r = 0.0;
for (unsigned i = 0; i < ndim; ++i) {
double t = fabs(s.C[i] - pos[i]) - extent[i]; if (t > 0.0) r += t*t;
}
return r <= s.r*s.r;
}
template<unsigned ndim>
bool aabb<ndim>::intersects(const plane<ndim> &plane) const {
double d1 = fabs(distance(plane, pos));
double d2 = dot(abs(plane.N), extent);
return d1 <= d2;
}
template<unsigned ndim>
bool aabb<ndim>::intersects(const linesegment<ndim> &ls) const {
return intersectsLineSegment(ls.v1, ls.v2);
}
template<unsigned ndim>
std::pair<double, double> aabb<ndim>::rangeInDirection(const carve::geom::vector<ndim> &v) const {
double d1 = dot(v, pos);
double d2 = dot(abs(v), extent);
return std::make_pair(d1 - d2, d1 + d2);
}
template<unsigned ndim>
typename aabb<ndim>::vector_t aabb<ndim>::min() const { return pos - extent; }
template<unsigned ndim>
typename aabb<ndim>::vector_t aabb<ndim>::mid() const { return pos; }
template<unsigned ndim>
typename aabb<ndim>::vector_t aabb<ndim>::max() const { return pos + extent; }
template<unsigned ndim>
double aabb<ndim>::min(unsigned dim) const { return pos.v[dim] - extent.v[dim]; }
template<unsigned ndim>
double aabb<ndim>::mid(unsigned dim) const { return pos.v[dim]; }
template<unsigned ndim>
double aabb<ndim>::max(unsigned dim) const { return pos.v[dim] + extent.v[dim]; }
template<unsigned ndim>
double aabb<ndim>::volume() const {
double v = 1.0;
for (size_t dim = 0; dim < ndim; ++dim) { v *= 2.0 * extent.v[dim]; }
return v;
}
template<unsigned ndim>
int aabb<ndim>::compareAxis(const axis_pos &ap) const {
double p = ap.pos - pos[ap.axis];
if (p > extent[ap.axis]) return -1;
if (p < -extent[ap.axis]) return +1;
return 0;
}
template<unsigned ndim>
void aabb<ndim>::constrainMax(const axis_pos &ap) {
if (pos[ap.axis] + extent[ap.axis] > ap.pos) {
double min = std::min(ap.pos, pos[ap.axis] - extent[ap.axis]);
pos[ap.axis] = (min + ap.pos) / 2.0;
extent[ap.axis] = ap.pos - pos[ap.axis];
}
}
template<unsigned ndim>
void aabb<ndim>::constrainMin(const axis_pos &ap) {
if (pos[ap.axis] - extent[ap.axis] < ap.pos) {
double max = std::max(ap.pos, pos[ap.axis] + extent[ap.axis]);
pos[ap.axis] = (ap.pos + max) / 2.0;
extent[ap.axis] = pos[ap.axis] - ap.pos;
}
}
template<unsigned ndim>
aabb<ndim> aabb<ndim>::getAABB() const {
return *this;
}
template<unsigned ndim>
aabb<ndim>::aabb(const vector_t &_pos,
const vector_t &_extent) : pos(_pos), extent(_extent) {
}
template<unsigned ndim>
template<typename iter_t, typename adapt_t>
aabb<ndim>::aabb(iter_t begin, iter_t end, adapt_t adapt) {
fit(begin, end, adapt);
}
template<unsigned ndim>
template<typename iter_t>
aabb<ndim>::aabb(iter_t begin, iter_t end) {
fit(begin, end);
}
template<unsigned ndim>
aabb<ndim>::aabb(const aabb<ndim> &a, const aabb<ndim> &b) {
fit(a, b);
}
template<unsigned ndim>
bool operator==(const aabb<ndim> &a, const aabb<ndim> &b) {
return a.pos == b.pos && a.extent == b.extent;
}
template<unsigned ndim>
bool operator!=(const aabb<ndim> &a, const aabb<ndim> &b) {
return a.pos != b.pos || a.extent != b.extent;
}
template<unsigned ndim>
std::ostream &operator<<(std::ostream &o, const aabb<ndim> &a) {
o << (a.pos - a.extent) << "--" << (a.pos + a.extent);
return o;
}
template<unsigned ndim>
double distance2(const aabb<3> &a, const vector<ndim> &v) {
double d2 = 0.0;
for (unsigned i = 0; i < ndim; ++i) {
double d = ::fabs(v.v[i] - a.pos.v[i]) - a.extent.v[i];
if (d > 0.0) {
d2 += d * d;
}
}
return d2;
}
template<unsigned ndim>
double distance(const aabb<3> &a, const vector<ndim> &v) {
return ::sqrt(distance2(a, v));
}
template<>
inline bool aabb<3>::intersects(const ray<3> &ray) const {
vector<3> t = pos - ray.v;
double r;
//l.cross(x-axis)?
r = extent.y * fabs(ray.D.z) + extent.z * fabs(ray.D.y);
if (fabs(t.y * ray.D.z - t.z * ray.D.y) > r) return false;
//ray.D.cross(y-axis)?
r = extent.x * fabs(ray.D.z) + extent.z * fabs(ray.D.x);
if (fabs(t.z * ray.D.x - t.x * ray.D.z) > r) return false;
//ray.D.cross(z-axis)?
r = extent.x*fabs(ray.D.y) + extent.y*fabs(ray.D.x);
if (fabs(t.x * ray.D.y - t.y * ray.D.x) > r) return false;
return true;
}
template<>
inline bool aabb<3>::intersectsLineSegment(const vector<3> &v1, const vector<3> &v2) const {
vector<3> half_length = 0.5 * (v2 - v1);
vector<3> t = pos - half_length - v1;
double r;
//do any of the principal axes form a separating axis?
if(fabs(t.x) > extent.x + fabs(half_length.x)) return false;
if(fabs(t.y) > extent.y + fabs(half_length.y)) return false;
if(fabs(t.z) > extent.z + fabs(half_length.z)) return false;
// NOTE: Since the separating axis is perpendicular to the line in
// these last four cases, the line does not contribute to the
// projection.
//line.cross(x-axis)?
r = extent.y * fabs(half_length.z) + extent.z * fabs(half_length.y);
if (fabs(t.y * half_length.z - t.z * half_length.y) > r) return false;
//half_length.cross(y-axis)?
r = extent.x * fabs(half_length.z) + extent.z * fabs(half_length.x);
if (fabs(t.z * half_length.x - t.x * half_length.z) > r) return false;
//half_length.cross(z-axis)?
r = extent.x*fabs(half_length.y) + extent.y*fabs(half_length.x);
if (fabs(t.x * half_length.y - t.y * half_length.x) > r) return false;
return true;
}
template<int Ax, int Ay, int Az, int c>
static inline bool intersectsTriangle_axisTest_3(const aabb<3> &aabb, const tri<3> &tri) {
const int d = (c+1) % 3, e = (c+2) % 3;
const vector<3> a = cross(VECTOR(Ax, Ay, Az), tri.v[d] - tri.v[c]);
double p1 = dot(a, tri.v[c]), p2 = dot(a, tri.v[e]);
if (p1 > p2) std::swap(p1, p2);
const double r = dot(abs(a), aabb.extent);
return !(p1 > r || p2 < -r);
}
template<int c>
static inline bool intersectsTriangle_axisTest_2(const aabb<3> &aabb, const tri<3> &tri) {
double vmin = std::min(std::min(tri.v[0][c], tri.v[1][c]), tri.v[2][c]),
vmax = std::max(std::max(tri.v[0][c], tri.v[1][c]), tri.v[2][c]);
return !(vmin > aabb.extent[c] || vmax < -aabb.extent[c]);
}
static inline bool intersectsTriangle_axisTest_1(const aabb<3> &aabb, const tri<3> &tri) {
vector<3> n = cross(tri.v[1] - tri.v[0], tri.v[2] - tri.v[0]);
double d1 = fabs(dot(n, tri.v[0]));
double d2 = dot(abs(n), aabb.extent);
return d1 <= d2;
}
template<>
inline bool aabb<3>::intersects(tri<3> tri) const {
tri.v[0] -= pos;
tri.v[1] -= pos;
tri.v[2] -= pos;
if (!intersectsTriangle_axisTest_2<0>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_2<1>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_2<2>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_3<1,0,0,0>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_3<1,0,0,1>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_3<1,0,0,2>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_3<0,1,0,0>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_3<0,1,0,1>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_3<0,1,0,2>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_3<0,0,1,0>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_3<0,0,1,1>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_3<0,0,1,2>(*this, tri)) return false;
if (!intersectsTriangle_axisTest_1(*this, tri)) return false;
return true;
}
}
}

238
extern/carve/include/carve/carve.hpp vendored Normal file
View File

@@ -0,0 +1,238 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#if defined(CMAKE_BUILD)
# include <carve/config.h>
#elif defined(XCODE_BUILD)
# include <carve/xcode_config.h>
#elif defined(_MSC_VER)
# include <carve/vcpp_config.h>
#else
# include <carve/config.h>
#endif
#if defined(WIN32)
# include <carve/win32.h>
#elif defined(__GNUC__)
# include <carve/gnu_cxx.h>
#endif
#if defined(CARVE_SYSTEM_BOOST)
# define BOOST_INCLUDE(x) <boost/x>
#else
# define BOOST_INCLUDE(x) <carve/external/boost/x>
#endif
#include <math.h>
#include <string>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <sstream>
#include <iomanip>
#include <carve/collection.hpp>
#include <carve/util.hpp>
#include <stdarg.h>
#define STR(x) #x
#define XSTR(x) STR(x)
/**
* \brief Top level Carve namespace.
*/
namespace carve {
static struct noinit_t {} NOINIT;
inline std::string fmtstring(const char *fmt, ...);
/**
* \brief Base class for all Carve exceptions.
*/
struct exception {
private:
mutable std::string err;
mutable std::ostringstream accum;
public:
exception(const std::string &e) : err(e), accum() { }
exception() : err(), accum() { }
exception(const exception &e) : err(e.str()), accum() { }
exception &operator=(const exception &e) {
if (this != &e) {
err = e.str();
accum.str("");
}
return *this;
}
const std::string &str() const {
if (accum.str().size() > 0) {
err += accum.str();
accum.str("");
}
return err;
}
template<typename T>
exception &operator<<(const T &t) {
accum << t;
return *this;
}
};
template<typename iter_t, typename order_t = std::less<typename std::iterator_traits<iter_t>::value_type > >
struct index_sort {
iter_t base;
order_t order;
index_sort(const iter_t &_base) : base(_base), order() { }
index_sort(const iter_t &_base, const order_t &_order) : base(_base), order(_order) { }
template<typename U>
bool operator()(const U &a, const U &b) {
return order(*(base + a), *(base + b));
}
};
template<typename iter_t, typename order_t>
index_sort<iter_t, order_t> make_index_sort(const iter_t &base, const order_t &order) {
return index_sort<iter_t, order_t>(base, order);
}
template<typename iter_t>
index_sort<iter_t> make_index_sort(const iter_t &base) {
return index_sort<iter_t>(base);
}
enum RayIntersectionClass {
RR_DEGENERATE = -2,
RR_PARALLEL = -1,
RR_NO_INTERSECTION = 0,
RR_INTERSECTION = 1
};
enum LineIntersectionClass {
COLINEAR = -1,
NO_INTERSECTION = 0,
INTERSECTION_LL = 1,
INTERSECTION_PL = 2,
INTERSECTION_LP = 3,
INTERSECTION_PP = 4
};
enum PointClass {
POINT_UNK = -2,
POINT_OUT = -1,
POINT_ON = 0,
POINT_IN = 1,
POINT_VERTEX = 2,
POINT_EDGE = 3
};
enum IntersectionClass {
INTERSECT_BAD = -1,
INTERSECT_NONE = 0,
INTERSECT_FACE = 1,
INTERSECT_VERTEX = 2,
INTERSECT_EDGE = 3,
INTERSECT_PLANE = 4,
};
extern double EPSILON;
extern double EPSILON2;
static inline void setEpsilon(double ep) { EPSILON = ep; EPSILON2 = ep * ep; }
template<typename T>
struct identity_t {
typedef T argument_type;
typedef T result_type;
const T &operator()(const T &t) const { return t; }
};
template<typename iter_t>
inline bool is_sorted(iter_t first, iter_t last) {
if (first == last) return true;
iter_t iter = first;
iter_t next = first; ++next;
for (; next != last; iter = next, ++next) {
if (*next < *iter) {
return false;
}
}
return true;
}
template<typename iter_t,
typename pred_t>
inline bool is_sorted(iter_t first, iter_t last, pred_t pred) {
if (first == last) return true;
iter_t iter = first;
iter_t next = first; ++next;
for (; next != last; iter = next, ++next) {
if (pred(*next, *iter)) {
return false;
}
}
return true;
}
inline double rangeSeparation(const std::pair<double, double> &a,
const std::pair<double, double> &b) {
if (a.second < b.first) {
return b.first - a.second;
} else if (b.second < a.first) {
return a.first - b.second;
} else {
return 0.0;
}
}
}
#if defined(_MSC_VER)
# define MACRO_BEGIN do {
# define MACRO_END __pragma(warning(push)) __pragma(warning(disable:4127)) } while(0) __pragma(warning(pop))
#else
# define MACRO_BEGIN do {
# define MACRO_END } while(0)
#endif
#if !defined(CARVE_NODEBUG)
# define CARVE_ASSERT(x) MACRO_BEGIN if (!(x)) throw carve::exception() << __FILE__ << ":" << __LINE__ << " " << #x; MACRO_END
#else
# define CARVE_ASSERT(X)
#endif
#define CARVE_FAIL(x) MACRO_BEGIN throw carve::exception() << __FILE__ << ":" << __LINE__ << " " << #x; MACRO_END

93
extern/carve/include/carve/cbrt.h vendored Normal file
View File

@@ -0,0 +1,93 @@
// N.B. only appropriate for IEEE doubles.
// Cube root implementation obtained from code with the following notice:
/* @(#)s_cbrt.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/* Sometimes it's necessary to define __LITTLE_ENDIAN explicitly
but these catch some common cases. */
#if defined(i386) || defined(i486) || \
defined(intel) || defined(x86) || defined(i86pc) || \
defined(__alpha) || defined(__osf__)
#define __LITTLE_ENDIAN
#endif
#ifdef __LITTLE_ENDIAN
#define __HI(x) *(1+(int*)&x)
#define __LO(x) *(int*)&x
#define __HIp(x) *(1+(int*)x)
#define __LOp(x) *(int*)x
#else
#define __HI(x) *(int*)&x
#define __LO(x) *(1+(int*)&x)
#define __HIp(x) *(int*)x
#define __LOp(x) *(1+(int*)x)
#endif
/* cbrt(x)
* Return cube root of x
*/
inline double cbrt(double x) {
static const unsigned
B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
static const double
C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */
D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */
F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */
G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */
int hx;
double r,s,t=0.0,w;
unsigned sign;
hx = __HI(x); /* high word of x */
sign=hx&0x80000000; /* sign= sign(x) */
hx ^=sign;
if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
if((hx|__LO(x))==0)
return(x); /* cbrt(0) is itself */
__HI(x) = hx; /* x <- |x| */
/* rough cbrt to 5 bits */
if(hx<0x00100000) /* subnormal number */
{__HI(t)=0x43500000; /* set t= 2**54 */
t*=x; __HI(t)=__HI(t)/3+B2;
}
else
__HI(t)=hx/3+B1;
/* new cbrt to 23 bits, may be implemented in single precision */
r=t*t/x;
s=C+r*t;
t*=G+F/(s+E+D/s);
/* chopped to 20 bits and make it larger than cbrt(x) */
__LO(t)=0; __HI(t)+=0x00000001;
/* one step newton iteration to 53 bits with error less than 0.667 ulps */
s=t*t; /* t*t is exact */
r=x/s;
w=t+t;
r=(r-t)/(w+r); /* r-s is exact */
t=t+t*r;
/* retore the sign bit */
__HI(t) |= sign;
return(t);
}

View File

@@ -0,0 +1,115 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/collection_types.hpp>
namespace carve {
namespace csg {
enum FaceClass {
FACE_UNCLASSIFIED = -3,
FACE_ON_ORIENT_OUT = -2,
FACE_OUT = -1,
FACE_ON = 0,
FACE_IN = +1,
FACE_ON_ORIENT_IN = +2
};
enum FaceClassBit {
FACE_ON_ORIENT_OUT_BIT = 0x01,
FACE_OUT_BIT = 0x02,
FACE_IN_BIT = 0x04,
FACE_ON_ORIENT_IN_BIT = 0x08,
FACE_ANY_BIT = 0x0f,
FACE_ON_BIT = 0x09,
FACE_NOT_ON_BIT = 0x06
};
static inline FaceClass class_bit_to_class(unsigned i) {
if (i & FACE_ON_ORIENT_OUT_BIT) return FACE_ON_ORIENT_OUT;
if (i & FACE_OUT_BIT) return FACE_OUT;
if (i & FACE_IN_BIT) return FACE_IN;
if (i & FACE_ON_ORIENT_IN_BIT) return FACE_ON_ORIENT_IN;
return FACE_UNCLASSIFIED;
}
static inline unsigned class_to_class_bit(FaceClass f) {
switch (f) {
case FACE_ON_ORIENT_OUT: return FACE_ON_ORIENT_OUT_BIT;
case FACE_OUT: return FACE_OUT_BIT;
case FACE_ON: return FACE_ON_BIT;
case FACE_IN: return FACE_IN_BIT;
case FACE_ON_ORIENT_IN: return FACE_ON_ORIENT_IN_BIT;
case FACE_UNCLASSIFIED: return FACE_ANY_BIT;
default: return 0;
}
}
enum EdgeClass {
EDGE_UNK = -2,
EDGE_OUT = -1,
EDGE_ON = 0,
EDGE_IN = 1
};
const char *ENUM(FaceClass f);
const char *ENUM(PointClass p);
struct ClassificationInfo {
const carve::mesh::Mesh<3> *intersected_mesh;
FaceClass classification;
ClassificationInfo() : intersected_mesh(NULL), classification(FACE_UNCLASSIFIED) { }
ClassificationInfo(const carve::mesh::Mesh<3> *_intersected_mesh,
FaceClass _classification) :
intersected_mesh(_intersected_mesh),
classification(_classification) {
}
bool intersectedMeshIsClosed() const {
return intersected_mesh->isClosed();
}
};
struct EC2 {
EdgeClass cls[2];
EC2() { cls[0] = cls[1] = EDGE_UNK; }
EC2(EdgeClass a, EdgeClass b) { cls[0] = a; cls[1] = b; }
};
struct PC2 {
PointClass cls[2];
PC2() { cls[0] = cls[1] = POINT_UNK; }
PC2(PointClass a, PointClass b) { cls[0] = a; cls[1] = b; }
};
typedef std::unordered_map<std::pair<const carve::mesh::MeshSet<3>::vertex_t *, const carve::mesh::MeshSet<3>::vertex_t *>,
EC2> EdgeClassification;
typedef std::unordered_map<const carve::mesh::Vertex<3> *, PC2> VertexClassification;
}
}

View File

@@ -0,0 +1,51 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/collection/unordered.hpp>
namespace carve {
template<typename set_t>
class set_insert_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void> {
protected:
set_t *set;
public:
set_insert_iterator(set_t &s) : set(&s) {
}
set_insert_iterator &
operator=(typename set_t::const_reference value) {
set->insert(value);
return *this;
}
set_insert_iterator &operator*() { return *this; }
set_insert_iterator &operator++() { return *this; }
set_insert_iterator &operator++(int) { return *this; }
};
template<typename set_t>
inline set_insert_iterator<set_t>
set_inserter(set_t &s) {
return set_insert_iterator<set_t>(s);
}
}

View File

@@ -0,0 +1,43 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#if defined(HAVE_STD_UNORDERED_COLLECTIONS)
# include <carve/collection/unordered/std_impl.hpp>
#elif defined(HAVE_TR1_UNORDERED_COLLECTIONS)
# include <carve/collection/unordered/tr1_impl.hpp>
#elif defined(HAVE_BOOST_UNORDERED_COLLECTIONS)
# include <carve/collection/unordered/boost_impl.hpp>
#elif defined(HAVE_LIBSTDCPP_UNORDERED_COLLECTIONS)
# include <carve/collection/unordered/libstdcpp_impl.hpp>
#elif defined(_MSC_VER) && _MSC_VER >= 1300
# include <carve/collection/unordered/vcpp_impl.hpp>
#else
# include <carve/collection/unordered/fallback_impl.hpp>
#endif

View File

@@ -0,0 +1,45 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include BOOST_INCLUDE(unordered_set.hpp)
#include BOOST_INCLUDE(unordered_map.hpp)
#include <functional>
namespace std {
template <typename Key, typename T, typename Hash = boost::hash<Key>,
typename Pred = std::equal_to<Key> >
class unordered_map : public boost::unordered_map<Key, T, Hash, Pred> {
public:
typedef T data_type;
};
template <typename Key, typename T, typename Hash = boost::hash<Key>,
typename Pred = std::equal_to<Key> >
class unordered_multimap : public boost::unordered_multimap<Key, T, Hash, Pred> {
};
template <typename Value, typename Hash = boost::hash<Value>,
typename Pred = std::equal_to<Value> >
class unordered_set : public boost::unordered_set<Value, Hash, Pred> {
};
}
#undef UNORDERED_COLLECTIONS_SUPPORT_RESIZE

View File

@@ -0,0 +1,40 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <set>
#include <map>
namespace std {
template<typename K, typename T, typename H = int>
class unordered_map : public std::map<K, T> {
typedef std::map<K, T> super;
public:
typedef T data_type;
};
template<typename K, typename H = int>
class unordered_set : public std::set<K> {
typedef std::set<K> super;
public:
};
}
#undef UNORDERED_COLLECTIONS_SUPPORT_RESIZE

View File

@@ -0,0 +1,61 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <ext/hash_map>
#include <ext/hash_set>
namespace __gnu_cxx {
template <typename T>
struct hash<T *> : public std::unary_function<T *, size_t> {
size_t operator()(T *v) const {
size_t x = (size_t)(v);
return x + (x>>3);
}
};
template <typename A, typename B>
struct hash<std::pair<A, B> > : public std::unary_function<std::pair<A, B>, size_t> {
size_t operator()(const std::pair<A, B> &v) const {
std::size_t seed = 0;
seed ^= hash<A>()(v.first);
seed ^= hash<B>()(v.second) + (seed<<6) + (seed>>2);
return seed;
}
};
}
namespace std {
template<typename K, typename V, typename H = __gnu_cxx::hash<K> >
class unordered_map : public __gnu_cxx::hash_map<K, V, H> {
typedef __gnu_cxx::hash_map<K, V, H> super;
public:
typedef typename super::mapped_type data_type;
};
template<typename K, typename H = __gnu_cxx::hash<K> >
class unordered_set : public __gnu_cxx::hash_set<K, H> {
typedef __gnu_cxx::hash_set<K, H> super;
public:
};
}
#define UNORDERED_COLLECTIONS_SUPPORT_RESIZE 1

View File

@@ -0,0 +1,23 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <unordered_map>
#include <unordered_set>
#undef UNORDERED_COLLECTIONS_SUPPORT_RESIZE

View File

@@ -0,0 +1,58 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <tr1/functional>
namespace std {
namespace tr1 {
template <typename A, typename B>
struct hash<std::pair<A, B> > : public std::unary_function<std::pair<A, B>, size_t> {
size_t operator()(const std::pair<A, B> &v) const {
std::size_t seed = 0;
seed ^= hash<A>()(v.first);
seed ^= hash<B>()(v.second) + (seed<<6) + (seed>>2);
return seed;
}
};
}
template <typename Key, typename T,
typename Hash = tr1::hash<Key>,
typename Pred = std::equal_to<Key> >
class unordered_map : public std::tr1::unordered_map<Key, T, Hash, Pred> {
public:
typedef T data_type;
};
template <typename Value,
typename Hash = tr1::hash<Value>,
typename Pred = std::equal_to<Value> >
class unordered_set : public std::tr1::unordered_set<Value, Hash, Pred> {
public:
};
}
#undef UNORDERED_COLLECTIONS_SUPPORT_RESIZE

View File

@@ -0,0 +1,65 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <hash_map>
#include <hash_set>
namespace std {
namespace {
template<class Value, class Hash> class hash_traits {
Hash hash_value;
std::less<Value> comp;
public:
enum {
bucket_size = 4,
min_buckets = 8
};
// hash _Keyval to size_t value
size_t operator()(const Value& v) const {
return ((size_t)hash_value(v));
}
// test if _Keyval1 ordered before _Keyval2
bool operator()(const Value& v1, const Value& v2) const {
return (comp(v1, v2));
}
};
}
template <typename Key, typename T, typename Hash = stdext::hash_compare<Key, less<Key> >, typename Pred = std::equal_to<Key> >
class unordered_map
: public stdext::hash_map<Key, T, hash_traits<Key, Hash> > {
typedef stdext::hash_map<Key, T, hash_traits<Key, Hash> > super;
public:
unordered_map() : super() {}
};
template <typename Value, typename Hash = stdext::hash_compare<Key, less<Key> >, typename Pred = std::equal_to<Value> >
class unordered_set
: public stdext::hash_set<Value, hash_traits<Value, Hash> > {
typedef stdext::hash_set<Value, hash_traits<Value, Hash> > super;
public:
unordered_set() : super() {}
};
}
#undef UNORDERED_COLLECTIONS_SUPPORT_RESIZE

View File

@@ -0,0 +1,63 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/mesh.hpp>
namespace carve {
namespace csg {
typedef std::pair<
carve::mesh::MeshSet<3>::vertex_t *,
carve::mesh::MeshSet<3>::vertex_t *> V2;
typedef std::pair<
carve::mesh::MeshSet<3>::face_t *,
carve::mesh::MeshSet<3>::face_t *> F2;
static inline V2 ordered_edge(
carve::mesh::MeshSet<3>::vertex_t *a,
carve::mesh::MeshSet<3>::vertex_t *b) {
return V2(std::min(a, b), std::max(a, b));
}
static inline V2 flip(const V2 &v) {
return V2(v.second, v.first);
}
// include/carve/csg.hpp include/carve/faceloop.hpp
// lib/intersect.cpp lib/intersect_classify_common_impl.hpp
// lib/intersect_classify_edge.cpp
// lib/intersect_classify_group.cpp
// lib/intersect_classify_simple.cpp
// lib/intersect_face_division.cpp lib/intersect_group.cpp
// lib/intersect_half_classify_group.cpp
typedef std::unordered_set<V2> V2Set;
// include/carve/csg.hpp include/carve/polyhedron_decl.hpp
// lib/csg_collector.cpp lib/intersect.cpp
// lib/intersect_common.hpp lib/intersect_face_division.cpp
// lib/polyhedron.cpp
typedef std::unordered_map<
carve::mesh::MeshSet<3>::vertex_t *,
carve::mesh::MeshSet<3>::vertex_t *> VVMap;
}
}

47
extern/carve/include/carve/colour.hpp vendored Normal file
View File

@@ -0,0 +1,47 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom.hpp>
namespace carve {
namespace colour {
static inline void HSV2RGB(float H, float S, float V, float &r, float &g, float &b) {
H = 6.0f * H;
if (S < 5.0e-6) {
r = g = b = V; return;
} else {
int i = (int)H;
float f = H - i;
float p1 = V * (1.0f - S);
float p2 = V * (1.0f - S * f);
float p3 = V * (1.0f - S * (1.0f - f));
switch (i) {
case 0: r = V; g = p3; b = p1; return;
case 1: r = p2; g = V; b = p1; return;
case 2: r = p1; g = V; b = p3; return;
case 3: r = p1; g = p2; b = V; return;
case 4: r = p3; g = p1; b = V; return;
case 5: r = V; g = p1; b = p2; return;
}
}
r = g = b = 0.0;
}
}
}

30
extern/carve/include/carve/config.h vendored Normal file
View File

@@ -0,0 +1,30 @@
#define CARVE_VERSION "2.0.0a"
#undef CARVE_DEBUG
#undef CARVE_DEBUG_WRITE_PLY_DATA
#if defined(__GNUC__)
# if !defined(HAVE_BOOST_UNORDERED_COLLECTIONS)
# define HAVE_TR1_UNORDERED_COLLECTIONS
# endif
# define HAVE_STDINT_H
#endif
// Support for latest Clang/LLVM on FreeBSD which does have different libcxx.
//
// TODO(sergey): Move it some some more generic header with platform-specific
// declarations.
// Indicates whether __is_heap is available
#undef HAVE_IS_HEAP
#ifdef __GNUC__
// NeyBSD doesn't have __is_heap
# ifndef __NetBSD__
# define HAVE_IS_HEAP
# ifdef _LIBCPP_VERSION
# define __is_heap is_heap
# endif // _LIBCPP_VERSION
# endif // !__NetBSD__
#endif // __GNUC__

View File

@@ -0,0 +1,52 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <list>
#include <vector>
#include <algorithm>
#include <carve/carve.hpp>
#include <carve/geom2d.hpp>
namespace carve {
namespace geom {
std::vector<int> convexHull(const std::vector<carve::geom2d::P2> &points);
template<typename project_t, typename polygon_container_t>
std::vector<int> convexHull(const project_t &project, const polygon_container_t &points) {
std::vector<carve::geom2d::P2> proj;
proj.reserve(points.size());
for (typename polygon_container_t::const_iterator i = points.begin(); i != points.end(); ++i) {
proj.push_back(project(*i));
}
return convexHull(proj);
}
template<typename project_t, typename iter_t>
std::vector<int> convexHull(const project_t &project, iter_t beg, iter_t end, size_t size_hint = 0) {
std::vector<carve::geom2d::P2> proj;
if (size_hint) proj.reserve(size_hint);
for (; beg != end; ++beg) {
proj.push_back(project(*beg));
}
return convexHull(proj);
}
}
}

510
extern/carve/include/carve/csg.hpp vendored Normal file
View File

@@ -0,0 +1,510 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <list>
#include <vector>
#include <algorithm>
#include <carve/carve.hpp>
#include <carve/geom3d.hpp>
#include <carve/mesh.hpp>
#include <carve/collection_types.hpp>
#include <carve/classification.hpp>
#include <carve/iobj.hpp>
#include <carve/faceloop.hpp>
#include <carve/intersection.hpp>
#include <carve/rtree.hpp>
namespace carve {
namespace csg {
class VertexPool {
typedef carve::mesh::MeshSet<3>::vertex_t vertex_t;
const static unsigned blocksize = 1024;
typedef std::list<std::vector<vertex_t> > pool_t;
pool_t pool;
public:
void reset();
vertex_t *get(const vertex_t::vector_t &v = vertex_t::vector_t::ZERO());
bool inPool(vertex_t *v) const;
VertexPool();
~VertexPool();
};
namespace detail {
struct Data;
class LoopEdges;
}
/**
* \class CSG
* \brief The class responsible for the computation of CSG operations.
*
*/
class CSG {
private:
public:
typedef carve::mesh::MeshSet<3> meshset_t;
struct Hook {
/**
* \class Hook
* \brief Provides API access to intermediate steps in CSG calculation.
*
*/
virtual void intersectionVertex(const meshset_t::vertex_t * /* vertex */,
const IObjPairSet & /* intersections */) {
}
virtual void processOutputFace(std::vector<meshset_t::face_t *> & /* faces */,
const meshset_t::face_t * /* orig_face */,
bool /* flipped */) {
}
virtual void resultFace(const meshset_t::face_t * /* new_face */,
const meshset_t::face_t * /* orig_face */,
bool /* flipped */) {
}
virtual void edgeDivision(const meshset_t::edge_t * /* orig_edge */,
size_t /* orig_edge_idx */,
const meshset_t::vertex_t * /* v1 */,
const meshset_t::vertex_t * /* v2 */) {
}
virtual ~Hook() {
}
};
/**
* \class Hooks
* \brief Management of API hooks.
*
*/
class Hooks {
public:
enum {
RESULT_FACE_HOOK = 0,
PROCESS_OUTPUT_FACE_HOOK = 1,
INTERSECTION_VERTEX_HOOK = 2,
EDGE_DIVISION_HOOK = 3,
HOOK_MAX = 4,
RESULT_FACE_BIT = 0x0001,
PROCESS_OUTPUT_FACE_BIT = 0x0002,
INTERSECTION_VERTEX_BIT = 0x0004,
EDGE_DIVISION_BIT = 0x0008
};
std::vector<std::list<Hook *> > hooks;
bool hasHook(unsigned hook_num);
void intersectionVertex(const meshset_t::vertex_t *vertex,
const IObjPairSet &intersections);
void processOutputFace(std::vector<meshset_t::face_t *> &faces,
const meshset_t::face_t *orig_face,
bool flipped);
void resultFace(const meshset_t::face_t *new_face,
const meshset_t::face_t *orig_face,
bool flipped);
void edgeDivision(const meshset_t::edge_t *orig_edge,
size_t orig_edge_idx,
const meshset_t::vertex_t *v1,
const meshset_t::vertex_t *v2);
void registerHook(Hook *hook, unsigned hook_bits);
void unregisterHook(Hook *hook);
void reset();
Hooks();
~Hooks();
};
/**
* \class Collector
* \brief Base class for objects responsible for selecting result from which form the result polyhedron.
*
*/
class Collector {
Collector(const Collector &);
Collector &operator=(const Collector &);
protected:
public:
virtual void collect(FaceLoopGroup *group, CSG::Hooks &) =0;
virtual meshset_t *done(CSG::Hooks &) =0;
Collector() {}
virtual ~Collector() {}
};
private:
typedef carve::geom::RTreeNode<3, carve::mesh::Face<3> *> face_rtree_t;
typedef std::unordered_map<carve::mesh::Face<3> *, std::vector<carve::mesh::Face<3> *> > face_pairs_t;
/// The computed intersection data.
Intersections intersections;
/// A map from intersection point to a set of intersections
/// represented by pairs of intersection objects.
VertexIntersections vertex_intersections;
/// A pool from which temporary vertices are allocated. Also
/// provides testing for pool membership.
VertexPool vertex_pool;
void init();
void makeVertexIntersections();
void groupIntersections();
void _generateVertexVertexIntersections(meshset_t::vertex_t *va,
meshset_t::edge_t *eb);
void generateVertexVertexIntersections(meshset_t::face_t *a,
const std::vector<meshset_t::face_t *> &b);
void _generateVertexEdgeIntersections(meshset_t::vertex_t *va,
meshset_t::edge_t *eb);
void generateVertexEdgeIntersections(meshset_t::face_t *a,
const std::vector<meshset_t::face_t *> &b);
void _generateEdgeEdgeIntersections(meshset_t::edge_t *ea,
meshset_t::edge_t *eb);
void generateEdgeEdgeIntersections(meshset_t::face_t *a,
const std::vector<meshset_t::face_t *> &b);
void _generateVertexFaceIntersections(meshset_t::face_t *fa,
meshset_t::edge_t *eb);
void generateVertexFaceIntersections(meshset_t::face_t *a,
const std::vector<meshset_t::face_t *> &b);
void _generateEdgeFaceIntersections(meshset_t::face_t *fa,
meshset_t::edge_t *eb);
void generateEdgeFaceIntersections(meshset_t::face_t *a,
const std::vector<meshset_t::face_t *> &b);
void generateIntersectionCandidates(meshset_t *a,
const face_rtree_t *a_node,
meshset_t *b,
const face_rtree_t *b_node,
face_pairs_t &face_pairs,
bool descend_a = true);
/**
* \brief Compute all points of intersection between poly \a a and poly \a b
*
* @param a Polyhedron a.
* @param b Polyhedron b.
*/
void generateIntersections(meshset_t *a,
const face_rtree_t *a_node,
meshset_t *b,
const face_rtree_t *b_node,
detail::Data &data);
/**
* \brief Generate tables of intersecting pairs of faces.
*
* @param[out] data Internal data-structure holding intersection info.
*/
void intersectingFacePairs(detail::Data &data);
/**
* \brief Divide edges in \a edges that are intersected by polyhedron \a poly
*
* @param edges The edges to divide.
* @param[in] poly The polyhedron to divide against.
* @param[in,out] data Intersection information.
*/
void divideEdges(
const std::vector<meshset_t::edge_t> &edges,
meshset_t *poly,
detail::Data &data);
void divideIntersectedEdges(detail::Data &data);
/**
* \brief From the intersection points of pairs of intersecting faces, compute intersection edges.
*
* @param[out] eclass Classification information about created edges.
* @param[in,out] data Intersection information.
*/
void makeFaceEdges(
EdgeClassification &eclass,
detail::Data &data);
friend void classifyEasyFaces(
FaceLoopList &face_loops,
VertexClassification &vclass,
meshset_t *other_poly,
int other_poly_num,
CSG &csg,
CSG::Collector &collector);
size_t generateFaceLoops(
meshset_t *poly,
const detail::Data &data,
FaceLoopList &face_loops_out);
// intersect_group.cpp
/**
* \brief Build a loop edge mapping from a list of face loops.
*
* @param[in] loops A list of face loops.
* @param[in] edge_count A hint as to the number of edges in \a loops.
* @param[out] edge_map The calculated map of edges to loops.
*/
void makeEdgeMap(
const FaceLoopList &loops,
size_t edge_count,
detail::LoopEdges &edge_map);
/**
* \brief Divide a list of face loops into groups that are connected by at least one edge not present in \a no_cross.
*
* @param[in] src The source mesh from which these loops derive.
* @param[in,out] face_loops The list of loops (will be emptied as a side effect)
* @param[in] loop_edges A loop edge map used for traversing connected loops.
* @param[in] no_cross A set of edges not to cross.
* @param[out] out_loops A list of grouped face loops.
*/
void groupFaceLoops(
meshset_t *src,
FaceLoopList &face_loops,
const detail::LoopEdges &loop_edges,
const V2Set &no_cross,
FLGroupList &out_loops);
/**
* \brief Find the set of edges shared between two edge maps.
*
* @param[in] edge_map_a The first edge map.
* @param[in] edge_map_b The second edge map.
* @param[out] shared_edges The resulting set of common edges.
*/
void findSharedEdges(
const detail::LoopEdges &edge_map_a,
const detail::LoopEdges &edge_map_b,
V2Set &shared_edges);
// intersect_classify_edge.cpp
/**
*
*
* @param shared_edges
* @param vclass
* @param poly_a
* @param a_loops_grouped
* @param a_edge_map
* @param poly_b
* @param b_loops_grouped
* @param b_edge_map
* @param collector
*/
void classifyFaceGroupsEdge(
const V2Set &shared_edges,
VertexClassification &vclass,
meshset_t *poly_a,
const face_rtree_t *poly_a_rtree,
FLGroupList &a_loops_grouped,
const detail::LoopEdges &a_edge_map,
meshset_t *poly_b,
const face_rtree_t *poly_b_rtree,
FLGroupList &b_loops_grouped,
const detail::LoopEdges &b_edge_map,
CSG::Collector &collector);
// intersect_classify_group.cpp
/**
*
*
* @param shared_edges
* @param vclass
* @param poly_a
* @param a_loops_grouped
* @param a_edge_map
* @param poly_b
* @param b_loops_grouped
* @param b_edge_map
* @param collector
*/
void classifyFaceGroups(
const V2Set &shared_edges,
VertexClassification &vclass,
meshset_t *poly_a,
const face_rtree_t *poly_a_rtree,
FLGroupList &a_loops_grouped,
const detail::LoopEdges &a_edge_map,
meshset_t *poly_b,
const face_rtree_t *poly_b_rtree,
FLGroupList &b_loops_grouped,
const detail::LoopEdges &b_edge_map,
CSG::Collector &collector);
// intersect_half_classify_group.cpp
/**
*
*
* @param shared_edges
* @param vclass
* @param poly_a
* @param a_loops_grouped
* @param a_edge_map
* @param poly_b
* @param b_loops_grouped
* @param b_edge_map
* @param FaceClass
* @param b_out
*/
void halfClassifyFaceGroups(
const V2Set &shared_edges,
VertexClassification &vclass,
meshset_t *poly_a,
const face_rtree_t *poly_a_rtree,
FLGroupList &a_loops_grouped,
const detail::LoopEdges &a_edge_map,
meshset_t *poly_b,
const face_rtree_t *poly_b_rtree,
FLGroupList &b_loops_grouped,
const detail::LoopEdges &b_edge_map,
std::list<std::pair<FaceClass, meshset_t *> > &b_out);
// intersect.cpp
/**
* \brief The main calculation method for CSG.
*
* @param[in] a Polyhedron a
* @param[in] b Polyhedron b
* @param[out] vclass
* @param[out] eclass
* @param[out] a_face_loops
* @param[out] b_face_loops
* @param[out] a_edge_count
* @param[out] b_edge_count
*/
void calc(
meshset_t *a,
const face_rtree_t *a_rtree,
meshset_t *b,
const face_rtree_t *b_rtree,
VertexClassification &vclass,
EdgeClassification &eclass,
FaceLoopList &a_face_loops,
FaceLoopList &b_face_loops,
size_t &a_edge_count,
size_t &b_edge_count);
public:
/**
* \enum OP
* \brief Enumeration of the supported CSG operations.
*/
enum OP {
UNION, /**< in a or b. */
INTERSECTION, /**< in a and b. */
A_MINUS_B, /**< in a, but not b. */
B_MINUS_A, /**< in b, but not a. */
SYMMETRIC_DIFFERENCE, /**< in a or b, but not both. */
ALL /**< all split faces from a and b */
};
/**
* \enum CLASSIFY_TYPE
* \brief The type of classification algorithm to use.
*/
enum CLASSIFY_TYPE {
CLASSIFY_NORMAL, /**< Normal (group) classifier. */
CLASSIFY_EDGE /**< Edge classifier. */
};
CSG::Hooks hooks; /**< The manager for calculation hooks. */
CSG();
~CSG();
/**
* \brief Compute a CSG operation between two polyhedra, \a a and \a b.
*
* @param a Polyhedron a
* @param b Polyhedron b
* @param collector The collector (determines the CSG operation performed)
* @param shared_edges A pointer to a set that will be populated with shared edges (if not NULL).
* @param classify_type The type of classifier to use.
*
* @return
*/
meshset_t *compute(
meshset_t *a,
meshset_t *b,
CSG::Collector &collector,
V2Set *shared_edges = NULL,
CLASSIFY_TYPE classify_type = CLASSIFY_NORMAL);
/**
* \brief Compute a CSG operation between two closed polyhedra, \a a and \a b.
*
* @param a Polyhedron a
* @param b Polyhedron b
* @param op The CSG operation (A collector is created automatically).
* @param shared_edges A pointer to a set that will be populated with shared edges (if not NULL).
* @param classify_type The type of classifier to use.
*
* @return
*/
meshset_t *compute(
meshset_t *a,
meshset_t *b,
OP op,
V2Set *shared_edges = NULL,
CLASSIFY_TYPE classify_type = CLASSIFY_NORMAL);
void slice(
meshset_t *a,
meshset_t *b,
std::list<meshset_t *> &a_sliced,
std::list<meshset_t *> &b_sliced,
V2Set *shared_edges = NULL);
bool sliceAndClassify(
meshset_t *closed,
meshset_t *open,
std::list<std::pair<FaceClass, meshset_t *> > &result,
V2Set *shared_edges = NULL);
};
}
}

View File

@@ -0,0 +1,435 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#include <carve/csg.hpp>
#include <carve/tag.hpp>
#include <carve/poly.hpp>
#include <carve/triangulator.hpp>
#include <deque>
namespace carve {
namespace csg {
namespace detail {
template<bool with_improvement>
class CarveTriangulator : public csg::CSG::Hook {
public:
CarveTriangulator() {
}
virtual ~CarveTriangulator() {
}
virtual void processOutputFace(std::vector<carve::mesh::MeshSet<3>::face_t *> &faces,
const carve::mesh::MeshSet<3>::face_t *orig,
bool flipped) {
std::vector<carve::mesh::MeshSet<3>::face_t *> out_faces;
size_t n_tris = 0;
for (size_t f = 0; f < faces.size(); ++f) {
CARVE_ASSERT(faces[f]->nVertices() >= 3);
n_tris += faces[f]->nVertices() - 2;
}
out_faces.reserve(n_tris);
for (size_t f = 0; f < faces.size(); ++f) {
carve::mesh::MeshSet<3>::face_t *face = faces[f];
if (face->nVertices() == 3) {
out_faces.push_back(face);
continue;
}
std::vector<triangulate::tri_idx> result;
std::vector<carve::mesh::MeshSet<3>::vertex_t *> vloop;
face->getVertices(vloop);
triangulate::triangulate(
carve::mesh::MeshSet<3>::face_t::projection_mapping(face->project),
vloop,
result);
if (with_improvement) {
triangulate::improve(
carve::mesh::MeshSet<3>::face_t::projection_mapping(face->project),
vloop,
carve::mesh::vertex_distance(),
result);
}
std::vector<carve::mesh::MeshSet<3>::vertex_t *> fv;
fv.resize(3);
for (size_t i = 0; i < result.size(); ++i) {
fv[0] = vloop[result[i].a];
fv[1] = vloop[result[i].b];
fv[2] = vloop[result[i].c];
out_faces.push_back(face->create(fv.begin(), fv.end(), false));
}
delete face;
}
std::swap(faces, out_faces);
}
};
}
typedef detail::CarveTriangulator<false> CarveTriangulator;
typedef detail::CarveTriangulator<true> CarveTriangulatorWithImprovement;
class CarveTriangulationImprover : public csg::CSG::Hook {
public:
CarveTriangulationImprover() {
}
virtual ~CarveTriangulationImprover() {
}
virtual void processOutputFace(std::vector<carve::mesh::MeshSet<3>::face_t *> &faces,
const carve::mesh::MeshSet<3>::face_t *orig,
bool flipped) {
if (faces.size() == 1) return;
// doing improvement as a separate hook is much messier than
// just incorporating it into the triangulation hook.
typedef std::map<carve::mesh::MeshSet<3>::vertex_t *, size_t> vert_map_t;
std::vector<carve::mesh::MeshSet<3>::face_t *> out_faces;
vert_map_t vert_map;
out_faces.reserve(faces.size());
carve::mesh::MeshSet<3>::face_t::projection_mapping projector(faces[0]->project);
std::vector<triangulate::tri_idx> result;
for (size_t f = 0; f < faces.size(); ++f) {
carve::mesh::MeshSet<3>::face_t *face = faces[f];
if (face->nVertices() != 3) {
out_faces.push_back(face);
} else {
triangulate::tri_idx tri;
for (carve::mesh::MeshSet<3>::face_t::edge_iter_t i = face->begin(); i != face->end(); ++i) {
size_t v = 0;
vert_map_t::iterator j = vert_map.find(i->vert);
if (j == vert_map.end()) {
v = vert_map.size();
vert_map[i->vert] = v;
} else {
v = (*j).second;
}
tri.v[i.idx()] = v;
}
result.push_back(tri);
delete face;
}
}
std::vector<carve::mesh::MeshSet<3>::vertex_t *> verts;
verts.resize(vert_map.size());
for (vert_map_t::iterator i = vert_map.begin(); i != vert_map.end(); ++i) {
verts[(*i).second] = (*i).first;
}
triangulate::improve(projector, verts, carve::mesh::vertex_distance(), result);
std::vector<carve::mesh::MeshSet<3>::vertex_t *> fv;
fv.resize(3);
for (size_t i = 0; i < result.size(); ++i) {
fv[0] = verts[result[i].a];
fv[1] = verts[result[i].b];
fv[2] = verts[result[i].c];
out_faces.push_back(orig->create(fv.begin(), fv.end(), false));
}
std::swap(faces, out_faces);
}
};
class CarveTriangulationQuadMerger : public csg::CSG::Hook {
// this code is incomplete.
typedef std::map<V2, F2> edge_map_t;
public:
CarveTriangulationQuadMerger() {
}
virtual ~CarveTriangulationQuadMerger() {
}
double scoreQuad(edge_map_t::iterator i, edge_map_t &edge_map) {
if (!(*i).second.first || !(*i).second.second) return -1;
return -1;
}
carve::mesh::MeshSet<3>::face_t *mergeQuad(edge_map_t::iterator i, edge_map_t &edge_map) {
return NULL;
}
void recordEdge(carve::mesh::MeshSet<3>::vertex_t *v1,
carve::mesh::MeshSet<3>::vertex_t *v2,
carve::mesh::MeshSet<3>::face_t *f,
edge_map_t &edge_map) {
if (v1 < v2) {
edge_map[V2(v1, v2)].first = f;
} else {
edge_map[V2(v2, v1)].second = f;
}
}
virtual void processOutputFace(std::vector<carve::mesh::MeshSet<3>::face_t *> &faces,
const carve::mesh::MeshSet<3>::face_t *orig,
bool flipped) {
if (faces.size() == 1) return;
std::vector<carve::mesh::MeshSet<3>::face_t *> out_faces;
edge_map_t edge_map;
out_faces.reserve(faces.size());
poly::p2_adapt_project<3> projector(faces[0]->project);
for (size_t f = 0; f < faces.size(); ++f) {
carve::mesh::MeshSet<3>::face_t *face = faces[f];
if (face->nVertices() != 3) {
out_faces.push_back(face);
} else {
carve::mesh::MeshSet<3>::face_t::vertex_t *v1, *v2, *v3;
v1 = face->edge->vert;
v2 = face->edge->next->vert;
v3 = face->edge->next->next->vert;
recordEdge(v1, v2, face, edge_map);
recordEdge(v2, v3, face, edge_map);
recordEdge(v3, v1, face, edge_map);
}
}
for (edge_map_t::iterator i = edge_map.begin(); i != edge_map.end();) {
if ((*i).second.first && (*i).second.second) {
++i;
} else {
edge_map.erase(i++);
}
}
while (edge_map.size()) {
edge_map_t::iterator i = edge_map.begin();
edge_map_t::iterator best = i;
double best_score = scoreQuad(i, edge_map);
for (++i; i != edge_map.end(); ++i) {
double score = scoreQuad(i, edge_map);
if (score > best_score) best = i;
}
if (best_score < 0) break;
out_faces.push_back(mergeQuad(best, edge_map));
}
if (edge_map.size()) {
tagable::tag_begin();
for (edge_map_t::iterator i = edge_map.begin(); i != edge_map.end(); ++i) {
carve::mesh::MeshSet<3>::face_t *a = const_cast<carve::mesh::MeshSet<3>::face_t *>((*i).second.first);
carve::mesh::MeshSet<3>::face_t *b = const_cast<carve::mesh::MeshSet<3>::face_t *>((*i).second.first);
if (a && a->tag_once()) out_faces.push_back(a);
if (b && b->tag_once()) out_faces.push_back(b);
}
}
std::swap(faces, out_faces);
}
};
class CarveHoleResolver : public csg::CSG::Hook {
public:
CarveHoleResolver() {
}
virtual ~CarveHoleResolver() {
}
bool findRepeatedEdges(const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &vertices,
std::list<std::pair<size_t, size_t> > &edge_pos) {
std::map<V2, size_t> edges;
for (size_t i = 0; i < vertices.size() - 1; ++i) {
edges[std::make_pair(vertices[i], vertices[i+1])] = i;
}
edges[std::make_pair(vertices[vertices.size()-1], vertices[0])] = vertices.size() - 1;
for (std::map<V2, size_t>::iterator i = edges.begin(); i != edges.end(); ++i) {
V2 rev = V2((*i).first.second, (*i).first.first);
std::map<V2, size_t>::iterator j = edges.find(rev);
if (j != edges.end()) {
edge_pos.push_back(std::make_pair((*i).second, (*j).second));
}
}
return edge_pos.size() > 0;
}
void flood(size_t t1,
size_t t2,
size_t old_grp,
size_t new_grp_1,
size_t new_grp_2,
std::vector<size_t> &grp,
const std::vector<triangulate::tri_idx> &tris,
const std::map<std::pair<size_t, size_t>, size_t> &tri_edge) {
grp[t1] = new_grp_1;
grp[t2] = new_grp_2;
std::deque<size_t> to_visit;
to_visit.push_back(t1);
to_visit.push_back(t2);
std::vector<std::pair<size_t, size_t> > rev;
rev.resize(3);
while (to_visit.size()) {
size_t curr = to_visit.front();
to_visit.pop_front();
triangulate::tri_idx ct = tris[curr];
rev[0] = std::make_pair(ct.b, ct.a);
rev[1] = std::make_pair(ct.c, ct.b);
rev[2] = std::make_pair(ct.a, ct.c);
for (size_t i = 0; i < 3; ++i) {
std::map<std::pair<size_t, size_t>, size_t>::const_iterator adj = tri_edge.find(rev[i]);
if (adj == tri_edge.end()) continue;
size_t next = (*adj).second;
if (grp[next] != old_grp) continue;
grp[next] = grp[curr];
to_visit.push_back(next);
}
}
}
void findPerimeter(const std::vector<triangulate::tri_idx> &tris,
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &verts,
std::vector<carve::mesh::MeshSet<3>::vertex_t *> &out) {
std::map<std::pair<size_t, size_t>, size_t> edges;
for (size_t i = 0; i < tris.size(); ++i) {
edges[std::make_pair(tris[i].a, tris[i].b)] = i;
edges[std::make_pair(tris[i].b, tris[i].c)] = i;
edges[std::make_pair(tris[i].c, tris[i].a)] = i;
}
std::map<size_t, size_t> unpaired;
for (std::map<std::pair<size_t, size_t>, size_t>::iterator i = edges.begin(); i != edges.end(); ++i) {
if (edges.find(std::make_pair((*i).first.second, (*i).first.first)) == edges.end()) {
CARVE_ASSERT(unpaired.find((*i).first.first) == unpaired.end());
unpaired[(*i).first.first] = (*i).first.second;
}
}
out.clear();
out.reserve(unpaired.size());
size_t start = (*unpaired.begin()).first;
size_t vert = start;
do {
out.push_back(verts[vert]);
CARVE_ASSERT(unpaired.find(vert) != unpaired.end());
vert = unpaired[vert];
} while (vert != start);
}
virtual void processOutputFace(std::vector<carve::mesh::MeshSet<3>::face_t *> &faces,
const carve::mesh::MeshSet<3>::face_t *orig,
bool flipped) {
std::vector<carve::mesh::MeshSet<3>::face_t *> out_faces;
for (size_t f = 0; f < faces.size(); ++f) {
carve::mesh::MeshSet<3>::face_t *face = faces[f];
if (face->nVertices() == 3) {
out_faces.push_back(face);
continue;
}
std::vector<carve::mesh::MeshSet<3>::vertex_t *> vloop;
face->getVertices(vloop);
std::list<std::pair<size_t, size_t> > rep_edges;
if (!findRepeatedEdges(vloop, rep_edges)) {
out_faces.push_back(face);
continue;
}
std::vector<triangulate::tri_idx> result;
triangulate::triangulate(
carve::mesh::MeshSet<3>::face_t::projection_mapping(face->project),
vloop,
result);
std::map<std::pair<size_t, size_t>, size_t> tri_edge;
for (size_t i = 0; i < result.size(); ++i) {
tri_edge[std::make_pair(result[i].a, result[i].b)] = i;
tri_edge[std::make_pair(result[i].b, result[i].c)] = i;
tri_edge[std::make_pair(result[i].c, result[i].a)] = i;
}
std::vector<size_t> grp;
grp.resize(result.size(), 0);
size_t grp_max = 0;
while (rep_edges.size()) {
std::pair<size_t, size_t> e1, e2;
e1.first = rep_edges.front().first;
e1.second = (e1.first + 1) % vloop.size();
e2.first = rep_edges.front().second;
e2.second = (e2.first + 1) % vloop.size();
rep_edges.pop_front();
CARVE_ASSERT(tri_edge.find(e1) != tri_edge.end());
size_t t1 = tri_edge[e1];
CARVE_ASSERT(tri_edge.find(e2) != tri_edge.end());
size_t t2 = tri_edge[e2];
if (grp[t1] != grp[t2]) {
continue;
}
size_t t1g = ++grp_max;
size_t t2g = ++grp_max;
flood(t1, t2, grp[t1], t1g, t2g, grp, result, tri_edge);
}
std::set<size_t> groups;
std::copy(grp.begin(), grp.end(), std::inserter(groups, groups.begin()));
// now construct perimeters for each group.
std::vector<triangulate::tri_idx> grp_tris;
grp_tris.reserve(result.size());
for (std::set<size_t>::iterator i = groups.begin(); i != groups.end(); ++i) {
size_t grp_id = *i;
grp_tris.clear();
for (size_t j = 0; j < grp.size(); ++j) {
if (grp[j] == grp_id) {
grp_tris.push_back(result[j]);
}
}
std::vector<carve::mesh::MeshSet<3>::vertex_t *> grp_perim;
findPerimeter(grp_tris, vloop, grp_perim);
out_faces.push_back(face->create(grp_perim.begin(), grp_perim.end(), false));
}
delete face;
}
std::swap(faces, out_faces);
}
};
}
}

View File

@@ -0,0 +1,97 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/vector.hpp>
#include <carve/geom3d.hpp>
#include <carve/csg.hpp>
#include <iomanip>
template<typename MAP>
void map_histogram(std::ostream &out, const MAP &map) {
std::vector<int> hist;
for (typename MAP::const_iterator i = map.begin(); i != map.end(); ++i) {
size_t n = (*i).second.size();
if (hist.size() <= n) {
hist.resize(n + 1);
}
hist[n]++;
}
int total = (int)map.size();
std::string bar(50, '*');
for (size_t i = 0; i < hist.size(); i++) {
if (hist[i] > 0) {
out << std::setw(5) << i << " : " << std::setw(5) << hist[i] << " " << bar.substr((size_t)(50 - hist[i] * 50 / total)) << std::endl;
}
}
}
namespace carve {
namespace csg {
class IntersectDebugHooks {
public:
virtual void drawIntersections(const VertexIntersections & /* vint */) {
}
virtual void drawPoint(const carve::mesh::MeshSet<3>::vertex_t * /* v */,
float /* r */,
float /* g */,
float /* b */,
float /* a */,
float /* rad */) {
}
virtual void drawEdge(const carve::mesh::MeshSet<3>::vertex_t * /* v1 */,
const carve::mesh::MeshSet<3>::vertex_t * /* v2 */,
float /* rA */, float /* gA */, float /* bA */, float /* aA */,
float /* rB */, float /* gB */, float /* bB */, float /* aB */,
float /* thickness */ = 1.0) {
}
virtual void drawFaceLoopWireframe(const std::vector<carve::mesh::MeshSet<3>::vertex_t *> & /* face_loop */,
const carve::mesh::MeshSet<3>::vertex_t & /* normal */,
float /* r */, float /* g */, float /* b */, float /* a */,
bool /* inset */ = true) {
}
virtual void drawFaceLoop(const std::vector<carve::mesh::MeshSet<3>::vertex_t *> & /* face_loop */,
const carve::mesh::MeshSet<3>::vertex_t & /* normal */,
float /* r */, float /* g */, float /* b */, float /* a */,
bool /* offset */ = true,
bool /* lit */ = true) {
}
virtual void drawFaceLoop2(const std::vector<carve::mesh::MeshSet<3>::vertex_t *> & /* face_loop */,
const carve::mesh::MeshSet<3>::vertex_t & /* normal */,
float /* rF */, float /* gF */, float /* bF */, float /* aF */,
float /* rB */, float /* gB */, float /* bB */, float /* aB */,
bool /* offset */ = true,
bool /* lit */ = true) {
}
virtual ~IntersectDebugHooks() {
}
};
IntersectDebugHooks *intersect_installDebugHooks(IntersectDebugHooks *hooks);
bool intersect_debugEnabled();
}
}

134
extern/carve/include/carve/djset.hpp vendored Normal file
View File

@@ -0,0 +1,134 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <vector>
namespace carve {
namespace djset {
class djset {
protected:
struct elem {
size_t parent, rank;
elem(size_t p, size_t r) : parent(p), rank(r) {}
elem() {}
};
std::vector<elem> set;
size_t n_sets;
public:
djset() : set(), n_sets(0) {
}
djset(size_t N) {
n_sets = N;
set.reserve(N);
for (size_t i = 0; i < N; ++i) {
set.push_back(elem(i,0));
}
}
void init(size_t N) {
if (N == set.size()) {
for (size_t i = 0; i < N; ++i) {
set[i] = elem(i,0);
}
n_sets = N;
} else {
djset temp(N);
std::swap(set, temp.set);
std::swap(n_sets, temp.n_sets);
}
}
size_t count() const {
return n_sets;
}
size_t find_set_head(size_t a) {
if (a == set[a].parent) return a;
size_t a_head = a;
while (set[a_head].parent != a_head) a_head = set[a_head].parent;
set[a].parent = a_head;
return a_head;
}
bool same_set(size_t a, size_t b) {
return find_set_head(a) == find_set_head(b);
}
void merge_sets(size_t a, size_t b) {
a = find_set_head(a);
b = find_set_head(b);
if (a != b) {
n_sets--;
if (set[a].rank < set[b].rank) {
set[a].parent = b;
} else if (set[b].rank < set[a].rank) {
set[b].parent = a;
} else {
set[a].rank++;
set[b].parent = a;
}
}
}
void get_index_to_set(std::vector<size_t> &index_set, std::vector<size_t> &set_size) {
index_set.clear();
index_set.resize(set.size(), n_sets);
set_size.clear();
set_size.resize(n_sets, 0);
size_t c = 0;
for (size_t i = 0; i < set.size(); ++i) {
size_t s = find_set_head(i);
if (index_set[s] == n_sets) index_set[s] = c++;
index_set[i] = index_set[s];
set_size[index_set[s]]++;
}
}
template<typename in_iter_t, typename out_collection_t>
void collate(in_iter_t in, out_collection_t &out) {
std::vector<size_t> set_id(set.size(), n_sets);
out.clear();
out.resize(n_sets);
size_t c = 0;
for (size_t i = 0; i < set.size(); ++i) {
size_t s = find_set_head(i);
if (set_id[s] == n_sets) set_id[s] = c++;
s = set_id[s];
std::insert_iterator<typename out_collection_t::value_type> j(out[s], out[s].end());
*j = *in++;
}
}
};
}
}

View File

@@ -0,0 +1,68 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/vector.hpp>
#include <carve/tag.hpp>
#include <vector>
#include <list>
namespace carve {
namespace poly {
struct Object;
template<unsigned ndim>
class Edge : public tagable {
public:
typedef Vertex<ndim> vertex_t;
typedef typename Vertex<ndim>::vector_t vector_t;
typedef Object obj_t;
const vertex_t *v1, *v2;
const obj_t *owner;
Edge(const vertex_t *_v1, const vertex_t *_v2, const obj_t *_owner) :
tagable(), v1(_v1), v2(_v2), owner(_owner) {
}
~Edge() {
}
};
struct hash_edge_ptr {
template<unsigned ndim>
size_t operator()(const Edge<ndim> * const &e) const {
return (size_t)e;
}
};
}
}

View File

@@ -0,0 +1,23 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
namespace carve {
namespace poly {
}
}

704
extern/carve/include/carve/exact.hpp vendored Normal file
View File

@@ -0,0 +1,704 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <vector>
#include <numeric>
#include <algorithm>
namespace carve {
namespace exact {
class exact_t : public std::vector<double> {
typedef std::vector<double> super;
public:
exact_t() : super() {
}
exact_t(double v, size_t sz = 1) : super(sz, v) {
}
template<typename iter_t>
exact_t(iter_t a, iter_t b) : super(a, b) {
}
exact_t(double a, double b) : super() {
reserve(2);
push_back(a);
push_back(b);
}
exact_t(double a, double b, double c) : super() {
reserve(3);
push_back(a);
push_back(b);
push_back(c);
}
exact_t(double a, double b, double c, double d) : super() {
reserve(4);
push_back(a);
push_back(b);
push_back(c);
push_back(d);
}
exact_t(double a, double b, double c, double d, double e) : super() {
reserve(5);
push_back(a);
push_back(b);
push_back(c);
push_back(d);
push_back(e);
}
exact_t(double a, double b, double c, double d, double e, double f) : super() {
reserve(6);
push_back(a);
push_back(b);
push_back(c);
push_back(d);
push_back(e);
push_back(f);
}
exact_t(double a, double b, double c, double d, double e, double f, double g) : super() {
reserve(7);
push_back(a);
push_back(b);
push_back(c);
push_back(d);
push_back(e);
push_back(f);
push_back(g);
}
exact_t(double a, double b, double c, double d, double e, double f, double g, double h) : super() {
reserve(8);
push_back(a);
push_back(b);
push_back(c);
push_back(d);
push_back(e);
push_back(f);
push_back(g);
push_back(h);
}
void compress();
exact_t compressed() const {
exact_t result(*this);
result.compress();
return result;
}
operator double() const {
return std::accumulate(begin(), end(), 0.0);
}
void removeZeroes() {
erase(std::remove(begin(), end(), 0.0), end());
}
};
inline std::ostream &operator<<(std::ostream &out, const exact_t &p) {
out << '{';
out << p[0];
for (size_t i = 1; i < p.size(); ++i) out << ';' << p[i];
out << '}';
return out;
}
namespace detail {
const struct constants_t {
double splitter; /* = 2^ceiling(p / 2) + 1. Used to split floats in half. */
double epsilon; /* = 2^(-p). Used to estimate roundoff errors. */
/* A set of coefficients used to calculate maximum roundoff errors. */
double resulterrbound;
double ccwerrboundA, ccwerrboundB, ccwerrboundC;
double o3derrboundA, o3derrboundB, o3derrboundC;
double iccerrboundA, iccerrboundB, iccerrboundC;
double isperrboundA, isperrboundB, isperrboundC;
constants_t() {
double half;
double check, lastcheck;
int every_other;
every_other = 1;
half = 0.5;
epsilon = 1.0;
splitter = 1.0;
check = 1.0;
/* Repeatedly divide `epsilon' by two until it is too small to add to */
/* one without causing roundoff. (Also check if the sum is equal to */
/* the previous sum, for machines that round up instead of using exact */
/* rounding. Not that this library will work on such machines anyway. */
do {
lastcheck = check;
epsilon *= half;
if (every_other) {
splitter *= 2.0;
}
every_other = !every_other;
check = 1.0 + epsilon;
} while ((check != 1.0) && (check != lastcheck));
splitter += 1.0;
/* Error bounds for orientation and incircle tests. */
resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;
ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;
iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
isperrboundA = (16.0 + 224.0 * epsilon) * epsilon;
isperrboundB = (5.0 + 72.0 * epsilon) * epsilon;
isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon;
}
} constants;
template<unsigned U, unsigned V>
struct op {
enum {
Vlo = V / 2,
Vhi = V - Vlo
};
static inline void add(const double *a, const double *b, double *r) {
double t[U + Vlo];
op<U, Vlo>::add(a, b, t);
for (size_t i = 0; i < Vlo; ++i) r[i] = t[i];
op<U, Vhi>::add(t + Vlo, b + Vlo, r + Vlo);
}
static inline void sub(const double *a, const double *b, double *r) {
double t[U + Vlo];
op<U, Vlo>::sub(a, b, t);
for (size_t i = 0; i < Vlo; ++i) r[i] = t[i];
op<U, Vhi>::sub(t + Vlo, b + Vlo, r + Vlo);
}
};
template<unsigned U>
struct op<U, 1> {
enum {
Ulo = U / 2,
Uhi = U - Ulo
};
static void add(const double *a, const double *b, double *r) {
double t[Ulo + 1];
op<Ulo, 1>::add(a, b, t);
for (size_t i = 0; i < Ulo; ++i) r[i] = t[i];
op<Uhi, 1>::add(a + Ulo, t + Ulo, r + Ulo);
}
static void sub(const double *a, const double *b, double *r) {
double t[Ulo + 1];
op<Ulo, 1>::sub(a, b, t);
for (size_t i = 0; i < Ulo; ++i) r[i] = t[i];
op<Uhi, 1>::add(a + Ulo, t + Ulo, r + Ulo);
}
};
template<>
struct op<1, 1> {
static void add_fast(const double *a, const double *b, double *r) {
assert(fabs(a[0]) >= fabs(b[0]));
volatile double sum = a[0] + b[0];
volatile double bvirt = sum - a[0];
r[0] = b[0] - bvirt;
r[1] = sum;
}
static void sub_fast(const double *a, const double *b, double *r) {
assert(fabs(a[0]) >= fabs(b[0]));
volatile double diff = a[0] - b[0];
volatile double bvirt = a[0] - diff;
r[0] = bvirt - b[0];
r[1] = diff;
}
static void add(const double *a, const double *b, double *r) {
volatile double sum = a[0] + b[0];
volatile double bvirt = sum - a[0];
double avirt = sum - bvirt;
double bround = b[0] - bvirt;
double around = a[0] - avirt;
r[0] = around + bround;
r[1] = sum;
}
static void sub(const double *a, const double *b, double *r) {
volatile double diff = a[0] - b[0];
volatile double bvirt = a[0] - diff;
double avirt = diff + bvirt;
double bround = bvirt - b[0];
double around = a[0] - avirt;
r[0] = around + bround;
r[1] = diff;
}
};
template<unsigned U, unsigned V>
static exact_t add(const double *a, const double *b) {
exact_t result;
result.resize(U + V);
op<U,V>::add(a, b, &result[0]);
return result;
}
template<unsigned U, unsigned V>
static exact_t sub(const double *a, const double *b) {
exact_t result;
result.resize(U + V);
op<U,V>::sub(a, b, &result[0]);
return result;
}
template<unsigned U, unsigned V>
static exact_t add(const exact_t &a, const exact_t &b) {
assert(a.size() == U);
assert(b.size() == V);
exact_t result;
result.resize(U + V);
std::fill(result.begin(), result.end(), std::numeric_limits<double>::quiet_NaN());
op<U,V>::add(&a[0], &b[0], &result[0]);
return result;
}
template<unsigned U, unsigned V>
static exact_t add(const exact_t &a, const double *b) {
assert(a.size() == U);
exact_t result;
result.resize(U + V);
std::fill(result.begin(), result.end(), std::numeric_limits<double>::quiet_NaN());
op<U,V>::add(&a[0], b, &result[0]);
return result;
}
template<unsigned U, unsigned V>
static exact_t sub(const exact_t &a, const exact_t &b) {
assert(a.size() == U);
assert(b.size() == V);
exact_t result;
result.resize(U + V);
std::fill(result.begin(), result.end(), std::numeric_limits<double>::quiet_NaN());
op<U,V>::sub(&a[0], &b[0], &result[0]);
return result;
}
template<unsigned U, unsigned V>
static exact_t sub(const exact_t &a, const double *b) {
assert(a.size() == U);
exact_t result;
result.resize(U + V);
std::fill(result.begin(), result.end(), std::numeric_limits<double>::quiet_NaN());
op<U,V>::sub(&a[0], &b[0], &result[0]);
return result;
}
static inline void split(const double a, double *r) {
volatile double c = constants.splitter * a;
volatile double abig = c - a;
r[1] = c - abig;
r[0] = a - r[1];
}
static inline void prod_1_1(const double *a, const double *b, double *r) {
r[1] = a[0] * b[0];
double a_sp[2]; split(a[0], a_sp);
double b_sp[2]; split(b[0], b_sp);
double err1 = r[1] - a_sp[1] * b_sp[1];
double err2 = err1 - a_sp[0] * b_sp[1];
double err3 = err2 - a_sp[1] * b_sp[0];
r[0] = a_sp[0] * b_sp[0] - err3;
}
static inline void prod_1_1s(const double *a, const double *b, const double *b_sp, double *r) {
r[1] = a[0] * b[0];
double a_sp[2]; split(a[0], a_sp);
double err1 = r[1] - a_sp[1] * b_sp[1];
double err2 = err1 - a_sp[0] * b_sp[1];
double err3 = err2 - a_sp[1] * b_sp[0];
r[0] = a_sp[0] * b_sp[0] - err3;
}
static inline void prod_1s_1s(const double *a, const double *a_sp, const double *b, const double *b_sp, double *r) {
r[1] = a[0] * b[0];
double err1 = r[1] - a_sp[1] * b_sp[1];
double err2 = err1 - a_sp[0] * b_sp[1];
double err3 = err2 - a_sp[1] * b_sp[0];
r[0] = a_sp[0] * b_sp[0] - err3;
}
static inline void prod_2_1(const double *a, const double *b, double *r) {
double b_sp[2]; split(b[0], b_sp);
double t1[2]; prod_1_1s(a+0, b, b_sp, t1);
r[0] = t1[0];
double t2[2]; prod_1_1s(a+1, b, b_sp, t2);
double t3[2]; op<1,1>::add(t1+1, t2, t3);
r[1] = t3[0];
double t4[2]; op<1,1>::add_fast(t2+1, t3+1, r + 2);
}
static inline void prod_1_2(const double *a, const double *b, double *r) {
prod_2_1(b, a, r);
}
static inline void prod_4_1(const double *a, const double *b, double *r) {
double b_sp[2]; split(b[0], b_sp);
double t1[2]; prod_1_1s(a+0, b, b_sp, t1);
r[0] = t1[0];
double t2[2]; prod_1_1s(a+1, b, b_sp, t2);
double t3[2]; op<1,1>::add(t1+1, t2, t3);
r[1] = t3[0];
double t4[2]; op<1,1>::add_fast(t2+1, t3+1, t4);
r[2] = t4[0];
double t5[2]; prod_1_1s(a+2, b, b_sp, t5);
double t6[2]; op<1,1>::add(t4+1, t5, t6);
r[3] = t6[0];
double t7[2]; op<1,1>::add_fast(t5+1, t6+1, t7);
r[4] = t7[0];
double t8[2]; prod_1_1s(a+3, b, b_sp, t8);
double t9[2]; op<1,1>::add(t7+1, t8, t9);
r[5] = t9[0];
op<1,1>::add_fast(t8+1, t9+1, r + 6);
}
static inline void prod_1_4(const double *a, const double *b, double *r) {
prod_4_1(b, a, r);
}
static inline void prod_2_2(const double *a, const double *b, double *r) {
double a1_sp[2]; split(a[1], a1_sp);
double a0_sp[2]; split(a[0], a0_sp);
double b1_sp[2]; split(b[1], b1_sp);
double b0_sp[2]; split(b[0], b0_sp);
double t1[2]; prod_1s_1s(a+0, a0_sp, b+0, b0_sp, t1);
r[0] = t1[0];
double t2[2]; prod_1s_1s(a+1, a1_sp, b+0, b0_sp, t2);
double t3[2]; op<1,1>::add(t1+1, t2, t3);
double t4[2]; op<1,1>::add_fast(t2+1, t3+1, t4);
double t5[2]; prod_1s_1s(a+0, a0_sp, b+1, b1_sp, t5);
double t6[2]; op<1,1>::add(t3, t5, t6);
r[1] = t6[0];
double t7[2]; op<1,1>::add(t4, t6+1, t7);
double t8[2]; op<1,1>::add(t4+1, t7+1, t8);
double t9[2]; prod_1s_1s(a+1, a1_sp, b+1, b1_sp, t9);
double t10[2]; op<1,1>::add(t5+1, t9, t10);
double t11[2]; op<1,1>::add(t7, t10, t11);
r[2] = t11[0];
double t12[2]; op<1,1>::add(t8, t11+1, t12);
double t13[2]; op<1,1>::add(t8+1, t12+1, t13);
double t14[2]; op<1,1>::add(t9+1, t10+1, t14);
double t15[2]; op<1,1>::add(t12, t14, t15);
r[3] = t15[0];
double t16[2]; op<1,1>::add(t13, t15+1, t16);
double t17[2]; op<1,1>::add(t13+1, t16+1, t17);
double t18[2]; op<1,1>::add(t16, t14+1, t18);
r[4] = t18[0];
double t19[2]; op<1,1>::add(t17, t18+1, t19);
r[5] = t19[0];
double t20[2]; op<1,1>::add(t17+1, t19+1, t20);
r[6] = t20[0];
r[7] = t20[1];
}
static inline void square(const double a, double *r) {
r[1] = a * a;
double a_sp[2]; split(a, a_sp);
double err1 = r[1] - (a_sp[1] * a_sp[1]);
double err3 = err1 - ((a_sp[1] + a_sp[1]) * a_sp[0]);
r[0] = a_sp[0] * a_sp[0] - err3;
}
static inline void square_2(const double *a, double *r) {
double t1[2]; square(a[0], t1);
r[0] = t1[0];
double t2 = a[0] + a[0];
double t3[2]; prod_1_1(a+1, &t2, t3);
double t4[3]; op<2,1>::add(t3, t1 + 1, t4);
r[1] = t4[0];
double t5[2]; square(a[1], t5);
double t6[4]; op<2,2>::add(t5, t4 + 1, r + 2);
}
}
void exact_t::compress() {
double sum[2];
int j = size() - 1;
double Q = (*this)[j];
for (int i = (int)size()-2; i >= 0; --i) {
detail::op<1,1>::add_fast(&Q, &(*this)[i], sum);
if (sum[0] != 0) {
(*this)[j--] = sum[1];
Q = sum[0];
} else {
Q = sum[1];
}
}
int j2 = 0;
for (int i = j + 1; i < (int)size(); ++i) {
detail::op<1,1>::add_fast(&(*this)[i], &Q, sum);
if (sum[0] != 0) {
(*this)[j2++] = sum[0];
}
Q = sum[1];
}
(*this)[j2++] = Q;
erase(begin() + j2, end());
}
template<typename iter_t>
void negate(iter_t begin, iter_t end) {
while (begin != end) { *begin = -*begin; ++begin; }
}
void negate(exact_t &e) {
negate(&e[0], &e[e.size()]);
}
template<typename iter_t>
void scale_zeroelim(iter_t ebegin,
iter_t eend,
double b,
exact_t &h) {
double Q;
h.clear();
double b_sp[2]; detail::split(b, b_sp);
double prod[2], sum[2];
detail::prod_1_1s((double *)ebegin++, &b, b_sp, prod);
Q = prod[1];
if (prod[0] != 0.0) {
h.push_back(prod[0]);
}
while (ebegin != eend) {
double enow = *ebegin++;
detail::prod_1_1s(&enow, &b, b_sp, prod);
detail::op<1,1>::add(&Q, prod, sum);
if (sum[0] != 0) {
h.push_back(sum[0]);
}
detail::op<1,1>::add_fast(prod+1, sum+1, sum);
Q = sum[1];
if (sum[0] != 0) {
h.push_back(sum[0]);
}
}
if ((Q != 0.0) || (h.size() == 0)) {
h.push_back(Q);
}
}
void scale_zeroelim(const exact_t &e,
double b,
exact_t &h) {
scale_zeroelim(&e[0], &e[e.size()], b, h);
}
template<typename iter_t>
void sum_zeroelim(iter_t ebegin,
iter_t eend,
iter_t fbegin,
iter_t fend,
exact_t &h) {
double Q;
double enow, fnow;
double sum[2];
enow = *ebegin;
fnow = *fbegin;
h.clear();
if ((fnow > enow) == (fnow > -enow)) {
Q = enow;
enow = *++ebegin;
} else {
Q = fnow;
fnow = *++fbegin;
}
if (ebegin != eend && fbegin != fend) {
if ((fnow > enow) == (fnow > -enow)) {
detail::op<1,1>::add_fast(&enow, &Q, sum);
enow = *++ebegin;
} else {
detail::op<1,1>::add_fast(&fnow, &Q, sum);
fnow = *++fbegin;
}
Q = sum[1];
if (sum[0] != 0.0) {
h.push_back(sum[0]);
}
while (ebegin != eend && fbegin != fend) {
if ((fnow > enow) == (fnow > -enow)) {
detail::op<1,1>::add(&Q, &enow, sum);
enow = *++ebegin;
} else {
detail::op<1,1>::add(&Q, &fnow, sum);
fnow = *++fbegin;
}
Q = sum[1];
if (sum[0] != 0.0) {
h.push_back(sum[0]);
}
}
}
while (ebegin != eend) {
detail::op<1,1>::add(&Q, &enow, sum);
enow = *++ebegin;
Q = sum[1];
if (sum[0] != 0.0) {
h.push_back(sum[0]);
}
}
while (fbegin != fend) {
detail::op<1,1>::add(&Q, &fnow, sum);
fnow = *++fbegin;
Q = sum[1];
if (sum[0] != 0.0) {
h.push_back(sum[0]);
}
}
if (Q != 0.0 || !h.size()) {
h.push_back(Q);
}
}
void sum_zeroelim(const exact_t &e,
const exact_t &f,
exact_t &h) {
sum_zeroelim(&e[0], &e[e.size()], &f[0], &f[f.size()], h);
}
void sum_zeroelim(const double *ebegin,
const double *eend,
const exact_t &f,
exact_t &h) {
sum_zeroelim(ebegin, eend, &f[0], &f[f.size()], h);
}
void sum_zeroelim(const exact_t &e,
const double *fbegin,
const double *fend,
exact_t &h) {
sum_zeroelim(&e[0], &e[e.size()], fbegin, fend, h);
}
exact_t operator+(const exact_t &a, const exact_t &b) {
exact_t r;
sum_zeroelim(a, b, r);
return r;
}
void diffprod(const double a, const double b, const double c, const double d, double *r) {
// return ab - cd;
double ab[2], cd[2];
detail::prod_1_1(&a, &b, ab);
detail::prod_1_1(&c, &d, cd);
detail::op<2,2>::sub(ab, cd, r);
}
double orient3dexact(const double *pa,
const double *pb,
const double *pc,
const double *pd) {
using namespace detail;
double ab[4]; diffprod(pa[0], pb[1], pb[0], pa[1], ab);
double bc[4]; diffprod(pb[0], pc[1], pc[0], pb[1], bc);
double cd[4]; diffprod(pc[0], pd[1], pd[0], pc[1], cd);
double da[4]; diffprod(pd[0], pa[1], pa[0], pd[1], da);
double ac[4]; diffprod(pa[0], pc[1], pc[0], pa[1], ac);
double bd[4]; diffprod(pb[0], pd[1], pd[0], pb[1], bd);
exact_t temp;
exact_t cda, dab, abc, bcd;
exact_t adet, bdet, cdet, ddet, abdet, cddet, det;
sum_zeroelim(cd, cd + 4, da, da + 4, temp);
sum_zeroelim(temp, ac, ac + 4, cda);
sum_zeroelim(da, da + 4, ab, ab + 4, temp);
sum_zeroelim(temp, bd, bd + 4, dab);
negate(bd, bd + 4);
negate(ac, bd + 4);
sum_zeroelim(ab, ab + 4, bc, bc + 4, temp);
sum_zeroelim(temp, ac, ac + 4, abc);
sum_zeroelim(bc, bc + 4, cd, cd + 4, temp);
sum_zeroelim(temp, bd, bd + 4, bcd);
scale_zeroelim(bcd, +pa[2], adet);
scale_zeroelim(cda, -pb[2], bdet);
scale_zeroelim(dab, +pc[2], cdet);
scale_zeroelim(abc, -pd[2], ddet);
sum_zeroelim(adet, bdet, abdet);
sum_zeroelim(cdet, ddet, cddet);
sum_zeroelim(abdet, cddet, det);
return det[det.size() - 1];
}
}
}

208
extern/carve/include/carve/face_decl.hpp vendored Normal file
View File

@@ -0,0 +1,208 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom2d.hpp>
#include <carve/vector.hpp>
#include <carve/matrix.hpp>
#include <carve/geom3d.hpp>
#include <carve/aabb.hpp>
#include <carve/tag.hpp>
#include <vector>
#include <list>
#include <map>
namespace carve {
namespace poly {
struct Object;
template<unsigned ndim>
class Edge;
template<unsigned ndim>
struct p2_adapt_project {
typedef carve::geom2d::P2 (*proj_t)(const carve::geom::vector<ndim> &);
proj_t proj;
p2_adapt_project(proj_t _proj) : proj(_proj) { }
carve::geom2d::P2 operator()(const carve::geom::vector<ndim> &v) const { return proj(v); }
carve::geom2d::P2 operator()(const carve::geom::vector<ndim> *v) const { return proj(*v); }
carve::geom2d::P2 operator()(const Vertex<ndim> &v) const { return proj(v.v); }
carve::geom2d::P2 operator()(const Vertex<ndim> *v) const { return proj(v->v); }
};
template<unsigned ndim>
class Face : public tagable {
public:
typedef Vertex<ndim> vertex_t;
typedef typename Vertex<ndim>::vector_t vector_t;
typedef Edge<ndim> edge_t;
typedef Object obj_t;
typedef carve::geom::aabb<ndim> aabb_t;
typedef carve::geom::plane<ndim> plane_t;
typedef carve::geom2d::P2 (*project_t)(const vector_t &);
typedef vector_t (*unproject_t)(const carve::geom2d::P2 &, const plane_t &);
protected:
std::vector<const vertex_t *> vertices; // pointer into polyhedron.vertices
std::vector<const edge_t *> edges; // pointer into polyhedron.edges
project_t getProjector(bool positive_facing, int axis);
unproject_t getUnprojector(bool positive_facing, int axis);
public:
typedef typename std::vector<const vertex_t *>::iterator vertex_iter_t;
typedef typename std::vector<const vertex_t *>::const_iterator const_vertex_iter_t;
typedef typename std::vector<const edge_t *>::iterator edge_iter_t;
typedef typename std::vector<const edge_t *>::const_iterator const_edge_iter_t;
obj_t *owner;
aabb_t aabb;
plane_t plane_eqn;
int manifold_id;
int group_id;
project_t project;
unproject_t unproject;
Face(const std::vector<const vertex_t *> &_vertices, bool delay_recalc = false);
Face(const vertex_t *v1, const vertex_t *v2, const vertex_t *v3, bool delay_recalc = false);
Face(const vertex_t *v1, const vertex_t *v2, const vertex_t *v3, const vertex_t *v4, bool delay_recalc = false);
template <typename iter_t>
Face(const Face *base, iter_t vbegin, iter_t vend, bool flipped) {
init(base, vbegin, vend, flipped);
}
Face(const Face *base, const std::vector<const vertex_t *> &_vertices, bool flipped) {
init(base, _vertices, flipped);
}
Face() {}
~Face() {}
bool recalc();
template<typename iter_t>
Face *init(const Face *base, iter_t vbegin, iter_t vend, bool flipped);
Face *init(const Face *base, const std::vector<const vertex_t *> &_vertices, bool flipped);
template<typename iter_t>
Face *create(iter_t vbegin, iter_t vend, bool flipped) const;
Face *create(const std::vector<const vertex_t *> &_vertices, bool flipped) const;
Face *clone(bool flipped = false) const;
void invert();
void getVertexLoop(std::vector<const vertex_t *> &loop) const;
const vertex_t *&vertex(size_t idx);
const vertex_t *vertex(size_t idx) const;
size_t nVertices() const;
vertex_iter_t vbegin() { return vertices.begin(); }
vertex_iter_t vend() { return vertices.end(); }
const_vertex_iter_t vbegin() const { return vertices.begin(); }
const_vertex_iter_t vend() const { return vertices.end(); }
std::vector<carve::geom::vector<2> > projectedVertices() const;
const edge_t *&edge(size_t idx);
const edge_t *edge(size_t idx) const;
size_t nEdges() const;
edge_iter_t ebegin() { return edges.begin(); }
edge_iter_t eend() { return edges.end(); }
const_edge_iter_t ebegin() const { return edges.begin(); }
const_edge_iter_t eend() const { return edges.end(); }
bool containsPoint(const vector_t &p) const;
bool containsPointInProjection(const vector_t &p) const;
bool simpleLineSegmentIntersection(const carve::geom::linesegment<ndim> &line,
vector_t &intersection) const;
IntersectionClass lineSegmentIntersection(const carve::geom::linesegment<ndim> &line,
vector_t &intersection) const;
vector_t centroid() const;
p2_adapt_project<ndim> projector() const {
return p2_adapt_project<ndim>(project);
}
void swap(Face<ndim> &other);
};
struct hash_face_ptr {
template<unsigned ndim>
size_t operator()(const Face<ndim> * const &f) const {
return (size_t)f;
}
};
namespace face {
template<unsigned ndim>
static inline carve::geom2d::P2 project(const Face<ndim> *f, const typename Face<ndim>::vector_t &v) {
return f->project(v);
}
template<unsigned ndim>
static inline carve::geom2d::P2 project(const Face<ndim> &f, const typename Face<ndim>::vector_t &v) {
return f.project(v);
}
template<unsigned ndim>
static inline typename Face<ndim>::vector_t unproject(const Face<ndim> *f, const carve::geom2d::P2 &p) {
return f->unproject(p, f->plane_eqn);
}
template<unsigned ndim>
static inline typename Face<ndim>::vector_t unproject(const Face<ndim> &f, const carve::geom2d::P2 &p) {
return f.unproject(p, f.plane_eqn);
}
}
}
}

142
extern/carve/include/carve/face_impl.hpp vendored Normal file
View File

@@ -0,0 +1,142 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
namespace std {
template<unsigned ndim>
inline void swap(carve::poly::Face<ndim> &a, carve::poly::Face<ndim> &b) {
a.swap(b);
}
}
namespace carve {
namespace poly {
template<unsigned ndim>
void Face<ndim>::swap(Face<ndim> &other) {
std::swap(vertices, other.vertices);
std::swap(edges, other.edges);
std::swap(owner, other.owner);
std::swap(aabb, other.aabb);
std::swap(plane_eqn, other.plane_eqn);
std::swap(manifold_id, other.manifold_id);
std::swap(group_id, other.group_id);
std::swap(project, other.project);
std::swap(unproject, other.unproject);
}
template<unsigned ndim>
template<typename iter_t>
Face<ndim> *Face<ndim>::init(const Face<ndim> *base, iter_t vbegin, iter_t vend, bool flipped) {
CARVE_ASSERT(vbegin < vend);
vertices.reserve((size_t)std::distance(vbegin, vend));
if (flipped) {
std::reverse_copy(vbegin, vend, std::back_inserter(vertices));
plane_eqn = -base->plane_eqn;
} else {
std::copy(vbegin, vend, std::back_inserter(vertices));
plane_eqn = base->plane_eqn;
}
edges.clear();
edges.resize(nVertices(), NULL);
aabb.fit(vertices.begin(), vertices.end(), vec_adapt_vertex_ptr());
untag();
int da = carve::geom::largestAxis(plane_eqn.N);
project = getProjector(plane_eqn.N.v[da] > 0, da);
unproject = getUnprojector(plane_eqn.N.v[da] > 0, da);
return this;
}
template<unsigned ndim>
template<typename iter_t>
Face<ndim> *Face<ndim>::create(iter_t vbegin, iter_t vend, bool flipped) const {
return (new Face)->init(this, vbegin, vend, flipped);
}
template<unsigned ndim>
Face<ndim> *Face<ndim>::create(const std::vector<const vertex_t *> &_vertices, bool flipped) const {
return (new Face)->init(this, _vertices.begin(), _vertices.end(), flipped);
}
template<unsigned ndim>
Face<ndim> *Face<ndim>::clone(bool flipped) const {
return (new Face)->init(this, vertices, flipped);
}
template<unsigned ndim>
void Face<ndim>::getVertexLoop(std::vector<const vertex_t *> &loop) const {
loop.resize(nVertices(), NULL);
std::copy(vbegin(), vend(), loop.begin());
}
template<unsigned ndim>
const typename Face<ndim>::edge_t *&Face<ndim>::edge(size_t idx) {
return edges[idx];
}
template<unsigned ndim>
const typename Face<ndim>::edge_t *Face<ndim>::edge(size_t idx) const {
return edges[idx];
}
template<unsigned ndim>
size_t Face<ndim>::nEdges() const {
return edges.size();
}
template<unsigned ndim>
const typename Face<ndim>::vertex_t *&Face<ndim>::vertex(size_t idx) {
return vertices[idx];
}
template<unsigned ndim>
const typename Face<ndim>::vertex_t *Face<ndim>::vertex(size_t idx) const {
return vertices[idx];
}
template<unsigned ndim>
size_t Face<ndim>::nVertices() const {
return vertices.size();
}
template<unsigned ndim>
typename Face<ndim>::vector_t Face<ndim>::centroid() const {
vector_t c;
carve::geom::centroid(vertices.begin(), vertices.end(), vec_adapt_vertex_ptr(), c);
return c;
}
template<unsigned ndim>
std::vector<carve::geom::vector<2> > Face<ndim>::projectedVertices() const {
p2_adapt_project<ndim> proj = projector();
std::vector<carve::geom::vector<2> > result;
result.reserve(nVertices());
for (size_t i = 0; i < nVertices(); ++i) {
result.push_back(proj(vertex(i)->v));
}
return result;
}
}
}

103
extern/carve/include/carve/faceloop.hpp vendored Normal file
View File

@@ -0,0 +1,103 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/classification.hpp>
#include <carve/collection_types.hpp>
namespace carve {
namespace csg {
struct FaceLoopGroup;
struct FaceLoop {
FaceLoop *next, *prev;
const carve::mesh::MeshSet<3>::face_t *orig_face;
std::vector<carve::mesh::MeshSet<3>::vertex_t *> vertices;
FaceLoopGroup *group;
FaceLoop(const carve::mesh::MeshSet<3>::face_t *f, const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &v) : next(NULL), prev(NULL), orig_face(f), vertices(v), group(NULL) {}
};
struct FaceLoopList {
FaceLoop *head, *tail;
unsigned count;
FaceLoopList() : head(NULL), tail(NULL), count(0) { }
void append(FaceLoop *f) {
f->prev = tail;
f->next = NULL;
if (tail) tail->next = f;
tail = f;
if (!head) head = f;
count++;
}
void prepend(FaceLoop *f) {
f->next = head;
f->prev = NULL;
if (head) head->prev = f;
head = f;
if (!tail) tail = f;
count++;
}
unsigned size() const {
return count;
}
FaceLoop *remove(FaceLoop *f) {
FaceLoop *r = f->next;
if (f->prev) { f->prev->next = f->next; } else { head = f->next; }
if (f->next) { f->next->prev = f->prev; } else { tail = f->prev; }
f->next = f->prev = NULL;
count--;
return r;
}
~FaceLoopList() {
FaceLoop *a = head, *b;
while (a) {
b = a;
a = a->next;
delete b;
}
}
};
struct FaceLoopGroup {
const carve::mesh::MeshSet<3> *src;
FaceLoopList face_loops;
V2Set perimeter;
std::list<ClassificationInfo> classification;
FaceLoopGroup(const carve::mesh::MeshSet<3> *_src) : src(_src) {
}
FaceClass classificationAgainst(const carve::mesh::MeshSet<3>::mesh_t *mesh) const;
};
typedef std::list<FaceLoopGroup> FLGroupList;
}
}

367
extern/carve/include/carve/geom.hpp vendored Normal file
View File

@@ -0,0 +1,367 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <vector>
namespace carve {
namespace geom {
template<unsigned ndim> struct aabb;
// ========================================================================
struct _uninitialized { };
template<unsigned ndim>
struct base {
double v[ndim];
};
template<> struct base<2> {union { double v[2]; struct { double x, y; }; }; };
template<> struct base<3> {union { double v[3]; struct { double x, y, z; }; }; };
template<> struct base<4> {union { double v[4]; struct { double x, y, z, w; }; }; };
template<unsigned ndim>
struct vector : public base<ndim> {
enum { __ndim = ndim };
static vector ZERO();
double length2() const;
double length() const;
vector<ndim> &normalize();
vector<ndim> normalized() const;
bool exactlyZero() const;
bool isZero(double epsilon = EPSILON) const;
void setZero();
void fill(double val);
vector<ndim> &scaleBy(double d);
vector<ndim> &invscaleBy(double d);
vector<ndim> scaled(double d) const;
vector<ndim> invscaled(double d) const;
vector<ndim> &negate();
vector<ndim> negated() const;
double &operator[](unsigned i);
const double &operator[](unsigned i) const;
template<typename assign_t>
vector<ndim> &operator=(const assign_t &t);
std::string asStr() const;
aabb<ndim> getAABB() const;
vector() { setZero(); }
vector(noinit_t) { }
};
template<unsigned ndim>
vector<ndim> vector<ndim>::ZERO() { vector<ndim> r; r.setZero(); return r; }
static inline vector<2> VECTOR(double x, double y) { vector<2> r; r.x = x; r.y = y; return r; }
static inline vector<3> VECTOR(double x, double y, double z) { vector<3> r; r.x = x; r.y = y; r.z = z; return r; }
static inline vector<4> VECTOR(double x, double y, double z, double w) { vector<4> r; r.x = x; r.y = y; r.z = z; r.w = w; return r; }
template<unsigned ndim> vector<ndim> operator+(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> vector<ndim> operator+(const vector<ndim> &a, double b);
template<unsigned ndim, typename val_t> vector<ndim> operator+(const vector<ndim> &a, const val_t &b);
template<unsigned ndim, typename val_t> vector<ndim> operator+(const val_t &a, const vector<ndim> &b);
template<unsigned ndim> vector<ndim> &operator+=(vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> vector<ndim> &operator+=(vector<ndim> &a, double b);
template<unsigned ndim, typename val_t> vector<ndim> &operator+=(vector<ndim> &a, const val_t &b);
template<unsigned ndim> vector<ndim> operator-(const vector<ndim> &a);
template<unsigned ndim> vector<ndim> operator-(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> vector<ndim> operator-(const vector<ndim> &a, double b);
template<unsigned ndim, typename val_t> vector<ndim> operator-(const vector<ndim> &a, const val_t &b);
template<unsigned ndim, typename val_t> vector<ndim> operator-(const val_t &a, const vector<ndim> &b);
template<unsigned ndim> vector<ndim> &operator-=(vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> vector<ndim> &operator-=(vector<ndim> &a, double b);
template<unsigned ndim, typename val_t> vector<ndim> &operator-=(vector<ndim> &a, const val_t &b);
template<unsigned ndim> vector<ndim> operator*(const vector<ndim> &a, double s);
template<unsigned ndim> vector<ndim> operator*(double s, const vector<ndim> &a);
template<unsigned ndim> vector<ndim> &operator*=(vector<ndim> &a, double s);
template<unsigned ndim> vector<ndim> operator/(const vector<ndim> &a, double s);
template<unsigned ndim> vector<ndim> &operator/=(vector<ndim> &a, double s);
template<unsigned ndim> bool operator==(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> bool operator!=(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> bool operator<(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> bool operator<=(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> bool operator>(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> bool operator>=(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> vector<ndim> abs(const vector<ndim> &a);
template<unsigned ndim> double distance2(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> double distance(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> bool equal(const vector<ndim> &a, const vector<ndim> &b);
template<unsigned ndim> int smallestAxis(const vector<ndim> &a);
template<unsigned ndim> int largestAxis(const vector<ndim> &a);
template<unsigned ndim> vector<2> select(const vector<ndim> &a, int a1, int a2);
template<unsigned ndim> vector<3> select(const vector<ndim> &a, int a1, int a2, int a3);
template<unsigned ndim, typename assign_t, typename oper_t>
vector<ndim> &assign_op(vector<ndim> &a, const assign_t &t, oper_t op);
template<unsigned ndim, typename assign1_t, typename assign2_t, typename oper_t>
vector<ndim> &assign_op(vector<ndim> &a, const assign1_t &t1, const assign2_t &t2, oper_t op);
template<unsigned ndim, typename iter_t>
void bounds(iter_t begin, iter_t end, vector<ndim> &min, vector<ndim> &max);
template<unsigned ndim, typename iter_t, typename adapt_t>
void bounds(iter_t begin, iter_t end, adapt_t adapt, vector<ndim> &min, vector<ndim> &max);
template<unsigned ndim, typename iter_t>
void centroid(iter_t begin, iter_t end, vector<ndim> &c);
template<unsigned ndim, typename iter_t, typename adapt_t>
void centroid(iter_t begin, iter_t end, adapt_t adapt, vector<ndim> &c);
template<unsigned ndim, typename val_t> double dot(const vector<ndim> &a, const val_t &b);
static inline vector<3> cross(const vector<3> &a, const vector<3> &b);
static inline double cross(const vector<2> &a, const vector<2> &b);
static inline double dotcross(const vector<3> &a, const vector<3> &b, const vector<3> &c);
// ========================================================================
struct axis_pos {
int axis;
double pos;
axis_pos(int _axis, double _pos) : axis(_axis), pos(_pos) { }
};
template<unsigned ndim>
double distance(const axis_pos &a, const vector<ndim> &b);
template<unsigned ndim>
double distance2(const axis_pos &a, const vector<ndim> &b);
template<unsigned ndim> bool operator<(const axis_pos &a, const vector<ndim> &b);
template<unsigned ndim> bool operator<(const vector<ndim> &a, const axis_pos &b);
template<unsigned ndim> bool operator<=(const axis_pos &a, const vector<ndim> &b);
template<unsigned ndim> bool operator<=(const vector<ndim> &a, const axis_pos &b);
template<unsigned ndim> bool operator>(const axis_pos &a, const vector<ndim> &b);
template<unsigned ndim> bool operator>(const vector<ndim> &a, const axis_pos &b);
template<unsigned ndim> bool operator>=(const axis_pos &a, const vector<ndim> &b);
template<unsigned ndim> bool operator>=(const vector<ndim> &a, const axis_pos &b);
template<unsigned ndim> bool operator==(const axis_pos &a, const vector<ndim> &b);
template<unsigned ndim> bool operator==(const vector<ndim> &a, const axis_pos &b);
template<unsigned ndim> bool operator!=(const axis_pos &a, const vector<ndim> &b);
template<unsigned ndim> bool operator!=(const vector<ndim> &a, const axis_pos &b);
// ========================================================================
template<unsigned ndim>
struct ray {
typedef vector<ndim> vector_t;
vector_t D, v;
bool OK() const;
ray() { }
ray(vector_t _D, vector_t _v) : D(_D), v(_v) { }
};
template<unsigned ndim>
ray<ndim> rayThrough(const vector<ndim> &a, const vector<ndim> &b);
static inline double distance2(const ray<3> &r, const vector<3> &v);
static inline double distance(const ray<3> &r, const vector<3> &v);
static inline double distance2(const ray<2> &r, const vector<2> &v);
static inline double distance(const ray<2> &r, const vector<2> &v);
// ========================================================================
template<unsigned ndim>
struct linesegment {
typedef vector<ndim> vector_t;
vector_t v1;
vector_t v2;
vector_t midpoint;
vector_t half_length;
void update();
bool OK() const;
void flip();
aabb<ndim> getAABB() const;
linesegment(const vector_t &_v1, const vector_t &_v2);
};
template<unsigned ndim>
double distance2(const linesegment<ndim> &l, const vector<ndim> &v);
template<unsigned ndim>
double distance(const linesegment<ndim> &l, const vector<ndim> &v);
// ========================================================================
template<unsigned ndim>
struct plane {
typedef vector<ndim> vector_t;
vector_t N;
double d;
void negate();
plane();
plane(const vector_t &_N, vector_t _p);
plane(const vector_t &_N, double _d);
};
template<unsigned ndim>
inline plane<ndim> operator-(const plane<ndim> &p);
template<unsigned ndim, typename val_t>
double distance(const plane<ndim> &plane, const val_t &point);
template<unsigned ndim, typename val_t>
double distance2(const plane<ndim> &plane, const val_t &point);
template<unsigned ndim>
static inline vector<ndim> closestPoint(const plane<ndim> &p, const vector<ndim> &v);
// ========================================================================
template<unsigned ndim>
struct sphere {
typedef vector<ndim> vector_t;
vector_t C;
double r;
aabb<ndim> getAABB() const;
sphere();
sphere(const vector_t &_C, double _r);
};
template<unsigned ndim, typename val_t>
double distance(const sphere<ndim> &sphere, const val_t &point);
template<unsigned ndim, typename val_t>
double distance2(const sphere<ndim> &sphere, const val_t &point);
template<unsigned ndim>
static inline vector<ndim> closestPoint(const sphere<ndim> &sphere, const vector<ndim> &point);
// ========================================================================
template<unsigned ndim>
struct tri {
typedef vector<ndim> vector_t;
vector_t v[3];
aabb<ndim> getAABB() const;
tri() { }
tri(vector_t _v[3]);
tri(const vector_t &a, const vector_t &b, const vector_t &c);
vector_t normal() const {
return cross(v[1] - v[0], v[2] - v[1]).normalized();
}
};
template<unsigned ndim> std::ostream &operator<<(std::ostream &o, const vector<ndim> &v);
template<unsigned ndim> std::ostream &operator<<(std::ostream &o, const carve::geom::plane<ndim> &p);
template<unsigned ndim> std::ostream &operator<<(std::ostream &o, const carve::geom::sphere<ndim> &sphere);
template<unsigned ndim> std::ostream &operator<<(std::ostream &o, const carve::geom::tri<ndim> &tri);
template<unsigned ndim> vector<ndim> closestPoint(const tri<ndim> &tri, const vector<ndim> &pt);
template<unsigned ndim> double distance(const tri<ndim> &tri, const vector<ndim> &pt);
template<unsigned ndim> double distance2(const tri<ndim> &tri, const vector<ndim> &pt);
// ========================================================================
struct distance_functor {
template<typename obj1_t, typename obj2_t>
double operator()(const obj1_t &o1, const obj2_t &o2) {
return distance(o1, o2);
}
};
// ========================================================================
template<int base, int power> struct __pow__ { enum { val = __pow__<base, (power >> 1)>::val * __pow__<base, power - (power >> 1)>::val }; };
template<int base> struct __pow__<base, 1> { enum { val = base }; };
template<int base> struct __pow__<base, 0> { enum { val = 1 }; };
template<unsigned base, unsigned ndigits>
struct quantize {
typedef __pow__<base, ndigits> fac;
double operator()(double in) {
return round(in * fac::val) / fac::val;
}
template<unsigned ndim>
vector<ndim> operator()(const vector<ndim> &in) {
vector<ndim> r(NOINIT);
assign_op(r, in, *this);
return r;
}
};
}
}
#include <carve/geom_impl.hpp>

403
extern/carve/include/carve/geom2d.hpp vendored Normal file
View File

@@ -0,0 +1,403 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/math.hpp>
#include <carve/math_constants.hpp>
#include <carve/geom.hpp>
#include <vector>
#include <algorithm>
#include <math.h>
#if defined(CARVE_DEBUG)
# include <iostream>
#endif
#if defined CARVE_USE_EXACT_PREDICATES
# include <carve/shewchuk_predicates.hpp>
#endif
namespace carve {
namespace geom2d {
typedef carve::geom::vector<2> P2;
typedef carve::geom::ray<2> Ray2;
typedef carve::geom::linesegment<2> LineSegment2;
struct p2_adapt_ident {
P2 &operator()(P2 &p) const { return p; }
const P2 &operator()(const P2 &p) const { return p; }
};
typedef std::vector<P2> P2Vector;
/**
* \brief Return the orientation of c with respect to the ray defined by a->b.
*
* (Can be implemented exactly)
*
* @param[in] a
* @param[in] b
* @param[in] c
*
* @return positive, if c to the left of a->b.
* zero, if c is colinear with a->b.
* negative, if c to the right of a->b.
*/
#if defined CARVE_USE_EXACT_PREDICATES
inline double orient2d(const P2 &a, const P2 &b, const P2 &c) {
return shewchuk::orient2d(a.v, b.v, c.v);
}
#else
inline double orient2d(const P2 &a, const P2 &b, const P2 &c) {
double acx = a.x - c.x;
double bcx = b.x - c.x;
double acy = a.y - c.y;
double bcy = b.y - c.y;
return acx * bcy - acy * bcx;
}
#endif
/**
* \brief Determine whether p is internal to the anticlockwise
* angle abc, where b is the apex of the angle.
*
* @param[in] a
* @param[in] b
* @param[in] c
* @param[in] p
*
* @return true, if p is contained in the anticlockwise angle from
* b->a to b->c. Reflex angles contain p if p lies
* on b->a or on b->c. Acute angles do not contain p
* if p lies on b->a or on b->c. This is so that
* internalToAngle(a,b,c,p) = !internalToAngle(c,b,a,p)
*/
inline bool internalToAngle(const P2 &a,
const P2 &b,
const P2 &c,
const P2 &p) {
bool reflex = (a < c) ? orient2d(b, a, c) <= 0.0 : orient2d(b, c, a) > 0.0;
double d1 = orient2d(b, a, p);
double d2 = orient2d(b, c, p);
if (reflex) {
return d1 >= 0.0 || d2 <= 0.0;
} else {
return d1 > 0.0 && d2 < 0.0;
}
}
/**
* \brief Determine whether p is internal to the anticlockwise
* angle ac, with apex at (0,0).
*
* @param[in] a
* @param[in] c
* @param[in] p
*
* @return true, if p is contained in a0c.
*/
inline bool internalToAngle(const P2 &a,
const P2 &c,
const P2 &p) {
return internalToAngle(a, P2::ZERO(), c, p);
}
template<typename P2vec>
bool isAnticlockwise(const P2vec &tri) {
return orient2d(tri[0], tri[1], tri[2]) > 0.0;
}
template<typename P2vec>
bool pointIntersectsTriangle(const P2 &p, const P2vec &tri) {
int orient = isAnticlockwise(tri) ? +1 : -1;
if (orient2d(tri[0], tri[1], p) * orient < 0) return false;
if (orient2d(tri[1], tri[2], p) * orient < 0) return false;
if (orient2d(tri[2], tri[0], p) * orient < 0) return false;
return true;
}
template<typename P2vec>
bool lineIntersectsTriangle(const P2 &p1, const P2 &p2, const P2vec &tri) {
double s[3];
// does tri lie on one side or the other of p1-p2?
s[0] = orient2d(p1, p2, tri[0]);
s[1] = orient2d(p1, p2, tri[1]);
s[2] = orient2d(p1, p2, tri[2]);
if (*std::max_element(s, s+3) < 0) return false;
if (*std::min_element(s, s+3) > 0) return false;
// does line lie entirely to the right of a triangle edge?
int orient = isAnticlockwise(tri) ? +1 : -1;
if (orient2d(tri[0], tri[1], p1) * orient < 0 && orient2d(tri[0], tri[1], p2) * orient < 0) return false;
if (orient2d(tri[1], tri[2], p1) * orient < 0 && orient2d(tri[1], tri[2], p2) * orient < 0) return false;
if (orient2d(tri[2], tri[0], p1) * orient < 0 && orient2d(tri[2], tri[0], p2) * orient < 0) return false;
return true;
}
template<typename P2vec>
int triangleLineOrientation(const P2 &p1, const P2 &p2, const P2vec &tri) {
double lo, hi, tmp;
lo = hi = orient2d(p1, p2, tri[0]);
tmp = orient2d(p1, p2, tri[1]); lo = std::min(lo, tmp); hi = std::max(hi, tmp);
tmp = orient2d(p1, p2, tri[2]); lo = std::min(lo, tmp); hi = std::max(hi, tmp);
if (hi < 0.0) return -1;
if (lo > 0.0) return +1;
return 0;
}
template<typename P2vec>
bool triangleIntersectsTriangle(const P2vec &tri_b, const P2vec &tri_a) {
int orient_a = isAnticlockwise(tri_a) ? +1 : -1;
if (triangleLineOrientation(tri_a[0], tri_a[1], tri_b) * orient_a < 0) return false;
if (triangleLineOrientation(tri_a[1], tri_a[2], tri_b) * orient_a < 0) return false;
if (triangleLineOrientation(tri_a[2], tri_a[0], tri_b) * orient_a < 0) return false;
int orient_b = isAnticlockwise(tri_b) ? +1 : -1;
if (triangleLineOrientation(tri_b[0], tri_b[1], tri_a) * orient_b < 0) return false;
if (triangleLineOrientation(tri_b[1], tri_b[2], tri_a) * orient_b < 0) return false;
if (triangleLineOrientation(tri_b[2], tri_b[0], tri_a) * orient_b < 0) return false;
return true;
}
static inline double atan2(const P2 &p) {
return ::atan2(p.y, p.x);
}
struct LineIntersectionInfo {
LineIntersectionClass iclass;
P2 ipoint;
int p1, p2;
LineIntersectionInfo(LineIntersectionClass _iclass,
P2 _ipoint = P2::ZERO(),
int _p1 = -1,
int _p2 = -1) :
iclass(_iclass), ipoint(_ipoint), p1(_p1), p2(_p2) {
}
};
struct PolyInclusionInfo {
PointClass iclass;
int iobjnum;
PolyInclusionInfo(PointClass _iclass,
int _iobjnum = -1) :
iclass(_iclass), iobjnum(_iobjnum) {
}
};
struct PolyIntersectionInfo {
IntersectionClass iclass;
P2 ipoint;
size_t iobjnum;
PolyIntersectionInfo(IntersectionClass _iclass,
const P2 &_ipoint,
size_t _iobjnum) :
iclass(_iclass), ipoint(_ipoint), iobjnum(_iobjnum) {
}
};
bool lineSegmentIntersection_simple(const P2 &l1v1, const P2 &l1v2,
const P2 &l2v1, const P2 &l2v2);
bool lineSegmentIntersection_simple(const LineSegment2 &l1,
const LineSegment2 &l2);
LineIntersectionInfo lineSegmentIntersection(const P2 &l1v1, const P2 &l1v2,
const P2 &l2v1, const P2 &l2v2);
LineIntersectionInfo lineSegmentIntersection(const LineSegment2 &l1,
const LineSegment2 &l2);
int lineSegmentPolyIntersections(const std::vector<P2> &points,
LineSegment2 line,
std::vector<PolyInclusionInfo> &out);
int sortedLineSegmentPolyIntersections(const std::vector<P2> &points,
LineSegment2 line,
std::vector<PolyInclusionInfo> &out);
static inline bool quadIsConvex(const P2 &a, const P2 &b, const P2 &c, const P2 &d) {
double s_1, s_2;
s_1 = carve::geom2d::orient2d(a, c, b);
s_2 = carve::geom2d::orient2d(a, c, d);
if ((s_1 < 0.0 && s_2 < 0.0) || (s_1 > 0.0 && s_2 > 0.0)) return false;
s_1 = carve::geom2d::orient2d(b, d, a);
s_2 = carve::geom2d::orient2d(b, d, c);
if ((s_1 < 0.0 && s_2 < 0.0) || (s_1 > 0.0 && s_2 > 0.0)) return false;
return true;
}
template<typename T, typename adapt_t>
inline bool quadIsConvex(const T &a, const T &b, const T &c, const T &d, adapt_t adapt) {
return quadIsConvex(adapt(a), adapt(b), adapt(c), adapt(d));
}
double signedArea(const std::vector<P2> &points);
static inline double signedArea(const P2 &a, const P2 &b, const P2 &c) {
return ((b.y + a.y) * (b.x - a.x) + (c.y + b.y) * (c.x - b.x) + (a.y + c.y) * (a.x - c.x)) / 2.0;
}
template<typename T, typename adapt_t>
double signedArea(const std::vector<T> &points, adapt_t adapt) {
P2Vector::size_type l = points.size();
double A = 0.0;
for (P2Vector::size_type i = 0; i < l - 1; i++) {
A += (adapt(points[i + 1]).y + adapt(points[i]).y) * (adapt(points[i + 1]).x - adapt(points[i]).x);
}
A += (adapt(points[0]).y + adapt(points[l - 1]).y) * (adapt(points[0]).x - adapt(points[l - 1]).x);
return A / 2.0;
}
template<typename iter_t, typename adapt_t>
double signedArea(iter_t begin, iter_t end, adapt_t adapt) {
double A = 0.0;
P2 p, n;
if (begin == end) return 0.0;
p = adapt(*begin);
for (iter_t c = begin; ++c != end; ) {
P2 n = adapt(*c);
A += (n.y + p.y) * (n.x - p.x);
p = n;
}
n = adapt(*begin);
A += (n.y + p.y) * (n.x - p.x);
return A / 2.0;
}
bool pointInPolySimple(const std::vector<P2> &points, const P2 &p);
template<typename T, typename adapt_t>
bool pointInPolySimple(const std::vector<T> &points, adapt_t adapt, const P2 &p) {
CARVE_ASSERT(points.size() > 0);
P2Vector::size_type l = points.size();
double s = 0.0;
double rp, r0, d;
rp = r0 = atan2(adapt(points[0]) - p);
for (P2Vector::size_type i = 1; i < l; i++) {
double r = atan2(adapt(points[i]) - p);
d = r - rp;
if (d > M_PI) d -= M_TWOPI;
if (d < -M_PI) d += M_TWOPI;
s = s + d;
rp = r;
}
d = r0 - rp;
if (d > M_PI) d -= M_TWOPI;
if (d < -M_PI) d += M_TWOPI;
s = s + d;
return !carve::math::ZERO(s);
}
PolyInclusionInfo pointInPoly(const std::vector<P2> &points, const P2 &p);
template<typename T, typename adapt_t>
PolyInclusionInfo pointInPoly(const std::vector<T> &points, adapt_t adapt, const P2 &p) {
P2Vector::size_type l = points.size();
for (unsigned i = 0; i < l; i++) {
if (equal(adapt(points[i]), p)) return PolyInclusionInfo(POINT_VERTEX, (int)i);
}
for (unsigned i = 0; i < l; i++) {
unsigned j = (i + 1) % l;
if (std::min(adapt(points[i]).x, adapt(points[j]).x) - EPSILON < p.x &&
std::max(adapt(points[i]).x, adapt(points[j]).x) + EPSILON > p.x &&
std::min(adapt(points[i]).y, adapt(points[j]).y) - EPSILON < p.y &&
std::max(adapt(points[i]).y, adapt(points[j]).y) + EPSILON > p.y &&
distance2(carve::geom::rayThrough(adapt(points[i]), adapt(points[j])), p) < EPSILON2) {
return PolyInclusionInfo(POINT_EDGE, (int)i);
}
}
if (pointInPolySimple(points, adapt, p)) {
return PolyInclusionInfo(POINT_IN);
}
return PolyInclusionInfo(POINT_OUT);
}
bool pickContainedPoint(const std::vector<P2> &poly, P2 &result);
template<typename T, typename adapt_t>
bool pickContainedPoint(const std::vector<T> &poly, adapt_t adapt, P2 &result) {
#if defined(CARVE_DEBUG)
std::cerr << "pickContainedPoint ";
for (unsigned i = 0; i < poly.size(); ++i) std::cerr << " " << adapt(poly[i]);
std::cerr << std::endl;
#endif
const size_t S = poly.size();
P2 a, b, c;
for (unsigned i = 0; i < S; ++i) {
a = adapt(poly[i]);
b = adapt(poly[(i + 1) % S]);
c = adapt(poly[(i + 2) % S]);
if (cross(a - b, c - b) < 0) {
P2 p = (a + b + c) / 3;
if (pointInPolySimple(poly, adapt, p)) {
result = p;
return true;
}
}
}
return false;
}
}
}

324
extern/carve/include/carve/geom3d.hpp vendored Normal file
View File

@@ -0,0 +1,324 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom.hpp>
#include <math.h>
#include <carve/math_constants.hpp>
#include <vector>
#include <list>
#include <map>
#if defined(CARVE_DEBUG)
# include <iostream>
#endif
#if defined CARVE_USE_EXACT_PREDICATES
# include <carve/shewchuk_predicates.hpp>
#endif
namespace carve {
namespace geom3d {
typedef carve::geom::plane<3> Plane;
typedef carve::geom::ray<3> Ray;
typedef carve::geom::linesegment<3> LineSegment;
typedef carve::geom::vector<3> Vector;
template<typename iter_t, typename adapt_t>
bool fitPlane(iter_t begin, iter_t end, adapt_t adapt, Plane &plane) {
std::vector<Vector> p;
for (; begin != end; ++begin) {
p.push_back(adapt(*begin));
}
if (p.size() < 3) {
return false;
}
Vector C;
carve::geom::centroid(p.begin(), p.end(), C);
Vector n;
if (p.size() == 3) {
n = cross(p[1] - p[0], p[2] - p[0]);
} else {
const size_t N = p.size();
n = cross(p[N-1] - C, p[0] - C);
if (n < Vector::ZERO()) n.negate();
for (size_t i = 1; i < p.size(); ++i) {
Vector v = cross(p[i] - C, p[i-1] - C);
if (v < Vector::ZERO()) v.negate();
n += v;
}
}
double l = n.length();
if (l == 0.0) {
n.x = 1.0;
n.y = 0.0;
n.z = 0.0;
} else {
n.normalize();
}
plane.N = n;
plane.d = -dot(n, C);
#if defined(CARVE_DEBUG)
if (p.size() > 3) {
std::cerr << "N-gon with " << p.size() << " vertices: fitted distance:";
for (size_t i = 0; i < p.size(); ++i) {
std::cerr << " {" << p[i] << "} " << distance(plane, p[i]);
}
std::cerr << std::endl;
}
#endif
return true;
}
bool planeIntersection(const Plane &a, const Plane &b, Ray &r);
IntersectionClass rayPlaneIntersection(const Plane &p,
const Vector &v1,
const Vector &v2,
Vector &v,
double &t);
IntersectionClass lineSegmentPlaneIntersection(const Plane &p,
const LineSegment &line,
Vector &v);
RayIntersectionClass rayRayIntersection(const Ray &r1,
const Ray &r2,
Vector &v1,
Vector &v2,
double &mu1,
double &mu2);
// test whether point d is above, below or on the plane formed by the triangle a,b,c.
// return: +ve = d is below a,b,c
// -ve = d is above a,b,c
// 0 = d is on a,b,c
#if defined CARVE_USE_EXACT_PREDICATES
inline double orient3d(const Vector &a,
const Vector &b,
const Vector &c,
const Vector &d) {
return shewchuk::orient3d(a.v, b.v, c.v, d.v);
}
#else
inline double orient3d(const Vector &a,
const Vector &b,
const Vector &c,
const Vector &d) {
return dotcross((a - d), (b - d), (c - d));
}
#endif
// Volume of a tetrahedron described by 4 points. Will be
// positive if the anticlockwise normal of a,b,c is oriented out
// of the tetrahedron.
//
// see: http://mathworld.wolfram.com/Tetrahedron.html
inline double tetrahedronVolume(const Vector &a,
const Vector &b,
const Vector &c,
const Vector &d) {
return dotcross((a - d), (b - d), (c - d)) / 6.0;
}
/**
* \brief Determine whether p is internal to the wedge defined by
* the area between the planes defined by a,b,c and a,b,d
* angle abc, where ab is the apex of the angle.
*
* @param[in] a
* @param[in] b
* @param[in] c
* @param[in] d
* @param[in] p
*
* @return true, if p is contained in the wedge defined by the
* area between the planes defined by a,b,c and
* a,b,d. If the wedge is reflex, p is considered to
* be contained if it lies on either plane. Acute
* wdges do not contain p if p lies on either
* plane. This is so that internalToWedge(a,b,c,d,p) =
* !internalToWedge(a,b,d,c,p)
*/
inline bool internalToWedge(const Vector &a,
const Vector &b,
const Vector &c,
const Vector &d,
const Vector &p) {
bool reflex = (c < d) ?
orient3d(a, b, c, d) >= 0.0 :
orient3d(a, b, d, c) < 0.0;
double d1 = orient3d(a, b, c, p);
double d2 = orient3d(a, b, d, p);
if (reflex) {
// above a,b,c or below a,b,d (or coplanar with either)
return d1 <= 0.0 || d2 >= 0.0;
} else {
// above a,b,c and below a,b,d
return d1 < 0.0 && d2 > 0.0;
}
}
/**
* \brief Determine the ordering relationship of a and b, when
* rotating around direction, starting from base.
*
* @param[in] adirection
* @param[in] base
* @param[in] a
* @param[in] b
*
* @return
* * -1, if a is ordered before b around, rotating about direction.
* * 0, if a and b are equal in angle.
* * +1, if a is ordered after b around, rotating about direction.
*/
inline int compareAngles(const Vector &direction, const Vector &base, const Vector &a, const Vector &b) {
// double d1 = carve::geom3d::orient3d(carve::geom::VECTOR(0,0,0), direction, a, b);
// double d2 = carve::geom3d::orient3d(carve::geom::VECTOR(0,0,0), direction, base, a);
// double d3 = carve::geom3d::orient3d(carve::geom::VECTOR(0,0,0), direction, base, b);
#if defined(CARVE_USE_EXACT_PREDICATES)
// which is equivalent to the following (which eliminates a
// vector subtraction):
double d1 = carve::geom3d::orient3d(direction, b, a, carve::geom::VECTOR(0,0,0));
double d2 = carve::geom3d::orient3d(direction, a, base, carve::geom::VECTOR(0,0,0));
double d3 = carve::geom3d::orient3d(direction, b, base, carve::geom::VECTOR(0,0,0));
#else
// dotcross = a . (b x c)
double d1 = carve::geom::dotcross(direction, b, a );
double d2 = carve::geom::dotcross(direction, a, base);
double d3 = carve::geom::dotcross(direction, b, base);
#endif
// CASE: a and b are coplanar wrt. direction.
if (d1 == 0.0) {
// a and b point in the same direction.
if (dot(a, b) > 0.0) {
// Neither is less than the other.
return 0;
}
// a and b point in opposite directions.
// * if d2 < 0.0, a is above plane(direction, base) and is less
// than b.
// * if d2 == 0.0 a is coplanar with plane(direction, base) and is
// less than b if it points in the same direction as base.
// * if d2 > 0.0, a is below plane(direction, base) and is greater
// than b.
if (d2 == 0.0) { return dot(a, base) > 0.0 ? -1 : +1; }
if (d3 == 0.0) { return dot(b, base) > 0.0 ? +1 : -1; }
if (d2 < 0.0 && d3 > 0.0) return -1;
if (d2 > 0.0 && d3 < 0.0) return +1;
// both a and b are to one side of plane(direction, base) -
// rounding error (if a and b are truly coplanar with
// direction, one should be above, and one should be below any
// other plane that is not itself coplanar with
// plane(direction, a|b) - which would imply d2 and d3 == 0.0).
// If both are below plane(direction, base) then the one that
// points in the same direction as base is greater.
// If both are above plane(direction, base) then the one that
// points in the same direction as base is lesser.
if (d2 > 0.0) { return dot(a, base) > 0.0 ? +1 : -1; }
else { return dot(a, base) > 0.0 ? -1 : +1; }
}
// CASE: a and b are not coplanar wrt. direction
if (d2 < 0.0) {
// if a is above plane(direction,base), then a is less than b if
// b is below plane(direction,base) or b is above plane(direction,a)
return (d3 > 0.0 || d1 < 0.0) ? -1 : +1;
} else if (d2 == 0.0) {
// if a is on plane(direction,base) then a is less than b if a
// points in the same direction as base, or b is below
// plane(direction,base)
return (dot(a, base) > 0.0 || d3 > 0.0) ? -1 : +1;
} else {
// if a is below plane(direction,base), then a is less than b if b
// is below plane(direction,base) and b is above plane(direction,a)
return (d3 > 0.0 && d1 < 0.0) ? -1 : +1;
}
}
// The anticlockwise angle from vector "from" to vector "to", oriented around the vector "orient".
static inline double antiClockwiseAngle(const Vector &from, const Vector &to, const Vector &orient) {
double dp = dot(from, to);
Vector cp = cross(from, to);
if (cp.isZero()) {
if (dp < 0) {
return M_PI;
} else {
return 0.0;
}
} else {
if (dot(cp, orient) > 0.0) {
return acos(dp);
} else {
return M_TWOPI - acos(dp);
}
}
}
static inline double antiClockwiseOrdering(const Vector &from, const Vector &to, const Vector &orient) {
double dp = dot(from, to);
Vector cp = cross(from, to);
if (cp.isZero()) {
if (dp < 0) {
return 2.0;
} else {
return 0.0;
}
} else {
if (dot(cp, orient) > 0.0) {
// 1..-1 -> 0..2
return 1.0 - dp;
} else {
// -1..1 -> 2..4
return dp + 1.0;
}
}
}
}
}

672
extern/carve/include/carve/geom_impl.hpp vendored Normal file
View File

@@ -0,0 +1,672 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/math.hpp>
namespace carve {
namespace geom {
template<unsigned ndim>
double vector<ndim>::length2() const { return dot(*this, *this); }
template<unsigned ndim>
double vector<ndim>::length() const { return sqrt(dot(*this, *this)); }
template<unsigned ndim>
vector<ndim> &vector<ndim>::normalize() {
#if defined(CARVE_DEBUG)
CARVE_ASSERT(length() > 0.0);
#endif
*this /= length();
return *this;
}
template<unsigned ndim>
vector<ndim> vector<ndim>::normalized() const {
#if defined(CARVE_DEBUG)
CARVE_ASSERT(length() > 0.0);
#endif
return *this / length();
}
template<unsigned ndim>
bool vector<ndim>::exactlyZero() const {
for (unsigned i = 0; i < ndim; ++i) if (this->v[i]) return false;
return true;
}
template<unsigned ndim>
bool vector<ndim>::isZero(double epsilon) const {
return length2() < epsilon * epsilon;
}
template<unsigned ndim>
void vector<ndim>::setZero() { for (size_t i = 0; i < ndim; ++i) this->v[i] = 0.0; }
template<unsigned ndim>
void vector<ndim>::fill(double val) { for (size_t i = 0; i < ndim; ++i) this->v[i] = val; }
template<unsigned ndim>
vector<ndim> &vector<ndim>::scaleBy(double d) { for (unsigned i = 0; i < ndim; ++i) this->v[i] *= d; return *this; }
template<unsigned ndim>
vector<ndim> &vector<ndim>::invscaleBy(double d) { for (unsigned i = 0; i < ndim; ++i) this->v[i] /= d; return *this; }
template<unsigned ndim>
vector<ndim> vector<ndim>::scaled(double d) const { return *this * d; }
template<unsigned ndim>
vector<ndim> vector<ndim>::invscaled(double d) const { return *this / d; }
template<unsigned ndim>
vector<ndim> &vector<ndim>::negate() { for (unsigned i = 0; i < ndim; ++i) this->v[i] = -this->v[i]; return *this; }
template<unsigned ndim>
vector<ndim> vector<ndim>::negated() const { return -*this; }
template<unsigned ndim>
double &vector<ndim>::operator[](unsigned i) { return this->v[i]; }
template<unsigned ndim>
const double &vector<ndim>::operator[](unsigned i) const { return this->v[i]; }
template<unsigned ndim>
template<typename assign_t>
vector<ndim> &vector<ndim>::operator=(const assign_t &t) {
for (unsigned i = 0; i < ndim; ++i) this->v[i] = t[i];
return *this;
}
template<unsigned ndim>
std::string vector<ndim>::asStr() const {
std::ostringstream out;
out << '<';
out << std::setprecision(24);
for (unsigned i = 0; i < ndim; ++i) { if (i) out << ','; out << this->v[i]; }
out << '>';
return out.str();
}
template<unsigned ndim>
vector<ndim> operator+(const vector<ndim> &a, const vector<ndim> &b) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] + b[i];
return c;
}
template<unsigned ndim>
vector<ndim> operator+(const vector<ndim> &a, double b) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] + b;
return c;
}
template<unsigned ndim, typename val_t>
vector<ndim> operator+(const vector<ndim> &a, const val_t &b) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] + b[i];
return c;
}
template<unsigned ndim, typename val_t>
vector<ndim> operator+(const val_t &a, const vector<ndim> &b) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] + b[i];
return c;
}
template<unsigned ndim>
vector<ndim> &operator+=(vector<ndim> &a, const vector<ndim> &b) {
for (unsigned i = 0; i < ndim; ++i) a[i] += b[i];
return a;
}
template<unsigned ndim>
vector<ndim> &operator+=(vector<ndim> &a, double b) {
for (unsigned i = 0; i < ndim; ++i) a[i] += b;
return a;
}
template<unsigned ndim, typename val_t>
vector<ndim> &operator+=(vector<ndim> &a, const val_t &b) {
for (unsigned i = 0; i < ndim; ++i) a[i] += b[i];
return a;
}
template<unsigned ndim>
vector<ndim> operator-(const vector<ndim> &a) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = -a[i];
return c;
}
template<unsigned ndim>
vector<ndim> operator-(const vector<ndim> &a, double b) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] - b;
return c;
}
template<unsigned ndim>
vector<ndim> operator-(const vector<ndim> &a, const vector<ndim> &b) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] - b[i];
return c;
}
template<unsigned ndim, typename val_t>
vector<ndim> operator-(const vector<ndim> &a, const val_t &b) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] - b[i];
return c;
}
template<unsigned ndim, typename val_t>
vector<ndim> operator-(const val_t &a, const vector<ndim> &b) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] - b[i];
return c;
}
template<unsigned ndim>
vector<ndim> &operator-=(vector<ndim> &a, const vector<ndim> &b) {
for (unsigned i = 0; i < ndim; ++i) a[i] -= b[i];
return a;
}
template<unsigned ndim>
vector<ndim> &operator-=(vector<ndim> &a, double b) {
for (unsigned i = 0; i < ndim; ++i) a[i] -= b;
return a;
}
template<unsigned ndim, typename val_t>
vector<ndim> &operator-=(vector<ndim> &a, const val_t &b) {
for (unsigned i = 0; i < ndim; ++i) a[i] -= b[i];
return a;
}
template<unsigned ndim>
vector<ndim> operator*(const vector<ndim> &a, double s) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] * s;
return c;
}
template<unsigned ndim>
vector<ndim> operator*(double s, const vector<ndim> &a) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] * s;
return c;
}
template<unsigned ndim>
vector<ndim> &operator*=(vector<ndim> &a, double s) {
for (unsigned i = 0; i < ndim; ++i) a[i] *= s;
return a;
}
template<unsigned ndim>
vector<ndim> operator/(const vector<ndim> &a, double s) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = a[i] / s;
return c;
}
template<unsigned ndim>
vector<ndim> &operator/=(vector<ndim> &a, double s) {
for (unsigned i = 0; i < ndim; ++i) a[i] /= s;
return a;
}
template<unsigned ndim>
bool operator==(const vector<ndim> &a, const vector<ndim> &b) {
for (unsigned i = 0; i < ndim; ++i) { if (a[i] != b[i]) return false; }
return true;
}
template<unsigned ndim>
bool operator!=(const vector<ndim> &a, const vector<ndim> &b) {
return !(a == b);
}
template<unsigned ndim>
bool operator<(const vector<ndim> &a, const vector<ndim> &b) {
for (unsigned i = 0; i < ndim; ++i) { if (a[i] < b[i]) return true; if (a[i] > b[i]) return false; }
return false;
}
template<unsigned ndim>
bool operator<=(const vector<ndim> &a, const vector<ndim> &b) {
return !(b < a);
}
template<unsigned ndim>
bool operator>(const vector<ndim> &a, const vector<ndim> &b) {
return b < a;
}
template<unsigned ndim>
bool operator>=(const vector<ndim> &a, const vector<ndim> &b) {
return !(a < b);
}
template<unsigned ndim>
vector<ndim> abs(const vector<ndim> &a) {
vector<ndim> c(NOINIT);
for (unsigned i = 0; i < ndim; ++i) c[i] = fabs(a[i]);
return c;
}
template<unsigned ndim>
double distance2(const vector<ndim> &a, const vector<ndim> &b) {
return (b - a).length2();
}
template<unsigned ndim>
double distance(const vector<ndim> &a, const vector<ndim> &b) {
return (b - a).length();
}
template<unsigned ndim>
bool equal(const vector<ndim> &a, const vector<ndim> &b) {
return (b - a).isZero();
}
template<unsigned ndim>
int smallestAxis(const vector<ndim> &a) {
int idx = 0;
double lo = fabs(a[0]);
for (unsigned i = 1; i < ndim; ++i) {
double val = fabs(a[i]);
if (val <= lo) { lo = val; idx = (int)i; }
}
return idx;
}
template<unsigned ndim>
int largestAxis(const vector<ndim> &a) {
int idx = 0;
double hi = fabs(a[0]);
for (unsigned i = 1; i < ndim; ++i) {
double val = fabs(a[i]);
if (val > hi) { hi = val; idx = (int)i; }
}
return idx;
}
template<unsigned ndim>
vector<2> select(const vector<ndim> &a, int a1, int a2) {
vector<2> r(NOINIT);
r.v[0] = a.v[a1]; r.v[1] = a.v[a2];
return r;
}
template<unsigned ndim>
vector<3> select(const vector<ndim> &a, int a1, int a2, int a3) {
vector<3> r(NOINIT);
r.v[0] = a.v[a1]; r.v[1] = a.v[a2]; r.v[2] = a.v[a3];
return r;
}
template<unsigned ndim, typename assign_t, typename oper_t>
vector<ndim> &assign_op(vector<ndim> &a, const assign_t &t, oper_t op) {
for (unsigned i = 0; i < ndim; ++i) a[i] = op(t[i]);
return a;
}
template<unsigned ndim, typename assign1_t, typename assign2_t, typename oper_t>
vector<ndim> &assign_op(vector<ndim> &a, const assign1_t &t1, const assign2_t &t2, oper_t op) {
for (unsigned i = 0; i < ndim; ++i) a[i] = op(t1[i], t2[i]);
return a;
}
template<unsigned ndim, typename iter_t>
void bounds(iter_t begin, iter_t end, vector<ndim> &min, vector<ndim> &max) {
if (begin == end) {
min.setZero();
max.setZero();
} else {
min = max = *begin;
while (++begin != end) {
vector<ndim> v = *begin;
assign_op(min, min, v, carve::util::min_functor());
assign_op(max, max, v, carve::util::max_functor());
}
}
}
template<unsigned ndim, typename iter_t, typename adapt_t>
void bounds(iter_t begin, iter_t end, adapt_t adapt, vector<ndim> &min, vector<ndim> &max) {
if (begin == end) {
min.setZero();
max.setZero();
} else {
min = max = adapt(*begin);
while (++begin != end) {
vector<ndim> v = adapt(*begin);
assign_op(min, min, v, carve::util::min_functor());
assign_op(max, max, v, carve::util::max_functor());
}
}
}
template<unsigned ndim, typename iter_t>
void centroid(iter_t begin, iter_t end, vector<ndim> &c) {
c.setZero();
int n = 0;
for (; begin != end; ++begin, ++n) { c += *begin; }
c /= double(n);
}
template<unsigned ndim, typename iter_t, typename adapt_t>
void centroid(iter_t begin, iter_t end, adapt_t adapt, vector<ndim> &c) {
c.setZero();
int n = 0;
for (; begin != end; ++begin, ++n) { c += adapt(*begin); }
c /= double(n);
}
template<unsigned ndim, typename val_t>
double dot(const vector<ndim> &a, const val_t &b) {
double r = 0.0;
for (unsigned i = 0; i < ndim; ++i) r += a[i] * b[i];
return r;
}
static inline vector<3> cross(const vector<3> &a, const vector<3> &b) {
// Compute a x b
return VECTOR(+(a.y * b.z - a.z * b.y),
-(a.x * b.z - a.z * b.x),
+(a.x * b.y - a.y * b.x));
}
static inline double cross(const vector<2> &a, const vector<2> &b) {
// Compute a x b
return a.x * b.y - b.x * a.y;
}
static inline double dotcross(const vector<3> &a, const vector<3> &b, const vector<3> &c) {
// Compute a . (b x c)
return
(a.x * b.y * c.z + a.y * b.z * c.x + a.z * b.x * c.y) -
(a.x * c.y * b.z + a.y * c.z * b.x + a.z * c.x * b.y);
}
template<unsigned ndim>
double distance(const axis_pos &a, const vector<ndim> &b) {
return fabs(b[a.axis] - a.pos);
}
template<unsigned ndim>
double distance2(const axis_pos &a, const vector<ndim> &b) {
double r = fabs(b[a.axis] - a.pos);
return r * r;
}
template<unsigned ndim> bool operator<(const axis_pos &a, const vector<ndim> &b) { return a.pos < b[a.axis]; }
template<unsigned ndim> bool operator<(const vector<ndim> &a, const axis_pos &b) { return a[b.axis] < b.pos; }
template<unsigned ndim> bool operator<=(const axis_pos &a, const vector<ndim> &b) { return a.pos <= b[a.axis]; }
template<unsigned ndim> bool operator<=(const vector<ndim> &a, const axis_pos &b) { return a[b.axis] <= b.pos; }
template<unsigned ndim> bool operator>(const axis_pos &a, const vector<ndim> &b) { return a.pos > b[a.axis]; }
template<unsigned ndim> bool operator>(const vector<ndim> &a, const axis_pos &b) { return a[b.axis] > b.pos; }
template<unsigned ndim> bool operator>=(const axis_pos &a, const vector<ndim> &b) { return a.pos >= b[a.axis]; }
template<unsigned ndim> bool operator>=(const vector<ndim> &a, const axis_pos &b) { return a[b.axis] >= b.pos; }
template<unsigned ndim> bool operator==(const axis_pos &a, const vector<ndim> &b) { return a.pos == b[a.axis]; }
template<unsigned ndim> bool operator==(const vector<ndim> &a, const axis_pos &b) { return a[b.axis] == b.pos; }
template<unsigned ndim> bool operator!=(const axis_pos &a, const vector<ndim> &b) { return a.pos != b[a.axis]; }
template<unsigned ndim> bool operator!=(const vector<ndim> &a, const axis_pos &b) { return a[b.axis] != b.pos; }
template<unsigned ndim>
bool ray<ndim>::OK() const {
return !D.isZero();
}
template<unsigned ndim>
ray<ndim> rayThrough(const vector<ndim> &a, const vector<ndim> &b) {
return ray<ndim>(b - a, a);
}
static inline double distance2(const ray<3> &r, const vector<3> &v) {
return cross(r.D, v - r.v).length2() / r.D.length2();
}
static inline double distance(const ray<3> &r, const vector<3> &v) {
return sqrt(distance2(r, v));
}
static inline double distance2(const ray<2> &r, const vector<2> &v) {
double t = cross(r.D, v - r.v);
return (t * t) / r.D.length2();
}
static inline double distance(const ray<2> &r, const vector<2> &v) {
return sqrt(distance2(r, v));
}
template<unsigned ndim>
void linesegment<ndim>::update() {
midpoint = (v2 + v1) / 2.0;
half_length = (v2 - v1) / 2.0;
}
template<unsigned ndim>
bool linesegment<ndim>::OK() const {
return !half_length.isZero();
}
template<unsigned ndim>
void linesegment<ndim>::flip() {
std::swap(v1, v2);
half_length = (v2 - v1) / 2.0;
}
template<unsigned ndim>
aabb<ndim> linesegment<ndim>::getAABB() const {
aabb<ndim> r;
r.fit(v1, v2);
return r;
}
template<unsigned ndim>
linesegment<ndim>::linesegment(const vector_t &_v1, const vector_t &_v2) : v1(_v1), v2(_v2) {
update();
}
template<unsigned ndim>
double distance2(const linesegment<ndim> &l, const vector<ndim> &v) {
vector<ndim> D = l.v2 - l.v1;
double t = dot(v - l.v1, D) / dot(D, D);
if (t <= 0.0) return (v - l.v1).length2();
if (t >= 1.0) return (v - l.v2).length2();
vector<ndim> vc = D * t + l.v1;
return (v - vc).length2();
}
template<unsigned ndim>
double distance(const linesegment<ndim> &l, const vector<ndim> &v) {
return sqrt(distance2(l, v));
}
template<unsigned ndim>
void plane<ndim>::negate() {
N.negate();
d = -d;
}
template<unsigned ndim>
plane<ndim>::plane() {
N.setZero();
N[0] = 1.0;
d= 0.0;
}
template<unsigned ndim>
plane<ndim>::plane(const vector_t &_N, vector_t _p) : N(_N), d(-dot(_p, _N)) {
}
template<unsigned ndim>
plane<ndim>::plane(const vector_t &_N, double _d) : N(_N), d(_d) {
}
template<unsigned ndim>
plane<ndim> operator-(const plane<ndim> &p) {
return plane<ndim>(-p.N, -p.d);
}
template<unsigned ndim, typename val_t>
double distance(const plane<ndim> &plane, const val_t &point) {
return dot(plane.N, point) + plane.d;
}
template<unsigned ndim, typename val_t>
double distance2(const plane<ndim> &plane, const val_t &point) {
double d = distance(plane, point);
return d * d;
}
template<unsigned ndim>
vector<ndim> closestPoint(const plane<ndim> &p, const vector<ndim> &v) {
return v - p.N * (p.d + dot(p.N, v)) / dot(p.N, p.N);
}
template<unsigned ndim>
aabb<ndim> sphere<ndim>::getAABB() const {
aabb<ndim> r;
r.fit(C - r, C + r);
}
template<unsigned ndim>
sphere<ndim>::sphere() {
C.setZero();
r = 1.0;
}
template<unsigned ndim>
sphere<ndim>::sphere(const vector_t &_C, double _r) : C(_C), r(_r) {
}
template<unsigned ndim, typename val_t>
double distance(const sphere<ndim> &sphere, const val_t &point) {
return std::max(0.0, distance(sphere.C, point) - sphere.r);
}
template<unsigned ndim, typename val_t>
double distance2(const sphere<ndim> &sphere, const val_t &point) {
return std::max(0.0, distance2(sphere.C, point) - sphere.r * sphere.r);
}
template<unsigned ndim>
vector<ndim> closestPoint(const sphere<ndim> &sphere, const vector<ndim> &point) {
return (point - sphere.C).normalized() * sphere.r;
}
template<unsigned ndim>
aabb<ndim> tri<ndim>::getAABB() const {
aabb<ndim> aabb;
aabb.fit(v[0], v[1], v[2]);
return aabb;
}
template<unsigned ndim>
tri<ndim>::tri(vector_t _v[3]) {
std::copy(v, v+3, _v);
}
template<unsigned ndim>
tri<ndim>::tri(const vector_t &a, const vector_t &b, const vector_t &c) {
v[0] = a;
v[1] = b;
v[2] = c;
}
template<unsigned ndim>
std::ostream &operator<<(std::ostream &o, const vector<ndim> &v) {
o << v.asStr();
return o;
}
template<unsigned ndim>
std::ostream &operator<<(std::ostream &o, const carve::geom::plane<ndim> &p) {
o << p.N << ";" << p.d;
return o;
}
template<unsigned ndim>
std::ostream &operator<<(std::ostream &o, const carve::geom::sphere<ndim> &sphere) {
o << "{sphere " << sphere.C << ";" << sphere.r << "}";
return o;
}
template<unsigned ndim>
std::ostream &operator<<(std::ostream &o, const carve::geom::tri<ndim> &tri) {
o << "{tri " << tri.v[0] << ";" << tri.v[1] << ";" << tri.v[2] << "}";
return o;
}
template<unsigned ndim>
double distance(const tri<ndim> &tri, const vector<ndim> &pt) {
return distance(closestPoint(tri, pt), pt);
}
template<unsigned ndim>
double distance2(const tri<ndim> &tri, const vector<ndim> &pt) {
return distance2(closestPoint(tri, pt), pt);
}
}
}

4
extern/carve/include/carve/gnu_cxx.h vendored Normal file
View File

@@ -0,0 +1,4 @@
// Copyright 2006 Tobias Sargeant (toby@permuted.net)
// All rights reserved.
#pragma once

425
extern/carve/include/carve/heap.hpp vendored Normal file
View File

@@ -0,0 +1,425 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
namespace carve {
namespace heap {
namespace detail {
struct ignore_position_t {
template<typename value_t>
void operator()(value_t &val, size_t idx) const {}
};
template<typename random_access_iter_t,
typename distance_t,
typename value_t,
typename pred_t,
typename pos_notifier_t>
void _adjust_heap(random_access_iter_t begin,
distance_t pos,
distance_t len,
value_t val,
pred_t pred,
pos_notifier_t notify) {
const distance_t top = pos;
distance_t child = pos * 2 + 2;
while (child < len) {
if (pred(begin[child], begin[child - 1])) child--;
begin[pos] = begin[child];
notify(begin[pos], pos);
pos = child;
child = pos * 2 + 2;
}
if (child == len) {
child--;
begin[pos] = begin[child];
notify(begin[pos], pos);
pos = child;
}
distance_t parent = (pos - 1) / 2;
while (pos > top && pred(begin[parent], val)) {
begin[pos] = begin[parent];
notify(begin[pos], pos);
pos = parent;
parent = (pos - 1) / 2;
}
begin[pos] = val;
notify(begin[pos], pos);
}
template<typename random_access_iter_t,
typename distance_t,
typename value_t,
typename pred_t,
typename pos_notifier_t>
void _push_heap(random_access_iter_t begin,
distance_t pos,
value_t val,
pred_t pred,
pos_notifier_t notify) {
distance_t parent = (pos - 1) / 2;
while (pos > 0 && pred(begin[parent], val)) {
begin[pos] = begin[parent];
notify(begin[pos], pos);
pos = parent;
parent = (pos - 1) / 2;
}
begin[pos] = val;
notify(begin[pos], pos);
}
template<typename random_access_iter_t,
typename distance_t,
typename pred_t,
typename pos_notifier_t>
void _remove_heap(random_access_iter_t begin,
distance_t pos,
distance_t len,
pred_t pred,
pos_notifier_t notify) {
--len;
if (pos != len) {
typedef typename std::iterator_traits<random_access_iter_t>::value_type value_t;
value_t removed = begin[pos];
_adjust_heap(begin, pos, len, begin[len], pred, notify);
begin[len] = removed;
notify(begin[len], len);
}
}
template<typename random_access_iter_t,
typename distance_t,
typename pred_t,
typename pos_notifier_t>
void _make_heap(random_access_iter_t begin,
distance_t len,
pred_t pred,
pos_notifier_t notify) {
for (distance_t pos = len / 2; pos > 0; ) {
--pos;
_adjust_heap(begin, pos, len, begin[pos], pred, ignore_position_t());
}
for (distance_t pos = 0; pos < len; ++pos) {
notify(begin[pos], pos);
}
}
template<typename random_access_iter_t,
typename distance_t,
typename pred_t>
void _make_heap(random_access_iter_t begin,
distance_t len,
pred_t pred,
ignore_position_t) {
for (distance_t pos = len / 2; pos > 0; ) {
--pos;
_adjust_heap(begin, pos, len, begin[pos], pred, ignore_position_t());
}
}
template<typename random_access_iter_t,
typename distance_t,
typename pred_t>
bool _is_heap(random_access_iter_t begin,
distance_t len,
pred_t pred) {
distance_t parent = 0;
for (distance_t child = 1; child < len; ++child) {
if (pred(begin[parent], begin[child])) {
return false;
}
if (++child == len) break;
if (pred(begin[parent], begin[child])) {
return false;
}
++parent;
}
return true;
}
}
template<typename random_access_iter_t>
void adjust_heap(random_access_iter_t begin,
random_access_iter_t end,
random_access_iter_t pos) {
typedef typename std::iterator_traits<random_access_iter_t>::value_type value_t;
detail::_adjust_heap(begin, pos - begin, end - begin, *pos, std::less<value_t>());
}
template<typename random_access_iter_t,
typename pred_t>
void adjust_heap(random_access_iter_t begin,
random_access_iter_t end,
random_access_iter_t pos,
pred_t pred) {
detail::_adjust_heap(begin, pos - begin, end - begin, *pos, pred);
}
template<typename random_access_iter_t,
typename pred_t,
typename pos_notifier_t>
void adjust_heap(random_access_iter_t begin,
random_access_iter_t end,
random_access_iter_t pos,
pred_t pred,
pos_notifier_t notify) {
detail::_adjust_heap(begin, pos - begin, end - begin, *pos, pred, notify);
}
template<typename random_access_iter_t>
void remove_heap(random_access_iter_t begin,
random_access_iter_t end,
random_access_iter_t pos) {
typedef typename std::iterator_traits<random_access_iter_t>::value_type value_t;
detail::_remove_heap(begin, pos - begin, end - begin, std::less<value_t>(), detail::ignore_position_t());
}
template<typename random_access_iter_t,
typename pred_t>
void remove_heap(random_access_iter_t begin,
random_access_iter_t end,
random_access_iter_t pos,
pred_t pred) {
detail::_remove_heap(begin, pos - begin, end - begin, pred, detail::ignore_position_t());
}
template<typename random_access_iter_t,
typename pred_t,
typename pos_notifier_t>
void remove_heap(random_access_iter_t begin,
random_access_iter_t end,
random_access_iter_t pos,
pred_t pred,
pos_notifier_t notify) {
detail::_remove_heap(begin, pos - begin, end - begin, pred, notify);
}
template<typename random_access_iter_t>
void pop_heap(random_access_iter_t begin,
random_access_iter_t end) {
typedef typename std::iterator_traits<random_access_iter_t>::value_type value_t;
typedef typename std::iterator_traits<random_access_iter_t>::difference_type distance_t;
detail::_remove_heap(begin, distance_t(0), end - begin, std::less<value_t>(), detail::ignore_position_t());
}
template<typename random_access_iter_t,
typename pred_t>
void pop_heap(random_access_iter_t begin,
random_access_iter_t end,
pred_t pred) {
typedef typename std::iterator_traits<random_access_iter_t>::difference_type distance_t;
detail::_remove_heap(begin, distance_t(0), end - begin, pred, detail::ignore_position_t());
}
template<typename random_access_iter_t,
typename pred_t,
typename pos_notifier_t>
void pop_heap(random_access_iter_t begin,
random_access_iter_t end,
pred_t pred,
pos_notifier_t notify) {
typedef typename std::iterator_traits<random_access_iter_t>::difference_type distance_t;
detail::_remove_heap(begin, distance_t(0), end - begin, pred, notify);
}
template<typename random_access_iter_t>
void push_heap(random_access_iter_t begin,
random_access_iter_t end) {
typedef typename std::iterator_traits<random_access_iter_t>::value_type value_t;
typedef typename std::iterator_traits<random_access_iter_t>::difference_type distance_t;
distance_t pos = end - begin - 1;
detail::_push_heap(begin, pos, begin[pos], std::less<value_t>(), detail::ignore_position_t());
}
template<typename random_access_iter_t,
typename pred_t>
void push_heap(random_access_iter_t begin,
random_access_iter_t end,
pred_t pred) {
typedef typename std::iterator_traits<random_access_iter_t>::difference_type distance_t;
distance_t pos = end - begin - 1;
detail::_push_heap(begin, pos, begin[pos], pred, detail::ignore_position_t());
}
template<typename random_access_iter_t,
typename pred_t,
typename pos_notifier_t>
void push_heap(random_access_iter_t begin,
random_access_iter_t end,
pred_t pred,
pos_notifier_t notify) {
typedef typename std::iterator_traits<random_access_iter_t>::difference_type distance_t;
distance_t pos = end - begin - 1;
detail::_push_heap(begin, pos, begin[pos], pred, notify);
}
template<typename random_access_iter_t>
void make_heap(random_access_iter_t begin,
random_access_iter_t end) {
typedef typename std::iterator_traits<random_access_iter_t>::value_type value_t;
detail::_make_heap(begin, end - begin, std::less<value_t>(), detail::ignore_position_t());
}
template<typename random_access_iter_t,
typename pred_t>
void make_heap(random_access_iter_t begin,
random_access_iter_t end,
pred_t pred) {
detail::_make_heap(begin, end - begin, pred, detail::ignore_position_t());
}
template<typename random_access_iter_t,
typename pred_t,
typename pos_notifier_t>
void make_heap(random_access_iter_t begin,
random_access_iter_t end,
pred_t pred,
pos_notifier_t notify) {
detail::_make_heap(begin, end - begin, pred, notify);
}
template<typename random_access_iter_t>
bool is_heap(random_access_iter_t begin,
random_access_iter_t end) {
typedef typename std::iterator_traits<random_access_iter_t>::value_type value_t;
return detail::_is_heap(begin, end - begin, std::less<value_t>());
}
template<typename random_access_iter_t, typename pred_t>
bool is_heap(random_access_iter_t begin,
random_access_iter_t end,
pred_t pred) {
return detail::_is_heap(begin, end - begin, pred);
}
template<typename random_access_iter_t>
void sort_heap(random_access_iter_t begin,
random_access_iter_t end) {
typedef typename std::iterator_traits<random_access_iter_t>::difference_type distance_t;
typedef typename std::iterator_traits<random_access_iter_t>::value_type value_t;
for (distance_t len = end - begin; len > 1; --len) {
detail::_remove_heap(begin, distance_t(0), len, std::less<value_t>(), detail::ignore_position_t());
}
}
template<typename random_access_iter_t,
typename pred_t>
void sort_heap(random_access_iter_t begin,
random_access_iter_t end,
pred_t pred) {
typedef typename std::iterator_traits<random_access_iter_t>::difference_type distance_t;
for (distance_t len = end - begin; len > 1; --len) {
detail::_remove_heap(begin, distance_t(0), len, pred, detail::ignore_position_t());
}
}
template<typename random_access_iter_t,
typename pred_t,
typename pos_notifier_t>
void sort_heap(random_access_iter_t begin,
random_access_iter_t end,
pred_t pred,
pos_notifier_t notify) {
typedef typename std::iterator_traits<random_access_iter_t>::difference_type distance_t;
for (distance_t len = end - begin; len > 1; --len) {
detail::_remove_heap(begin, distance_t(0), len, pred, detail::ignore_position_t());
notify(begin[len], len);
}
notify(begin[0], 0);
}
}
}

304
extern/carve/include/carve/input.hpp vendored Normal file
View File

@@ -0,0 +1,304 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <map>
#include <string>
#include <carve/carve.hpp>
#include <carve/poly.hpp>
#include <carve/mesh.hpp>
#include <carve/polyline.hpp>
#include <carve/pointset.hpp>
namespace carve {
namespace input {
typedef std::map<std::string, std::string> Options;
static inline Options opts() {
return Options();
}
static inline Options opts(const char **kv) {
Options r;
for (size_t i = 0; kv[i] != NULL; i += 2) {
r[kv[i]] = kv[i+1];
}
return r;
}
static inline Options opts(const std::string &k1, const std::string &v1) {
Options r;
r[k1] = v1;
return r;
}
static inline Options opts(const std::string &k1, const std::string &v1,
const std::string &k2, const std::string &v2) {
Options r;
r[k1] = v1;
r[k2] = v2;
return r;
}
static inline Options opts(const std::string &k1, const std::string &v1,
const std::string &k2, const std::string &v2,
const std::string &k3, const std::string &v3) {
Options r;
r[k1] = v1;
r[k2] = v2;
r[k3] = v3;
return r;
}
static inline bool _bool(const std::string &str, bool _default = false) {
if (str == "true") return true;
if (str == "false") return false;
return _default;
}
struct Data {
Data() {
}
virtual ~Data() {
}
virtual void transform(const carve::math::Matrix & /* transform */) {
}
};
struct VertexData : public Data {
std::vector<carve::geom3d::Vector> points;
VertexData() : Data() {
}
virtual ~VertexData() {
}
virtual void transform(const carve::math::Matrix &transform) {
for (size_t i = 0; i < points.size(); ++i) {
points[i] *= transform;
}
}
size_t addVertex(carve::geom3d::Vector point) {
size_t index = points.size();
points.push_back(point);
return index;
}
inline void reserveVertices(int count) {
points.reserve(count);
}
size_t getVertexCount() const {
return points.size();
}
const carve::geom3d::Vector &getVertex(int index) const {
return points[index];
}
};
struct PolyhedronData : public VertexData {
std::vector<int> faceIndices;
int faceCount;
PolyhedronData() : VertexData(), faceIndices(), faceCount(0) {
}
virtual ~PolyhedronData() {
}
void reserveFaces(int count, int avgFaceSize) {
faceIndices.reserve(faceIndices.size() + count * (1 + avgFaceSize));
}
int getFaceCount() const {
return faceCount;
}
template <typename Iter>
void addFace(Iter begin, Iter end) {
size_t n = std::distance(begin, end);
faceIndices.reserve(faceIndices.size() + n + 1);
faceIndices.push_back(n);
std::copy(begin, end, std::back_inserter(faceIndices));
++faceCount;
}
void addFace(int a, int b, int c) {
faceIndices.push_back(3);
faceIndices.push_back(a);
faceIndices.push_back(b);
faceIndices.push_back(c);
++faceCount;
}
void addFace(int a, int b, int c, int d) {
faceIndices.push_back(4);
faceIndices.push_back(a);
faceIndices.push_back(b);
faceIndices.push_back(c);
faceIndices.push_back(d);
++faceCount;
}
void clearFaces() {
faceIndices.clear();
faceCount = 0;
}
carve::poly::Polyhedron *create(const Options &options) const {
return new carve::poly::Polyhedron(points, faceCount, faceIndices);
}
carve::mesh::MeshSet<3> *createMesh(const Options &options) const {
Options::const_iterator i;
carve::mesh::MeshOptions opts;
i = options.find("avoid_cavities");
if (i != options.end()) {
opts.avoid_cavities(_bool((*i).second));
}
return new carve::mesh::MeshSet<3>(points, faceCount, faceIndices, opts);
}
};
struct PolylineSetData : public VertexData {
typedef std::pair<bool, std::vector<int> > polyline_data_t;
std::list<polyline_data_t> polylines;
PolylineSetData() : VertexData(), polylines() {
}
virtual ~PolylineSetData() {
}
void beginPolyline(bool closed = false) {
polylines.push_back(std::make_pair(closed, std::vector<int>()));
}
void reservePolyline(size_t len) {
polylines.back().second.reserve(len);
}
void addPolylineIndex(int idx) {
polylines.back().second.push_back(idx);
}
carve::line::PolylineSet *create(const Options &options) const {
carve::line::PolylineSet *p = new carve::line::PolylineSet(points);
for (std::list<polyline_data_t>::const_iterator i = polylines.begin();
i != polylines.end();
++i) {
p->addPolyline((*i).first, (*i).second.begin(), (*i).second.end());
}
return p;
}
};
struct PointSetData : public VertexData {
PointSetData() : VertexData() {
}
virtual ~PointSetData() {
}
carve::point::PointSet *create(const Options &options) const {
carve::point::PointSet *p = new carve::point::PointSet(points);
return p;
}
};
class Input {
public:
std::list<Data *> input;
Input() {
}
~Input() {
for (std::list<Data *>::iterator i = input.begin(); i != input.end(); ++i) {
delete (*i);
}
}
void addDataBlock(Data *data) {
input.push_back(data);
}
void transform(const carve::math::Matrix &transform) {
if (transform == carve::math::Matrix::IDENT()) return;
for (std::list<Data *>::iterator i = input.begin(); i != input.end(); ++i) {
(*i)->transform(transform);
}
}
template<typename T>
static inline T *create(Data *d, const Options &options = Options()) {
return NULL;
}
};
template<>
inline carve::mesh::MeshSet<3> *Input::create(Data *d, const Options &options) {
PolyhedronData *p = dynamic_cast<PolyhedronData *>(d);
if (p == NULL) return NULL;
return p->createMesh(options);
}
template<>
inline carve::poly::Polyhedron *Input::create(Data *d, const Options &options) {
PolyhedronData *p = dynamic_cast<PolyhedronData *>(d);
if (p == NULL) return NULL;
return p->create(options);
}
template<>
inline carve::line::PolylineSet *Input::create(Data *d, const Options &options) {
PolylineSetData *p = dynamic_cast<PolylineSetData *>(d);
if (p == NULL) return NULL;
return p->create(options);
}
template<>
inline carve::point::PointSet *Input::create(Data *d, const Options &options) {
PointSetData *p = dynamic_cast<PointSetData *>(d);
if (p == NULL) return NULL;
return p->create(options);
}
}
}

View File

@@ -0,0 +1,513 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom2d.hpp>
#include <carve/poly.hpp>
#include <carve/mesh.hpp>
#include <carve/csg.hpp>
namespace carve {
namespace interpolate {
static inline std::vector<double> polyInterpolate(const std::vector<carve::geom2d::P2> &s,
const carve::geom2d::P2 &v) {
// see hormann et al. 2006
const size_t SZ = s.size();
std::vector<double> r;
std::vector<double> A;
std::vector<double> D;
std::vector<double> result;
r.resize(SZ);
A.resize(SZ);
D.resize(SZ);
result.resize(SZ, 0.0);
for (size_t i = 0; i < SZ; ++i) {
size_t i2 = (i + 1) % SZ;
carve::geom2d::P2 si = s[i] - v;
carve::geom2d::P2 si2 = s[i2] - v;
r[i] = sqrt(dot(si, si));
A[i] = cross(si, si2) / 2.0;
D[i] = dot(si, si2);
if (fabs(r[i]) < 1e-16) {
result[i] = 1.0;
return result;
} else if (fabs(A[i]) < 1e-16 && D[i] < 0.0) {
double r2 = sqrt(dot(si2, si2));
result[i2] = r[i] / (r[i] + r2);
result[i] = r2 / (r[i] + r2);
return result;
}
}
double w_sum = 0.0;
for (size_t i = 0; i < SZ; ++i) {
size_t i_m = (i + SZ - 1) % SZ;
size_t i_p = (i + 1) % SZ;
double w = 0.0;
if (fabs(A[i_m]) > 1e-16)
w += (r[i_m] - D[i_m] / r[i]) / A[i_m];
if (fabs(A[i]) > 1e-16)
w += (r[i_p] - D[i] / r[i]) / A[i];
result[i] = w;
w_sum += w;
}
for (size_t i = 0; i < SZ; ++i) {
result[i] /= w_sum;
}
// carve::geom2d::P2 test;
// for (size_t i = 0; i < SZ; ++i) {
// test = test + result[i] * s[i];
// }
return result;
}
template<typename iter_t,
typename adapt_t,
typename val_t,
typename mod_t>
val_t interp(iter_t begin,
iter_t end,
adapt_t adapt,
const std::vector<val_t> &vals,
double x,
double y,
mod_t mod = mod_t()) {
std::vector<carve::geom2d::P2> s;
s.reserve(std::distance(begin, end));
std::transform(begin, end, std::back_inserter(s), adapt);
std::vector<double> weight = polyInterpolate(s, carve::geom::VECTOR(x, y));
val_t v;
for (size_t z = 0; z < weight.size(); z++) {
v += weight[z] * vals[z];
}
return mod(v);
}
template<typename iter_t,
typename adapt_t,
typename val_t>
val_t interp(iter_t begin,
iter_t end,
adapt_t adapt,
const std::vector<val_t> &vals,
double x,
double y) {
return interp(begin, end, adapt, vals, x, y, identity_t<val_t>());
}
template<typename vertex_t,
typename adapt_t,
typename val_t,
typename mod_t>
val_t interp(const std::vector<vertex_t> &poly,
adapt_t adapt,
const std::vector<val_t> &vals,
double x,
double y,
mod_t mod = mod_t()) {
return interp(poly.begin(), poly.end(), adapt, vals, x, y, mod);
}
template<typename vertex_t,
typename adapt_t,
typename val_t>
val_t interp(const std::vector<vertex_t> &poly,
adapt_t adapt,
const std::vector<val_t> &vals,
double x,
double y) {
return interp(poly.begin(), poly.end(), adapt, vals, x, y, identity_t<val_t>());
}
template<typename val_t,
typename mod_t>
val_t interp(const std::vector<carve::geom2d::P2> &poly,
const std::vector<val_t> &vals,
double x,
double y,
mod_t mod = mod_t()) {
std::vector<double> weight = polyInterpolate(poly, carve::geom::VECTOR(x, y));
val_t v;
for (size_t z = 0; z < weight.size(); z++) {
v += weight[z] * vals[z];
}
return mod(v);
}
template<typename val_t>
val_t interp(const std::vector<carve::geom2d::P2> &poly,
const std::vector<val_t> &vals,
double x,
double y) {
return interp(poly, vals, x, y, identity_t<val_t>());
}
class Interpolator {
public:
typedef carve::mesh::MeshSet<3> meshset_t;
protected:
friend struct Hook;
struct Hook : public carve::csg::CSG::Hook {
const carve::csg::CSG &csg;
Interpolator *interpolator;
virtual unsigned hookBits() const {
return carve::csg::CSG::Hooks::RESULT_FACE_BIT;
}
virtual void resultFace(const meshset_t::face_t *new_face,
const meshset_t::face_t *orig_face,
bool flipped) {
interpolator->resultFace(csg, new_face, orig_face, flipped);
}
virtual void processOutputFace(std::vector<carve::mesh::MeshSet<3>::face_t *> &new_faces,
const meshset_t::face_t *orig_face,
bool flipped) {
interpolator->processOutputFace(csg, new_faces, orig_face, flipped);
}
virtual void edgeDivision(const meshset_t::edge_t *orig_edge,
size_t orig_edge_idx,
const meshset_t::vertex_t *v1,
const meshset_t::vertex_t *v2) {
interpolator->edgeDivision(csg, orig_edge, orig_edge_idx, v1, v2);
}
Hook(Interpolator *_interpolator, const carve::csg::CSG &_csg) : csg(_csg), interpolator(_interpolator) {
}
virtual ~Hook() {
}
};
virtual Hook *makeHook(carve::csg::CSG &csg) {
return new Hook(this, csg);
}
virtual void resultFace(const carve::csg::CSG &csg,
const meshset_t::face_t *new_face,
const meshset_t::face_t *orig_face,
bool flipped) {
}
virtual void processOutputFace(const carve::csg::CSG &csg,
std::vector<carve::mesh::MeshSet<3>::face_t *> &new_faces,
const meshset_t::face_t *orig_face,
bool flipped) {
}
virtual void edgeDivision(const carve::csg::CSG &csg,
const meshset_t::edge_t *orig_edge,
size_t orig_edge_idx,
const meshset_t::vertex_t *v1,
const meshset_t::vertex_t *v2) {
}
public:
Interpolator() {
}
virtual ~Interpolator() {
}
void installHooks(carve::csg::CSG &csg) {
Hook *hook = makeHook(csg);
csg.hooks.registerHook(hook, hook->hookBits());
}
};
template<typename attr_t>
class FaceVertexAttr : public Interpolator {
public:
typedef std::pair<const meshset_t::face_t *, unsigned> key_t;
protected:
struct key_hash {
size_t operator()(const key_t &v) const {
return size_t(v.first) ^ size_t(v.second);
}
};
typedef std::unordered_map<const meshset_t::vertex_t *, attr_t> attrvmap_t;
typedef std::unordered_map<key_t, attr_t, key_hash> attrmap_t;
attrmap_t attrs;
virtual void resultFace(const carve::csg::CSG &csg,
const meshset_t::face_t *new_face,
const meshset_t::face_t *orig_face,
bool flipped) {
std::vector<attr_t> vertex_attrs;
attrvmap_t base_attrs;
vertex_attrs.reserve(orig_face->nVertices());
for (meshset_t::face_t::const_edge_iter_t e = orig_face->begin(); e != orig_face->end(); ++e) {
typename attrmap_t::const_iterator a = attrs.find(key_t(orig_face, e.idx()));
if (a == attrs.end()) return;
vertex_attrs.push_back((*a).second);
base_attrs[e->vert] = vertex_attrs.back();
}
for (meshset_t::face_t::const_edge_iter_t e = new_face->begin(); e != new_face->end(); ++e) {
const meshset_t::vertex_t *vertex = e->vert;
typename attrvmap_t::const_iterator b = base_attrs.find(vertex);
if (b != base_attrs.end()) {
attrs[key_t(new_face, e.idx())] = (*b).second;
} else {
carve::geom2d::P2 p = orig_face->project(e->vert->v);
attr_t attr = interp(orig_face->begin(),
orig_face->end(),
orig_face->projector(),
vertex_attrs,
p.x,
p.y);
attrs[key_t(new_face, e.idx())] = attr;
}
}
}
public:
bool hasAttribute(const meshset_t::face_t *f, unsigned v) {
return attrs.find(key_t(f, v)) != attrs.end();
}
attr_t getAttribute(const meshset_t::face_t *f, unsigned v, const attr_t &def = attr_t()) {
typename attrmap_t::const_iterator fv = attrs.find(key_t(f, v));
if (fv != attrs.end()) {
return (*fv).second;
}
return def;
}
void setAttribute(const meshset_t::face_t *f, unsigned v, const attr_t &attr) {
attrs[key_t(f, v)] = attr;
}
FaceVertexAttr() : Interpolator() {
}
virtual ~FaceVertexAttr() {
}
};
template<typename attr_t>
class FaceEdgeAttr : public Interpolator {
public:
typedef std::pair<const meshset_t::face_t *, unsigned> key_t;
protected:
typedef std::pair<const meshset_t::vertex_t *, const meshset_t::vertex_t *> vpair_t;
struct key_hash {
size_t operator()(const key_t &v) const {
return size_t(v.first) ^ size_t(v.second);
}
};
struct vpair_hash {
size_t operator()(const vpair_t &v) const {
return size_t(v.first) ^ size_t(v.second);
}
};
typedef std::unordered_map<key_t, attr_t, key_hash> attrmap_t;
typedef std::unordered_map<vpair_t, key_t, vpair_hash> edgedivmap_t;
attrmap_t attrs;
edgedivmap_t edgediv;
struct Hook : public Interpolator::Hook {
public:
virtual unsigned hookBits() const {
return
carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT |
carve::csg::CSG::Hooks::EDGE_DIVISION_BIT;
}
Hook(Interpolator *_interpolator, const carve::csg::CSG &_csg) : Interpolator::Hook(_interpolator, _csg) {
}
virtual ~Hook() {
}
};
virtual Interpolator::Hook *makeHook(carve::csg::CSG &csg) {
return new Hook(this, csg);
}
virtual void edgeDivision(const carve::csg::CSG &csg,
const meshset_t::edge_t *orig_edge,
size_t orig_edge_idx,
const meshset_t::vertex_t *v1,
const meshset_t::vertex_t *v2) {
key_t k(orig_edge->face, orig_edge_idx);
typename attrmap_t::const_iterator attr_i = attrs.find(k);
if (attr_i == attrs.end()) return;
edgediv[vpair_t(v1, v2)] = k;
}
virtual void processOutputFace(const carve::csg::CSG &csg,
std::vector<carve::mesh::MeshSet<3>::face_t *> &new_faces,
const meshset_t::face_t *orig_face,
bool flipped) {
edgedivmap_t undiv;
for (meshset_t::face_t::const_edge_iter_t e = orig_face->begin(); e != orig_face->end(); ++e) {
key_t k(orig_face, e.idx());
typename attrmap_t::const_iterator attr_i = attrs.find(k);
if (attr_i == attrs.end()) {
continue;
} else {
undiv[vpair_t(e->v1(), e->v2())] = k;
}
}
for (size_t fnum = 0; fnum < new_faces.size(); ++fnum) {
const carve::mesh::MeshSet<3>::face_t *new_face = new_faces[fnum];
for (meshset_t::face_t::const_edge_iter_t e = new_face->begin(); e != new_face->end(); ++e) {
key_t k(new_face, e.idx());
vpair_t vp;
if (!flipped) {
vp = vpair_t(e->v1(), e->v2());
} else {
vp = vpair_t(e->v2(), e->v1());
}
typename edgedivmap_t::const_iterator vp_i;
if ((vp_i = undiv.find(vp)) != undiv.end()) {
attrs[k] = attrs[vp_i->second];
} else if ((vp_i = edgediv.find(vp)) != edgediv.end()) {
attrs[k] = attrs[vp_i->second];
}
}
}
}
public:
bool hasAttribute(const meshset_t::face_t *f, unsigned e) {
return attrs.find(std::make_pair(f, e)) != attrs.end();
}
attr_t getAttribute(const meshset_t::face_t *f, unsigned e, const attr_t &def = attr_t()) {
typename attrmap_t::const_iterator fv = attrs.find(std::make_pair(f, e));
if (fv != attrs.end()) {
return (*fv).second;
}
return def;
}
void setAttribute(const meshset_t::face_t *f, unsigned e, const attr_t &attr) {
attrs[std::make_pair(f, e)] = attr;
}
FaceEdgeAttr() : Interpolator() {
}
virtual ~FaceEdgeAttr() {
}
};
template<typename attr_t>
class FaceAttr : public Interpolator {
public:
typedef const meshset_t::face_t *key_t;
protected:
struct key_hash {
size_t operator()(const key_t &f) const {
return size_t(f);
}
};
typedef std::unordered_map<key_t, attr_t, key_hash> attrmap_t;
attrmap_t attrs;
virtual void resultFace(const carve::csg::CSG &csg,
const meshset_t::face_t *new_face,
const meshset_t::face_t *orig_face,
bool flipped) {
typename attrmap_t::const_iterator i = attrs.find(key_t(orig_face));
if (i != attrs.end()) {
attrs[key_t(new_face)] = (*i).second;
}
}
public:
bool hasAttribute(const meshset_t::face_t *f) {
return attrs.find(key_t(f)) != attrs.end();
}
attr_t getAttribute(const meshset_t::face_t *f, const attr_t &def = attr_t()) {
typename attrmap_t::const_iterator i = attrs.find(key_t(f));
if (i != attrs.end()) {
return (*i).second;
}
return def;
}
void setAttribute(const meshset_t::face_t *f, const attr_t &attr) {
attrs[key_t(f)] = attr;
}
FaceAttr() : Interpolator() {
}
virtual ~FaceAttr() {
}
};
}
}

View File

@@ -0,0 +1,267 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/collection_types.hpp>
#include <carve/iobj.hpp>
namespace carve {
namespace csg {
/**
* \class Intersections
* \brief Storage for computed intersections between vertices, edges and faces.
*
*/
struct Intersections : public std::unordered_map<IObj, IObjVMapSmall, IObj_hash> {
typedef carve::mesh::MeshSet<3>::vertex_t vertex_t;
typedef carve::mesh::MeshSet<3>::edge_t edge_t;
typedef carve::mesh::MeshSet<3>::face_t face_t;
typedef std::unordered_map<IObj, IObjVMapSmall, IObj_hash> super;
~Intersections() {
}
/**
* \brief Record the position of intersection between a pair of intersection objects.
*
* @param a The first intersecting object.
* @param b The second intersecting object.
* @param p The point of intersection.
*/
void record(IObj a, IObj b, vertex_t *p) {
if (a > b) std::swap(a, b);
(*this)[a][b] = p;
(*this)[b][a] = p;
}
/**
* \brief Test whether vertex \a v intersects face \a f.
*
* @param v The vertex to test.
* @param f The face to test.
*
* @return true, if \a v intersects \a f.
*/
bool intersectsFace(vertex_t *v, face_t *f) const;
/**
* \brief Collect sets of vertices, edges and faces that intersect \a obj
*
* @param[in] obj The intersection object to search for intersections.
* @param[out] collect_v A vector of vertices intersecting \a obj.
* @param[out] collect_e A vector of edges intersecting \a obj.
* @param[out] collect_f A vector of faces intersecting \a obj.
*/
void collect(const IObj &obj,
std::vector<vertex_t *> *collect_v,
std::vector<edge_t *> *collect_e,
std::vector<face_t *> *collect_f) const;
/**
* \brief Determine whether two intersection objects intersect.
*
* @param a The first intersection object.
* @param b The second intersection object.
*
* @return true, if \a a and \a b intersect.
*/
bool intersectsExactly(const IObj &a, const IObj &b) {
Intersections::const_iterator i = find(a);
if (i == end()) return false;
return i->second.find(b) != i->second.end();
}
/**
* \brief Determine whether an intersection object intersects a vertex.
*
* @param a The intersection object.
* @param v The vertex.
*
* @return true, if \a a and \a v intersect.
*/
bool intersects(const IObj &a, vertex_t *v) {
Intersections::const_iterator i = find(a);
if (i == end()) return false;
if (i->second.find(v) != i->second.end()) return true;
return false;
}
/**
* \brief Determine whether an intersection object intersects an edge.
*
* @param a The intersection object.
* @param e The edge.
*
* @return true, if \a a and \a e intersect (either on the edge,
* or at either endpoint).
*/
bool intersects(const IObj &a, edge_t *e) {
Intersections::const_iterator i = find(a);
if (i == end()) return false;
for (super::data_type::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
const IObj &obj = j->first;
switch (obj.obtype) {
case IObj::OBTYPE_VERTEX:
if (obj.vertex == e->v1() || obj.vertex == e->v2()) return true;
break;
case IObj::OBTYPE_EDGE:
if (obj.edge == e) return true;
break;
default:
break;
}
}
return false;
}
/**
* \brief Determine whether an intersection object intersects a face.
*
* @param a The intersection object.
* @param f The face.
*
* @return true, if \a a and \a f intersect (either on the face,
* or at any associated edge or vertex).
*/
bool intersects(const IObj &a, face_t *f) {
Intersections::const_iterator i = find(a);
if (i == end()) return false;
if (i->second.find(f) != i->second.end()) return true;
edge_t *e = f->edge;
do {
if (i->second.find(e) != i->second.end()) return true;
if (i->second.find(e->vert) != i->second.end()) return true;
e = e->next;
} while (e != f->edge);
return false;
}
/**
* \brief Determine whether an edge intersects another edge.
*
* @param e The edge.
* @param f The face.
*
* @return true, if \a e and \a f intersect.
*/
bool intersects(edge_t *e1, edge_t *e2) {
if (intersects(e1->v1(), e2) || intersects(e1->v2(), e2) || intersects(IObj(e1), e2)) return true;
return false;
}
/**
* \brief Determine whether an edge intersects a face.
*
* @param e The edge.
* @param f The face.
*
* @return true, if \a e and \a f intersect.
*/
bool intersects(edge_t *e, face_t *f) {
if (intersects(e->v1(), f) || intersects(e->v2(), f) || intersects(IObj(e), f)) return true;
return false;
}
/**
* \brief Determine the faces intersected by an edge.
*
* @tparam face_set_t A collection type holding face_t *
* @param[in] e The edge.
* @param[out] f The resulting set of faces.
*/
template<typename face_set_t>
void intersectedFaces(edge_t *e, face_set_t &f) const {
std::vector<face_t *> intersected_faces;
std::vector<edge_t *> intersected_edges;
std::vector<vertex_t *> intersected_vertices;
collect(e, &intersected_vertices, &intersected_edges, &intersected_faces);
for (unsigned i = 0; i < intersected_vertices.size(); ++i) {
facesForVertex(intersected_vertices[i], f);
}
for (unsigned i = 0; i < intersected_edges.size(); ++i) {
facesForEdge(intersected_edges[i], f);
}
f.insert(intersected_faces.begin(), intersected_faces.end());
}
/**
* \brief Determine the faces intersected by a vertex.
*
* @tparam face_set_t A collection type holding face_t *
* @param[in] v The vertex.
* @param[out] f The resulting set of faces.
*/
template<typename face_set_t>
void intersectedFaces(vertex_t *v, face_set_t &f) const {
std::vector<face_t *> intersected_faces;
std::vector<edge_t *> intersected_edges;
std::vector<vertex_t *> intersected_vertices;
collect(v, &intersected_vertices, &intersected_edges, &intersected_faces);
for (unsigned i = 0; i < intersected_vertices.size(); ++i) {
facesForVertex(intersected_vertices[i], f);
}
for (unsigned i = 0; i < intersected_edges.size(); ++i) {
facesForEdge(intersected_edges[i], f);
}
f.insert(intersected_faces.begin(), intersected_faces.end());
}
/**
* \brief Collect the set of faces that contain all vertices in \a verts.
*
* @tparam vertex_set_t A collection type holding vertex_t *
* @tparam face_set_t A collection type holding face_t *
* @param[in] verts A set of vertices.
* @param[out] result The resulting set of faces.
*/
template<typename vertex_set_t, typename face_set_t>
void commonFaces(const vertex_set_t &verts, face_set_t &result) {
std::set<face_t *> ifaces, temp, out;
typename vertex_set_t::const_iterator i = verts.begin();
if (i == verts.end()) return;
intersectedFaces((*i), ifaces);
while (++i != verts.end()) {
temp.clear();
intersectedFaces((*i), temp);
out.clear();
std::set_intersection(temp.begin(), temp.end(),
ifaces.begin(), ifaces.end(),
set_inserter(out));
ifaces.swap(out);
}
std::copy(ifaces.begin(), ifaces.end(), set_inserter(result));
}
void clear() {
super::clear();
}
};
}
}

106
extern/carve/include/carve/iobj.hpp vendored Normal file
View File

@@ -0,0 +1,106 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
namespace carve {
namespace csg {
struct IObj {
enum {
OBTYPE_NONE = 0,
OBTYPE_VERTEX = 1,
OBTYPE_EDGE = 2,
OBTYPE_FACE = 4
} obtype;
union {
carve::mesh::MeshSet<3>::vertex_t *vertex;
carve::mesh::MeshSet<3>::edge_t *edge;
carve::mesh::MeshSet<3>::face_t *face;
intptr_t val;
};
IObj() : obtype(OBTYPE_NONE), val(0) { }
IObj(carve::mesh::MeshSet<3>::vertex_t *v) : obtype(OBTYPE_VERTEX), vertex(v) { }
IObj(carve::mesh::MeshSet<3>::edge_t *e) : obtype(OBTYPE_EDGE), edge(e) { }
IObj(carve::mesh::MeshSet<3>::face_t *f) : obtype(OBTYPE_FACE), face(f) { }
char typeChar() const { return "NVExF"[obtype]; }
};
struct IObj_hash {
inline size_t operator()(const IObj &i) const {
return (size_t)i.val;
}
inline size_t operator()(const std::pair<const IObj, const IObj> &i) const {
return (size_t)i.first.val ^ (size_t)i.second.val;
}
};
typedef std::unordered_set<std::pair<const IObj, const IObj>, IObj_hash> IObjPairSet;
typedef std::unordered_map<IObj, carve::mesh::MeshSet<3>::vertex_t *, IObj_hash> IObjVMap;
typedef std::map<IObj, carve::mesh::MeshSet<3>::vertex_t *> IObjVMapSmall;
class VertexIntersections :
public std::unordered_map<carve::mesh::MeshSet<3>::vertex_t *, IObjPairSet> {
};
static inline bool operator==(const carve::csg::IObj &a, const carve::csg::IObj &b) {
return a.obtype == b.obtype && a.val == b.val;
}
static inline bool operator!=(const carve::csg::IObj &a, const carve::csg::IObj &b) {
return a.obtype != b.obtype || a.val != b.val;
}
static inline bool operator<(const carve::csg::IObj &a, const carve::csg::IObj &b) {
return a.obtype < b.obtype || (a.obtype == b.obtype && a.val < b.val);
}
static inline bool operator<=(const carve::csg::IObj &a, const carve::csg::IObj &b) {
return a.obtype < b.obtype || (a.obtype == b.obtype && a.val <= b.val);
}
static inline bool operator>(const carve::csg::IObj &a, const carve::csg::IObj &b) {
return a.obtype > b.obtype || (a.obtype == b.obtype && a.val > b.val);
}
static inline bool operator>=(const carve::csg::IObj &a, const carve::csg::IObj &b) {
return a.obtype > b.obtype || (a.obtype == b.obtype && a.val >= b.val);
}
static inline std::ostream &operator<<(std::ostream &o, const carve::csg::IObj &a) {
switch (a.obtype) {
case carve::csg::IObj::OBTYPE_NONE: o << "NONE{}"; break;
case carve::csg::IObj::OBTYPE_VERTEX: o << "VERT{" << a.vertex << "}"; break;
case carve::csg::IObj::OBTYPE_EDGE: o << "EDGE{" << a.edge << "}"; break;
case carve::csg::IObj::OBTYPE_FACE: o << "FACE{" << a.face << "}"; break;
}
return o;
}
}
}

308
extern/carve/include/carve/kd_node.hpp vendored Normal file
View File

@@ -0,0 +1,308 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom.hpp>
#include <carve/aabb.hpp>
#include <queue>
#include <list>
#include <limits>
namespace carve {
namespace geom {
template<unsigned ndim,
typename data_t,
typename inserter_t,
typename aabb_calc_t>
class kd_node {
kd_node(const kd_node &);
kd_node &operator=(const kd_node &);
public:
kd_node *c_neg;
kd_node *c_pos;
kd_node *parent;
axis_pos splitpos;
typedef vector<ndim> vector_t;
typedef std::list<data_t> container_t;
container_t data;
kd_node(kd_node *_parent = NULL) : c_neg(NULL), c_pos(NULL), parent(_parent), splitpos(0, 0.0) {
}
~kd_node() {
if (c_neg) delete c_neg;
if (c_pos) delete c_pos;
}
template<typename visitor_t>
void closeNodes(const vector_t &p, double d, visitor_t &visit) const {
if (c_neg) {
double delta = splitpos.pos - p[splitpos.axis];
if (delta <= d) c_neg->closeNodes(p, d, visit);
if (delta >= -d) c_pos->closeNodes(p, d, visit);
} else {
visit(this);
}
}
void removeData(const data_t &d) {
typename container_t::iterator i = std::find(data.begin(), data.end(), d);
if (i != data.end()) {
data.erase(i);
}
}
void addData(const data_t &d) {
data.push_back(d);
}
void insert(const data_t &data, inserter_t &inserter) {
inserter.insert(this, data);
}
void insert(const data_t &data) {
inserter_t inserter;
insert(data, inserter);
}
void remove(const data_t &data, inserter_t &inserter) {
inserter.remove(this, data);
}
void remove(const data_t &data) {
inserter_t inserter;
remove(data, inserter);
}
carve::geom::aabb<ndim> nodeAABB() const {
carve::geom::aabb<ndim> aabb;
if (c_neg) {
aabb = c_neg->nodeAABB();
aabb.unionAABB(c_pos->nodeAABB());
} else {
if (data.size()) {
typename container_t::const_iterator i = data.begin();
aabb = aabb_calc_t()(*i);
while (i != data.end()) {
aabb.unionAABB(aabb_calc_t()(*i));
++i;
}
}
}
return aabb;
}
bool split(axis_pos split_at, inserter_t &inserter) {
if (c_neg) {
// already split
return false;
}
c_neg = new kd_node(this);
c_pos = new kd_node(this);
// choose an axis and split point.
splitpos = split_at;
carve::geom::aabb<ndim> aabb;
if (splitpos.axis < 0 ||
splitpos.axis >= ndim ||
splitpos.pos == std::numeric_limits<double>::max()) {
// need an aabb
if (data.size()) {
typename container_t::const_iterator i = data.begin();
aabb = aabb_calc_t()(*i);
while (i != data.end()) {
aabb.unionAABB(aabb_calc_t()(*i));
++i;
}
}
}
if (splitpos.axis < 0 || splitpos.axis >= ndim) {
// choose an axis;
// if no axis was specified, force calculation of the split position.
splitpos.pos = std::numeric_limits<double>::max();
// choose the axis of the AABB with the biggest extent.
splitpos.axis = largestAxis(aabb.extent);
if (parent && splitpos.axis == parent->splitpos.axis) {
// but don't choose the same axis as the parent node;
// choose the axis with the second greatest AABB extent.
double e = -1.0;
int a = -1;
for (int i = 0; i < ndim; ++i) {
if (i == splitpos.axis) continue;
if (e < aabb.extent[i]) { a = i; e = aabb.extent[i]; }
}
if (a != -1) {
splitpos.axis = a;
}
}
}
if (splitpos.pos == std::numeric_limits<double>::max()) {
carve::geom::vector<ndim> min = aabb.min();
carve::geom::vector<ndim> max = aabb.max();
splitpos.pos = aabb.pos.v[splitpos.axis];
}
inserter.propagate(this);
return true;
}
bool split(axis_pos split_at = axis_pos(-1, std::numeric_limits<double>::max())) {
inserter_t inserter;
return split(split_at, inserter);
}
void splitn(int num, inserter_t &inserter) {
if (num <= 0) return;
if (!c_neg) {
split(inserter);
}
if (c_pos) c_pos->splitn(num-1, inserter);
if (c_neg) c_neg->splitn(num-1, inserter);
}
void splitn(int num) {
inserter_t inserter;
splitn(num, inserter);
}
template<typename split_t>
void splitn(int num, split_t splitter, inserter_t &inserter) {
if (num <= 0) return;
if (!c_neg) {
split(inserter, splitter(this));
}
if (c_pos) c_pos->splitn(num-1, inserter, splitter);
if (c_neg) c_neg->splitn(num-1, inserter, splitter);
}
template<typename split_t>
void splitn(int num, split_t splitter) {
inserter_t inserter;
splitn(num, splitter, inserter);
}
template<typename pred_t>
void splitpred(pred_t pred, inserter_t &inserter, int depth = 0) {
if (!c_neg) {
axis_pos splitpos(-1, std::numeric_limits<double>::max());
if (!pred(this, depth, splitpos)) return;
split(splitpos, inserter);
}
if (c_pos) c_pos->splitpred(pred, inserter, depth + 1);
if (c_neg) c_neg->splitpred(pred, inserter, depth + 1);
}
template<typename pred_t>
void splitpred(pred_t pred, int depth = 0) {
inserter_t inserter;
splitpred(pred, inserter, depth);
}
// distance_t must provide:
// double operator()(data_t, vector<ndim>);
// double operator()(axis_pos, vector<ndim>);
template<typename distance_t>
struct near_point_query {
// q_t - the priority queue value type.
// q_t.first: distance from object to query point.
// q_t.second: pointer to object
typedef std::pair<double, const data_t *> q_t;
// the queue priority should sort from smallest distance to largest, and on equal distance, by object pointer.
struct pcmp {
bool operator()(const q_t &a, const q_t &b) {
return (a.first > b.first) || ((a.first == b.first) && (a.second < b.second));
}
};
vector<ndim> point;
const kd_node *node;
std::priority_queue<q_t, std::vector<q_t>, pcmp> pq;
distance_t dist;
double dist_to_parent_split;
void addToPQ(kd_node *node) {
if (node->c_neg) {
addToPQ(node->c_neg);
addToPQ(node->c_pos);
} else {
for (typename kd_node::container_t::const_iterator i = node->data.begin(); i != node->data.end(); ++i) {
double d = dist((*i), point);
pq.push(std::make_pair(d, &(*i)));
}
}
}
const data_t *next() {
while (1) {
if (pq.size()) {
q_t t = pq.top();
if (!node->parent || t.first < dist_to_parent_split) {
pq.pop();
return t.second;
}
}
if (!node->parent) return NULL;
if (node->parent->c_neg == node) {
addToPQ(node->parent->c_pos);
} else {
addToPQ(node->parent->c_neg);
}
node = node->parent;
dist_to_parent_split = dist(node->splitpos, point);
}
}
near_point_query(const vector<ndim> _point, const kd_node *_node) : point(_point), node(_node), pq(), dist() {
while (node->c_neg) {
node = (point[node->axis] < node->pos) ? node->c_neg : node->c_pos;
}
if (node->parent) {
dist_to_parent_split = dist(node->parent->splitpos, point);
} else {
dist_to_parent_split = HUGE_VAL;
}
addToPQ(node);
}
};
};
}
}

60
extern/carve/include/carve/math.hpp vendored Normal file
View File

@@ -0,0 +1,60 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/math_constants.hpp>
#include <math.h>
namespace carve {
namespace geom {
template<unsigned ndim> struct vector;
}
}
namespace carve {
namespace math {
struct Matrix3;
int cubic_roots(double c3, double c2, double c1, double c0, double *roots);
void eigSolveSymmetric(const Matrix3 &m,
double &l1, carve::geom::vector<3> &e1,
double &l2, carve::geom::vector<3> &e2,
double &l3, carve::geom::vector<3> &e3);
void eigSolve(const Matrix3 &m, double &l1, double &l2, double &l3);
static inline bool ZERO(double x) { return fabs(x) < carve::EPSILON; }
static inline double radians(double deg) { return deg * M_PI / 180.0; }
static inline double degrees(double rad) { return rad * 180.0 / M_PI; }
static inline double ANG(double x) {
return (x < 0) ? x + M_TWOPI : x;
}
template<typename T>
static inline const T &clamp(const T &val, const T &min, const T &max) {
if (val < min) return min;
if (val > max) return max;
return val;
}
}
}

View File

@@ -0,0 +1,33 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <math.h>
#ifndef M_SQRT_3
#define M_SQRT_3 1.73205080756887729352
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_TWOPI
#define M_TWOPI (M_PI + M_PI)
#endif

262
extern/carve/include/carve/matrix.hpp vendored Normal file
View File

@@ -0,0 +1,262 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <cstring>
#include <carve/carve.hpp>
#include <carve/math.hpp>
#include <carve/geom.hpp>
namespace carve {
namespace math {
struct Quaternion {
double x, y, z, w;
Quaternion(double _x, double _y, double _z, double _w) : x(_x), y(_y), z(_z), w(_w) {
}
Quaternion(double angle, const carve::geom::vector<3> &axis) {
double s = axis.length();
if (!carve::math::ZERO(s)) {
double c = 1.0 / s;
double omega = -0.5 * angle;
s = sin(omega);
x = axis.x * c * s;
y = axis.y * c * s;
z = axis.z * c * s;
w = cos(omega);
normalize();
} else {
x = y = z = 0.0;
w = 1.0;
}
}
double lengthSquared() const {
return x * x + y * y + z * z + w * w;
}
double length() const {
return sqrt(lengthSquared());
}
Quaternion normalized() const {
return Quaternion(*this).normalize();
}
Quaternion &normalize() {
double l = length();
if (l == 0.0) {
x = 1.0; y = 0.0; z = 0.0; w = 0.0;
} else {
x /= l; y /= l; z /= l; w /= l;
}
return *this;
}
};
struct Matrix3 {
// access: .m[col][row], .v[col * 4 + row], ._cr
union {
double m[3][3];
double v[9];
struct {
// transposed
double _11, _12, _13;
double _21, _22, _23;
double _31, _32, _33;
};
};
Matrix3(double __11, double __21, double __31,
double __12, double __22, double __32,
double __13, double __23, double __33) {
// nb, args are row major, storage is column major.
_11 = __11; _12 = __12; _13 = __13;
_21 = __21; _22 = __22; _23 = __23;
_31 = __31; _32 = __32; _33 = __33;
}
Matrix3(double _m[3][3]) {
std::memcpy(m, _m, sizeof(m));
}
Matrix3(double _v[9]) {
std::memcpy(v, _v, sizeof(v));
}
Matrix3() {
_11 = 1.00; _12 = 0.00; _13 = 0.00;
_21 = 0.00; _22 = 1.00; _23 = 0.00;
_31 = 0.00; _32 = 0.00; _33 = 1.00;
}
};
struct Matrix {
// access: .m[col][row], .v[col * 4 + row], ._cr
union {
double m[4][4];
double v[16];
struct {
// transposed
double _11, _12, _13, _14;
double _21, _22, _23, _24;
double _31, _32, _33, _34;
double _41, _42 ,_43, _44;
};
};
Matrix(double __11, double __21, double __31, double __41,
double __12, double __22, double __32, double __42,
double __13, double __23, double __33, double __43,
double __14, double __24, double __34, double __44) {
// nb, args are row major, storage is column major.
_11 = __11; _12 = __12; _13 = __13; _14 = __14;
_21 = __21; _22 = __22; _23 = __23; _24 = __24;
_31 = __31; _32 = __32; _33 = __33; _34 = __34;
_41 = __41; _42 = __42; _43 = __43; _44 = __44;
}
Matrix(double _m[4][4]) {
std::memcpy(m, _m, sizeof(m));
}
Matrix(double _v[16]) {
std::memcpy(v, _v, sizeof(v));
}
Matrix() {
_11 = 1.00; _12 = 0.00; _13 = 0.00; _14 = 0.00;
_21 = 0.00; _22 = 1.00; _23 = 0.00; _24 = 0.00;
_31 = 0.00; _32 = 0.00; _33 = 1.00; _34 = 0.00;
_41 = 0.00; _42 = 0.00; _43 = 0.00; _44 = 1.00;
}
static Matrix ROT(const Quaternion &q) {
const double w = q.w;
const double x = q.x;
const double y = q.y;
const double z = q.z;
return Matrix(1 - 2*y*y - 2*z*z, 2*x*y - 2*z*w, 2*x*z + 2*y*w, 0.0,
2*x*y + 2*z*w, 1 - 2*x*x - 2*z*z, 2*y*z - 2*x*w, 0.0,
2*x*z - 2*y*w, 2*y*z + 2*x*w, 1 - 2*x*x - 2*y*y, 0.0,
0.0, 0.0, 0.0, 1.0);
}
static Matrix ROT(double angle, const carve::geom::vector<3> &axis) {
return ROT(Quaternion(angle, axis));
}
static Matrix ROT(double angle, double x, double y, double z) {
return ROT(Quaternion(angle, carve::geom::VECTOR(x, y, z)));
}
static Matrix TRANS(double x, double y, double z) {
return Matrix(1.0, 0.0, 0.0, x,
0.0, 1.0, 0.0, y,
0.0, 0.0, 1.0, z,
0.0, 0.0, 0.0, 1.0);
}
static Matrix TRANS(const carve::geom::vector<3> &v) {
return TRANS(v.x, v.y, v.z);
}
static Matrix SCALE(double x, double y, double z) {
return Matrix(x, 0.0, 0.0, 0.0,
0.0, y, 0.0, 0.0,
0.0, 0.0, z, 0.0,
0.0, 0.0, 0.0, 1.0);
}
static Matrix SCALE(const carve::geom::vector<3> &v) {
return SCALE(v.x, v.y, v.z);
}
static Matrix IDENT() {
return Matrix(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
}
};
static inline bool operator==(const Matrix &A, const Matrix &B) {
for (size_t i = 0; i < 16; ++i) if (A.v[i] != B.v[i]) return false;
return true;
}
static inline bool operator!=(const Matrix &A, const Matrix &B) {
return !(A == B);
}
static inline carve::geom::vector<3> operator*(const Matrix &A, const carve::geom::vector<3> &b) {
return carve::geom::VECTOR(
A._11 * b.x + A._21 * b.y + A._31 * b.z + A._41,
A._12 * b.x + A._22 * b.y + A._32 * b.z + A._42,
A._13 * b.x + A._23 * b.y + A._33 * b.z + A._43
);
}
static inline carve::geom::vector<3> &operator*=(carve::geom::vector<3> &b, const Matrix &A) {
b = A * b;
return b;
}
static inline carve::geom::vector<3> operator*(const Matrix3 &A, const carve::geom::vector<3> &b) {
return carve::geom::VECTOR(
A._11 * b.x + A._21 * b.y + A._31 * b.z,
A._12 * b.x + A._22 * b.y + A._32 * b.z,
A._13 * b.x + A._23 * b.y + A._33 * b.z
);
}
static inline carve::geom::vector<3> &operator*=(carve::geom::vector<3> &b, const Matrix3 &A) {
b = A * b;
return b;
}
static inline Matrix operator*(const Matrix &A, const Matrix &B) {
Matrix c;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
c.m[i][j] = 0.0;
for (int k = 0; k < 4; k++) {
c.m[i][j] += A.m[k][j] * B.m[i][k];
}
}
}
return c;
}
static inline Matrix3 operator*(const Matrix3 &A, const Matrix3 &B) {
Matrix3 c;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
c.m[i][j] = 0.0;
for (int k = 0; k < 3; k++) {
c.m[i][j] += A.m[k][j] * B.m[i][k];
}
}
}
return c;
}
struct matrix_transformation {
Matrix matrix;
matrix_transformation(const Matrix &_matrix) : matrix(_matrix) {
}
carve::geom::vector<3> operator()(const carve::geom::vector<3> &vector) const {
return matrix * vector;
}
};
}
}

874
extern/carve/include/carve/mesh.hpp vendored Normal file
View File

@@ -0,0 +1,874 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom.hpp>
#include <carve/geom3d.hpp>
#include <carve/tag.hpp>
#include <carve/djset.hpp>
#include <carve/aabb.hpp>
#include <carve/rtree.hpp>
#include <iostream>
namespace carve {
namespace poly {
class Polyhedron;
}
namespace mesh {
template<unsigned ndim> class Edge;
template<unsigned ndim> class Face;
template<unsigned ndim> class Mesh;
template<unsigned ndim> class MeshSet;
// A Vertex may participate in several meshes. If the Mesh belongs
// to a MeshSet, then the vertices come from the vertex_storage
// member of the MeshSet. This allows one to construct one or more
// Meshes out of sets of connected faces (possibly using vertices
// from a variety of MeshSets, and other storage), then create a
// MeshSet from the Mesh(es), causing the vertices to be
// collected, cloned and repointed into the MeshSet.
// Normally, in a half-edge structure, Vertex would have a member
// pointing to an incident edge, allowing the enumeration of
// adjacent faces and edges. Because we want to support vertex
// sharing between Meshes and groups of Faces, this is made more
// complex. If Vertex contained a list of incident edges, one from
// each disjoint face set, then this could be done (with the
// caveat that you'd need to pass in a Mesh pointer to the
// adjacency queries). However, it seems that this would
// unavoidably complicate the process of incorporating or removing
// a vertex into an edge.
// In most cases it is expected that a vertex will be arrived at
// via an edge or face in the mesh (implicit or explicit) of
// interest, so not storing this information will not hurt,
// overly.
template<unsigned ndim>
class Vertex : public tagable {
public:
typedef carve::geom::vector<ndim> vector_t;
typedef MeshSet<ndim> owner_t;
typedef carve::geom::aabb<ndim> aabb_t;
carve::geom::vector<ndim> v;
Vertex(const vector_t &_v) : tagable(), v(_v) {
}
Vertex() : tagable(), v() {
}
aabb_t getAABB() const {
return aabb_t(v, carve::geom::vector<ndim>::ZERO());
}
};
struct hash_vertex_pair {
template<unsigned ndim>
size_t operator()(const std::pair<Vertex<ndim> *, Vertex<ndim> *> &pair) const {
size_t r = (size_t)pair.first;
size_t s = (size_t)pair.second;
return r ^ ((s >> 16) | (s << 16));
}
template<unsigned ndim>
size_t operator()(const std::pair<const Vertex<ndim> *, const Vertex<ndim> *> &pair) const {
size_t r = (size_t)pair.first;
size_t s = (size_t)pair.second;
return r ^ ((s >> 16) | (s << 16));
}
};
struct vertex_distance {
template<unsigned ndim>
double operator()(const Vertex<ndim> &a, const Vertex<ndim> &b) const {
return carve::geom::distance(a.v, b.v);
}
template<unsigned ndim>
double operator()(const Vertex<ndim> *a, const Vertex<ndim> *b) const {
return carve::geom::distance(a->v, b->v);
}
};
namespace detail {
template<typename list_t> struct list_iter_t;
template<typename list_t, typename mapping_t> struct mapped_list_iter_t;
}
// The half-edge structure proper (Edge) is maintained by Face
// instances. Together with Face instances, the half-edge
// structure defines a simple mesh (either one or two faces
// incident on each edge).
template<unsigned ndim>
class Edge : public tagable {
public:
typedef Vertex<ndim> vertex_t;
typedef Face<ndim> face_t;
vertex_t *vert;
face_t *face;
Edge *prev, *next, *rev;
private:
static void _link(Edge *a, Edge *b) {
a->next = b; b->prev = a;
}
static void _freeloop(Edge *s) {
Edge *e = s;
do {
Edge *n = e->next;
delete e;
e = n;
} while (e != s);
}
static void _setloopface(Edge *s, face_t *f) {
Edge *e = s;
do {
e->face = f;
e = e->next;
} while (e != s);
}
static size_t _looplen(Edge *s) {
Edge *e = s;
face_t *f = s->face;
size_t c = 0;
do {
++c;
CARVE_ASSERT(e->rev->rev == e);
CARVE_ASSERT(e->next->prev == e);
CARVE_ASSERT(e->face == f);
e = e->next;
} while (e != s);
return c;
}
public:
void validateLoop() {
Edge *e = this;
face_t *f = face;
size_t c = 0;
do {
++c;
CARVE_ASSERT(e->rev == NULL || e->rev->rev == e);
CARVE_ASSERT(e->next == e || e->next->vert != e->vert);
CARVE_ASSERT(e->prev == e || e->prev->vert != e->vert);
CARVE_ASSERT(e->next->prev == e);
CARVE_ASSERT(e->prev->next == e);
CARVE_ASSERT(e->face == f);
e = e->next;
} while (e != this);
CARVE_ASSERT(f == NULL || c == f->n_edges);
}
size_t loopLen() {
return _looplen(this);
}
Edge *mergeFaces();
Edge *removeHalfEdge();
// Remove and delete this edge.
Edge *removeEdge();
// Unlink this edge from its containing edge loop. disconnect
// rev links. The rev links of the previous edge also change, as
// its successor vertex changes.
void unlink();
// Insert this edge into a loop before other. If edge was
// already in a loop, it needs to be removed first.
void insertBefore(Edge *other);
// Insert this edge into a loop after other. If edge was
// already in a loop, it needs to be removed first.
void insertAfter(Edge *other);
size_t loopSize() const;
vertex_t *v1() { return vert; }
vertex_t *v2() { return next->vert; }
const vertex_t *v1() const { return vert; }
const vertex_t *v2() const { return next->vert; }
Edge *perimNext() const;
Edge *perimPrev() const;
double length2() const {
return (v1()->v - v2()->v).length2();
}
double length() const {
return (v1()->v - v2()->v).length();
}
Edge(vertex_t *_vert, face_t *_face);
~Edge();
};
// A Face contains a pointer to the beginning of the half-edge
// circular list that defines its boundary.
template<unsigned ndim>
class Face : public tagable {
public:
typedef Vertex<ndim> vertex_t;
typedef Edge<ndim> edge_t;
typedef Mesh<ndim> mesh_t;
typedef typename Vertex<ndim>::vector_t vector_t;
typedef carve::geom::aabb<ndim> aabb_t;
typedef carve::geom::plane<ndim> plane_t;
typedef carve::geom::vector<2> (*project_t)(const vector_t &);
typedef vector_t (*unproject_t)(const carve::geom::vector<2> &, const plane_t &);
struct vector_mapping {
typedef typename vertex_t::vector_t value_type;
value_type operator()(const carve::geom::vector<ndim> &v) const { return v; }
value_type operator()(const carve::geom::vector<ndim> *v) const { return *v; }
value_type operator()(const Edge<ndim> &e) const { return e.vert->v; }
value_type operator()(const Edge<ndim> *e) const { return e->vert->v; }
value_type operator()(const Vertex<ndim> &v) const { return v.v; }
value_type operator()(const Vertex<ndim> *v) const { return v->v; }
};
struct projection_mapping {
typedef carve::geom::vector<2> value_type;
project_t proj;
projection_mapping(project_t _proj) : proj(_proj) { }
value_type operator()(const carve::geom::vector<ndim> &v) const { return proj(v); }
value_type operator()(const carve::geom::vector<ndim> *v) const { return proj(*v); }
value_type operator()(const Edge<ndim> &e) const { return proj(e.vert->v); }
value_type operator()(const Edge<ndim> *e) const { return proj(e->vert->v); }
value_type operator()(const Vertex<ndim> &v) const { return proj(v.v); }
value_type operator()(const Vertex<ndim> *v) const { return proj(v->v); }
};
edge_t *edge;
size_t n_edges;
mesh_t *mesh;
size_t id;
plane_t plane;
project_t project;
unproject_t unproject;
private:
Face &operator=(const Face &other);
protected:
Face() : edge(NULL), n_edges(0), mesh(NULL), id(0), plane(), project(NULL), unproject(NULL) {
}
Face(const Face &other) :
edge(NULL), n_edges(other.n_edges), mesh(NULL), id(other.id),
plane(other.plane), project(other.project), unproject(other.unproject) {
}
project_t getProjector(bool positive_facing, int axis) const;
unproject_t getUnprojector(bool positive_facing, int axis) const;
public:
typedef detail::list_iter_t<Edge<ndim> > edge_iter_t;
typedef detail::list_iter_t<const Edge<ndim> > const_edge_iter_t;
edge_iter_t begin() { return edge_iter_t(edge, 0); }
edge_iter_t end() { return edge_iter_t(edge, n_edges); }
const_edge_iter_t begin() const { return const_edge_iter_t(edge, 0); }
const_edge_iter_t end() const { return const_edge_iter_t(edge, n_edges); }
bool containsPoint(const vector_t &p) const;
bool containsPointInProjection(const vector_t &p) const;
bool simpleLineSegmentIntersection(
const carve::geom::linesegment<ndim> &line,
vector_t &intersection) const;
IntersectionClass lineSegmentIntersection(
const carve::geom::linesegment<ndim> &line,
vector_t &intersection) const;
aabb_t getAABB() const;
bool recalc();
void clearEdges();
// build an edge loop in forward orientation from an iterator pair
template<typename iter_t>
void loopFwd(iter_t vbegin, iter_t vend);
// build an edge loop in reverse orientation from an iterator pair
template<typename iter_t>
void loopRev(iter_t vbegin, iter_t vend);
// initialize a face from an ordered list of vertices.
template<typename iter_t>
void init(iter_t begin, iter_t end);
// initialization of a triangular face.
void init(vertex_t *a, vertex_t *b, vertex_t *c);
// initialization of a quad face.
void init(vertex_t *a, vertex_t *b, vertex_t *c, vertex_t *d);
void getVertices(std::vector<vertex_t *> &verts) const;
void getProjectedVertices(std::vector<carve::geom::vector<2> > &verts) const;
projection_mapping projector() const {
return projection_mapping(project);
}
std::pair<double, double> rangeInDirection(const vector_t &v, const vector_t &b) const {
edge_t *e = edge;
double lo, hi;
lo = hi = carve::geom::dot(v, e->vert->v - b);
e = e->next;
for (; e != edge; e = e->next) {
double d = carve::geom::dot(v, e->vert->v - b);
lo = std::min(lo, d);
hi = std::max(hi, d);
}
return std::make_pair(lo, hi);
}
size_t nVertices() const {
return n_edges;
}
size_t nEdges() const {
return n_edges;
}
vector_t centroid() const;
static Face *closeLoop(edge_t *open_edge);
Face(edge_t *e) : edge(e), n_edges(0), mesh(NULL) {
do {
e->face = this;
n_edges++;
e = e->next;
} while (e != edge);
recalc();
}
Face(vertex_t *a, vertex_t *b, vertex_t *c) : edge(NULL), n_edges(0), mesh(NULL) {
init(a, b, c);
recalc();
}
Face(vertex_t *a, vertex_t *b, vertex_t *c, vertex_t *d) : edge(NULL), n_edges(0), mesh(NULL) {
init(a, b, c, d);
recalc();
}
template<typename iter_t>
Face(iter_t begin, iter_t end) : edge(NULL), n_edges(0), mesh(NULL) {
init(begin, end);
recalc();
}
template<typename iter_t>
Face *create(iter_t beg, iter_t end, bool reversed) const;
Face *clone(const vertex_t *old_base, vertex_t *new_base, std::unordered_map<const edge_t *, edge_t *> &edge_map) const;
void remove() {
edge_t *e = edge;
do {
if (e->rev) e->rev->rev = NULL;
e = e->next;
} while (e != edge);
}
void invert() {
// We invert the direction of the edges of the face in this
// way so that the edge rev pointers (if any) are still
// correct. It is expected that invert() will be called on
// every other face in the mesh, too, otherwise everything
// will get messed up.
{
// advance vertices.
edge_t *e = edge;
vertex_t *va = e->vert;
do {
e->vert = e->next->vert;
e = e->next;
} while (e != edge);
edge->prev->vert = va;
}
{
// swap prev and next pointers.
edge_t *e = edge;
do {
edge_t *n = e->next;
std::swap(e->prev, e->next);
e = n;
} while (e != edge);
}
plane.negate();
int da = carve::geom::largestAxis(plane.N);
project = getProjector(plane.N.v[da] > 0, da);
unproject = getUnprojector(plane.N.v[da] > 0, da);
}
void canonicalize();
~Face() {
clearEdges();
}
};
struct MeshOptions {
bool opt_avoid_cavities;
MeshOptions() :
opt_avoid_cavities(false) {
}
MeshOptions &avoid_cavities(bool val) {
opt_avoid_cavities = val;
return *this;
}
};
namespace detail {
class FaceStitcher {
FaceStitcher();
FaceStitcher(const FaceStitcher &);
FaceStitcher &operator=(const FaceStitcher &);
typedef Vertex<3> vertex_t;
typedef Edge<3> edge_t;
typedef Face<3> face_t;
typedef std::pair<const vertex_t *, const vertex_t *> vpair_t;
typedef std::list<edge_t *> edgelist_t;
typedef std::unordered_map<vpair_t, edgelist_t, carve::mesh::hash_vertex_pair> edge_map_t;
typedef std::unordered_map<const vertex_t *, std::set<const vertex_t *> > edge_graph_t;
MeshOptions opts;
edge_map_t edges;
edge_map_t complex_edges;
carve::djset::djset face_groups;
std::vector<bool> is_open;
edge_graph_t edge_graph;
struct EdgeOrderData {
size_t group_id;
bool is_reversed;
carve::geom::vector<3> face_dir;
edge_t *edge;
EdgeOrderData(edge_t *_edge, size_t _group_id, bool _is_reversed) :
group_id(_group_id),
is_reversed(_is_reversed) {
if (is_reversed) {
face_dir = -(_edge->face->plane.N);
} else {
face_dir = (_edge->face->plane.N);
}
edge = _edge;
}
struct TestGroups {
size_t fwd, rev;
TestGroups(size_t _fwd, size_t _rev) : fwd(_fwd), rev(_rev) {
}
bool operator()(const EdgeOrderData &eo) const {
return eo.group_id == (eo.is_reversed ? rev : fwd);
}
};
struct Cmp {
carve::geom::vector<3> edge_dir;
carve::geom::vector<3> base_dir;
Cmp(const carve::geom::vector<3> &_edge_dir,
const carve::geom::vector<3> &_base_dir) :
edge_dir(_edge_dir),
base_dir(_base_dir) {
}
bool operator()(const EdgeOrderData &a, const EdgeOrderData &b) const;
};
};
void extractConnectedEdges(std::vector<const vertex_t *>::iterator begin,
std::vector<const vertex_t *>::iterator end,
std::vector<std::vector<Edge<3> *> > &efwd,
std::vector<std::vector<Edge<3> *> > &erev);
size_t faceGroupID(const Face<3> *face);
size_t faceGroupID(const Edge<3> *edge);
void resolveOpenEdges();
void fuseEdges(std::vector<Edge<3> *> &fwd,
std::vector<Edge<3> *> &rev);
void joinGroups(std::vector<std::vector<Edge<3> *> > &efwd,
std::vector<std::vector<Edge<3> *> > &erev,
size_t fwd_grp,
size_t rev_grp);
void matchOrderedEdges(const std::vector<std::vector<EdgeOrderData> >::iterator begin,
const std::vector<std::vector<EdgeOrderData> >::iterator end,
std::vector<std::vector<Edge<3> *> > &efwd,
std::vector<std::vector<Edge<3> *> > &erev);
void reorder(std::vector<EdgeOrderData> &ordering, size_t fwd_grp);
void orderForwardAndReverseEdges(std::vector<std::vector<Edge<3> *> > &efwd,
std::vector<std::vector<Edge<3> *> > &erev,
std::vector<std::vector<EdgeOrderData> > &result);
void edgeIncidentGroups(const vpair_t &e,
const edge_map_t &all_edges,
std::pair<std::set<size_t>, std::set<size_t> > &groups);
void buildEdgeGraph(const edge_map_t &all_edges);
void extractPath(std::vector<const vertex_t *> &path);
void removePath(const std::vector<const vertex_t *> &path);
void matchSimpleEdges();
void construct();
template<typename iter_t>
void initEdges(iter_t begin, iter_t end);
template<typename iter_t>
void build(iter_t begin, iter_t end, std::vector<Mesh<3> *> &meshes);
public:
FaceStitcher(const MeshOptions &_opts);
template<typename iter_t>
void create(iter_t begin, iter_t end, std::vector<Mesh<3> *> &meshes);
};
}
// A Mesh is a connected set of faces. It may be open (some edges
// have NULL rev members), or closed. On destruction, a Mesh
// should free its Faces (which will in turn free Edges, but not
// Vertices). A Mesh is edge-connected, which is to say that each
// face in the mesh shares an edge with at least one other face in
// the mesh. Touching at a vertex is not sufficient. This means
// that the perimeter of an open mesh visits each vertex no more
// than once.
template<unsigned ndim>
class Mesh {
public:
typedef Vertex<ndim> vertex_t;
typedef Edge<ndim> edge_t;
typedef Face<ndim> face_t;
typedef carve::geom::aabb<ndim> aabb_t;
typedef MeshSet<ndim> meshset_t;
std::vector<face_t *> faces;
// open_edges is a vector of all the edges in the mesh that
// don't have a matching edge in the opposite direction.
std::vector<edge_t *> open_edges;
// closed_edges is a vector of all the edges in the mesh that
// have a matching edge in the opposite direction, and whose
// address is lower than their counterpart. (i.e. for each pair
// of adjoining faces, one of the two half edges is stored in
// closed_edges).
std::vector<edge_t *> closed_edges;
bool is_negative;
meshset_t *meshset;
protected:
Mesh(std::vector<face_t *> &_faces,
std::vector<edge_t *> &_open_edges,
std::vector<edge_t *> &_closed_edges,
bool _is_negative);
public:
Mesh(std::vector<face_t *> &_faces);
~Mesh();
template<typename iter_t>
static void create(iter_t begin, iter_t end, std::vector<Mesh<ndim> *> &meshes, const MeshOptions &opts);
aabb_t getAABB() const {
return aabb_t(faces.begin(), faces.end());
}
bool isClosed() const {
return open_edges.size() == 0;
}
bool isNegative() const {
return is_negative;
}
double volume() const {
if (is_negative || !faces.size()) return 0.0;
double vol = 0.0;
typename vertex_t::vector_t origin = faces[0]->edge->vert->v;
for (size_t f = 0; f < faces.size(); ++f) {
face_t *face = faces[f];
edge_t *e1 = face->edge;
for (edge_t *e2 = e1->next ;e2->next != e1; e2 = e2->next) {
vol += carve::geom3d::tetrahedronVolume(e1->vert->v, e2->vert->v, e2->next->vert->v, origin);
}
}
return vol;
}
struct IsClosed {
bool operator()(const Mesh &mesh) const { return mesh.isClosed(); }
bool operator()(const Mesh *mesh) const { return mesh->isClosed(); }
};
struct IsNegative {
bool operator()(const Mesh &mesh) const { return mesh.isNegative(); }
bool operator()(const Mesh *mesh) const { return mesh->isNegative(); }
};
void cacheEdges();
int orientationAtVertex(edge_t *);
void calcOrientation();
void recalc() {
for (size_t i = 0; i < faces.size(); ++i) faces[i]->recalc();
calcOrientation();
}
void invert() {
for (size_t i = 0; i < faces.size(); ++i) {
faces[i]->invert();
}
if (isClosed()) is_negative = !is_negative;
}
Mesh *clone(const vertex_t *old_base, vertex_t *new_base) const;
};
// A MeshSet manages vertex storage, and a collection of meshes.
// It should be easy to turn a vertex pointer into its index in
// its MeshSet vertex_storage.
template<unsigned ndim>
class MeshSet {
MeshSet();
MeshSet(const MeshSet &);
MeshSet &operator=(const MeshSet &);
template<typename iter_t>
void _init_from_faces(iter_t begin, iter_t end, const MeshOptions &opts);
public:
typedef Vertex<ndim> vertex_t;
typedef Edge<ndim> edge_t;
typedef Face<ndim> face_t;
typedef Mesh<ndim> mesh_t;
typedef carve::geom::aabb<ndim> aabb_t;
std::vector<vertex_t> vertex_storage;
std::vector<mesh_t *> meshes;
public:
template<typename face_type>
struct FaceIter : public std::iterator<std::random_access_iterator_tag, face_type> {
typedef std::iterator<std::random_access_iterator_tag, face_type> super;
typedef typename super::difference_type difference_type;
const MeshSet<ndim> *obj;
size_t mesh, face;
FaceIter(const MeshSet<ndim> *_obj, size_t _mesh, size_t _face);
void fwd(size_t n);
void rev(size_t n);
void adv(int n);
FaceIter operator++(int) { FaceIter tmp = *this; tmp.fwd(1); return tmp; }
FaceIter operator+(int v) { FaceIter tmp = *this; tmp.adv(v); return tmp; }
FaceIter &operator++() { fwd(1); return *this; }
FaceIter &operator+=(int v) { adv(v); return *this; }
FaceIter operator--(int) { FaceIter tmp = *this; tmp.rev(1); return tmp; }
FaceIter operator-(int v) { FaceIter tmp = *this; tmp.adv(-v); return tmp; }
FaceIter &operator--() { rev(1); return *this; }
FaceIter &operator-=(int v) { adv(-v); return *this; }
difference_type operator-(const FaceIter &other) const;
bool operator==(const FaceIter &other) const {
return obj == other.obj && mesh == other.mesh && face == other.face;
}
bool operator!=(const FaceIter &other) const {
return !(*this == other);
}
bool operator<(const FaceIter &other) const {
CARVE_ASSERT(obj == other.obj);
return mesh < other.mesh || (mesh == other.mesh && face < other.face);
}
bool operator>(const FaceIter &other) const {
return other < *this;
}
bool operator<=(const FaceIter &other) const {
return !(other < *this);
}
bool operator>=(const FaceIter &other) const {
return !(*this < other);
}
face_type operator*() const {
return obj->meshes[mesh]->faces[face];
}
};
typedef FaceIter<const face_t *> const_face_iter;
typedef FaceIter<face_t *> face_iter;
face_iter faceBegin() { return face_iter(this, 0, 0); }
face_iter faceEnd() { return face_iter(this, meshes.size(), 0); }
const_face_iter faceBegin() const { return const_face_iter(this, 0, 0); }
const_face_iter faceEnd() const { return const_face_iter(this, meshes.size(), 0); }
aabb_t getAABB() const {
return aabb_t(meshes.begin(), meshes.end());
}
template<typename func_t>
void transform(func_t func) {
for (size_t i = 0; i < vertex_storage.size(); ++i) {
vertex_storage[i].v = func(vertex_storage[i].v);
}
for (size_t i = 0; i < meshes.size(); ++i) {
meshes[i]->recalc();
}
}
MeshSet(const std::vector<typename vertex_t::vector_t> &points,
size_t n_faces,
const std::vector<int> &face_indices,
const MeshOptions &opts = MeshOptions());
// Construct a mesh set from a set of disconnected faces. Takes
// posession of the face pointers.
MeshSet(std::vector<face_t *> &faces,
const MeshOptions &opts = MeshOptions());
MeshSet(std::list<face_t *> &faces,
const MeshOptions &opts = MeshOptions());
MeshSet(std::vector<vertex_t> &_vertex_storage,
std::vector<mesh_t *> &_meshes);
// This constructor consolidates and rewrites vertex pointers in
// each mesh, repointing them to local storage.
MeshSet(std::vector<mesh_t *> &_meshes);
MeshSet *clone() const;
~MeshSet();
bool isClosed() const {
for (size_t i = 0; i < meshes.size(); ++i) {
if (!meshes[i]->isClosed()) return false;
}
return true;
}
void invert() {
for (size_t i = 0; i < meshes.size(); ++i) {
meshes[i]->invert();
}
}
void collectVertices();
void canonicalize();
void separateMeshes();
};
carve::PointClass classifyPoint(
const carve::mesh::MeshSet<3> *meshset,
const carve::geom::RTreeNode<3, carve::mesh::Face<3> *> *face_rtree,
const carve::geom::vector<3> &v,
bool even_odd = false,
const carve::mesh::Mesh<3> *mesh = NULL,
const carve::mesh::Face<3> **hit_face = NULL);
}
mesh::MeshSet<3> *meshFromPolyhedron(const poly::Polyhedron *, int manifold_id);
poly::Polyhedron *polyhedronFromMesh(const mesh::MeshSet<3> *, int manifold_id);
};
#include <carve/mesh_impl.hpp>

1098
extern/carve/include/carve/mesh_impl.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

975
extern/carve/include/carve/mesh_ops.hpp vendored Normal file
View File

@@ -0,0 +1,975 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/mesh.hpp>
#include <iostream>
#include <fstream>
namespace carve {
namespace mesh {
namespace detail {
// make a triangle out of three edges.
template<unsigned ndim>
void link(Edge<ndim> *e1, Edge<ndim> *e2, Edge<ndim> *e3, Face<ndim> *f = NULL) {
e1->next = e2; e2->next = e3; e3->next = e1;
e3->prev = e2; e2->prev = e1; e1->prev = e3;
e1->face = e2->face = e3->face = f;
if (f) {
f->edge = e1;
f->recalc();
}
}
template<unsigned ndim, typename proj_t>
double loopArea(carve::mesh::Edge<ndim> *edge, proj_t proj) {
double A = 0.0;
carve::mesh::Edge<3> *e = edge;
do {
carve::geom2d::P2 p1 = proj(e->vert->v);
carve::geom2d::P2 p2 = proj(e->next->vert->v);
A += (p2.y + p1.y) * (p2.x - p1.x);
e = e->next;
} while (e != edge);
return A / 2.0;
}
template<unsigned ndim, typename proj_t>
struct TriangulationData {
typedef Edge<ndim> edge_t;
struct VertexInfo {
double score;
carve::geom2d::P2 p;
bool convex;
bool failed;
VertexInfo *next, *prev;
edge_t *edge;
VertexInfo(edge_t *_edge,
const carve::geom2d::P2 &_p) :
score(0.0), p(_p), convex(false), failed(false), next(NULL), prev(NULL), edge(_edge) {
}
bool isCandidate() const {
return convex && !failed;
}
void fail() {
failed = true;
}
static bool isLeft(const VertexInfo *a, const VertexInfo *b, const geom2d::P2 &p) {
if (a < b) {
return carve::geom2d::orient2d(a->p, b->p, p) > 0.0;
} else {
return carve::geom2d::orient2d(b->p, a->p, p) < 0.0;
}
}
// is the ear prev->edge->next convex?
bool testForConvexVertex() const {
return isLeft(next, prev, p);
}
static double triScore(const geom2d::P2 &a, const geom2d::P2 &b, const geom2d::P2 &c) {
// score is in the range: [0, 1]
// equilateral triangles score 1
// sliver triangles score 0
double dab = (a - b).length();
double dbc = (b - c).length();
double dca = (c - a).length();
if (dab < 1e-10 || dbc < 1e-10 || dca < 1e-10) return 0.0;
return std::max(std::min((dab + dbc) / dca, std::min((dab + dca) / dbc, (dbc + dca) / dab)) - 1.0, 0.0);
}
// calculate a score for the ear edge.
double calcScore() const {
double this_tri = triScore(prev->p, p, next->p);
double next_tri = triScore(prev->p, next->p, next->next->p);
double prev_tri = triScore(prev->prev->p, prev->p, next->p);
return this_tri + std::max(next_tri, prev_tri) * .2;
}
void recompute() {
convex = testForConvexVertex();
failed = false;
if (convex) {
score = calcScore();
} else {
score = -1e-5;
}
}
static bool inTriangle(const VertexInfo *a,
const VertexInfo *b,
const VertexInfo *c,
const geom2d::P2 &e) {
return !isLeft(b, a, e) && !isLeft(c, b, e) && !isLeft(a, c, e);
}
bool isClipable() const {
for (const VertexInfo *v_test = next->next; v_test != prev; v_test = v_test->next) {
if (v_test->convex) {
continue;
}
if (v_test->p == prev->p || v_test->p == next->p) {
continue;
}
if (v_test->p == p) {
if (v_test->next->p == prev->p && v_test->prev->p == next->p) {
return false;
}
if (v_test->next->p == prev->p || v_test->prev->p == next->p) {
continue;
}
}
if (inTriangle(prev, this, next, v_test->p)) {
return false;
}
}
return true;
}
};
struct order_by_score {
bool operator()(const VertexInfo *a, const VertexInfo *b) const {
return a->score < b->score;
}
};
typedef std::pair<VertexInfo *, VertexInfo *> diag_t;
proj_t proj;
geom2d::P2 P(const VertexInfo *vi) const {
return vi->p;
}
geom2d::P2 P(const edge_t *edge) const {
return proj(edge->vert->v);
}
bool isLeft(const edge_t *a, const edge_t *b, const geom2d::P2 &p) const {
if (a < b) {
return carve::geom2d::orient2d(P(a), P(b), p) > 0.0;
} else {
return carve::geom2d::orient2d(P(b), P(a), p) < 0.0;
}
}
bool testForConvexVertex(const edge_t *vert) const {
return isLeft(vert->next, vert->prev, P(vert));
}
bool inCone(const VertexInfo *vert, const geom2d::P2 &p) const {
return geom2d::internalToAngle(P(vert->next), P(vert), P(vert->prev), p);
}
int windingNumber(VertexInfo *vert, const carve::geom2d::P2 &point) const {
int wn = 0;
VertexInfo *v = vert;
geom2d::P2 v_p = P(vert);
do {
geom2d::P2 n_p = P(v->next);
if (v_p.y <= point.y) {
if (n_p.y > point.y && carve::geom2d::orient2d(v_p, n_p, point) > 0.0) {
++wn;
}
} else {
if (n_p.y <= point.y && carve::geom2d::orient2d(v_p, n_p, point) < 0.0) {
--wn;
}
}
v = v->next;
v_p = n_p;
} while (v != vert);
return wn;
}
bool diagonalIsCandidate(diag_t diag) const {
VertexInfo *v1 = diag.first;
VertexInfo *v2 = diag.second;
return (inCone(v1, P(v2)) && inCone(v2, P(v1)));
}
bool testDiagonal(diag_t diag) const {
// test whether v1-v2 is a valid diagonal.
VertexInfo *v1 = diag.first;
VertexInfo *v2 = diag.second;
geom2d::P2 v1p = P(v1);
geom2d::P2 v2p = P(v2);
bool intersected = false;
for (VertexInfo *t = v1->next; !intersected && t != v1->prev; t = t->next) {
VertexInfo *u = t->next;
if (t == v2 || u == v2) continue;
geom2d::P2 tp = P(t);
geom2d::P2 up = P(u);
double l_a1 = carve::geom2d::orient2d(v1p, v2p, tp);
double l_a2 = carve::geom2d::orient2d(v1p, v2p, up);
double l_b1 = carve::geom2d::orient2d(tp, up, v1p);
double l_b2 = carve::geom2d::orient2d(tp, up, v2p);
if (l_a1 > l_a2) std::swap(l_a1, l_a2);
if (l_b1 > l_b2) std::swap(l_b1, l_b2);
if (l_a1 == 0.0 && l_a2 == 0.0 &&
l_b1 == 0.0 && l_b2 == 0.0) {
// colinear
if (std::max(tp.x, up.x) >= std::min(v1p.x, v2p.x) && std::min(tp.x, up.x) <= std::max(v1p.x, v2p.x)) {
// colinear and intersecting
intersected = true;
}
continue;
}
if (l_a2 <= 0.0 || l_a1 >= 0.0 || l_b2 <= 0.0 || l_b1 >= 0.0) {
// no intersection
continue;
}
intersected = true;
}
if (!intersected) {
// test whether midpoint winding == 1
carve::geom2d::P2 mid = (v1p + v2p) / 2;
if (windingNumber(v1, mid) == 1) {
// this diagonal is ok
return true;
}
}
return false;
}
// Find the vertex half way around the loop (rounds upwards).
VertexInfo *findMidpoint(VertexInfo *vert) const {
VertexInfo *v = vert;
VertexInfo *r = vert;
while (1) {
r = r->next;
v = v->next; if (v == vert) return r;
v = v->next; if (v == vert) return r;
}
}
// Test all diagonals with a separation of a-b by walking both
// pointers around the loop. In the case where a-b divides the
// loop exactly in half, this will test each diagonal twice,
// but avoiding this case is not worth the extra effort
// required.
diag_t scanDiagonals(VertexInfo *a, VertexInfo *b) const {
VertexInfo *v1 = a;
VertexInfo *v2 = b;
do {
diag_t d(v1, v2);
if (diagonalIsCandidate(d) && testDiagonal(d)) {
return d;
}
v1 = v1->next;
v2 = v2->next;
} while (v1 != a);
return diag_t(NULL, NULL);
}
diag_t scanAllDiagonals(VertexInfo *a) const {
// Rationale: We want to find a diagonal that splits the
// loop into two as evenly as possible, to reduce the number
// of times that diagonal splitting is required. Start by
// scanning all diagonals separated by loop_len / 2, then
// decrease the separation until we find something.
// loops of length 2 or 3 have no possible diagonal.
if (a->next == a || a->next->next == a) return diag_t(NULL, NULL);
VertexInfo *b = findMidpoint(a);
while (b != a->next) {
diag_t d = scanDiagonals(a, b);
if (d != diag_t(NULL, NULL)) return d;
b = b->prev;
}
return diag_t(NULL, NULL);
}
diag_t findDiagonal(VertexInfo *vert) const {
return scanAllDiagonals(vert);
}
diag_t findHighScoringDiagonal(VertexInfo *vert) const {
typedef std::pair<double, diag_t> heap_entry_t;
VertexInfo *v1, *v2;
std::vector<heap_entry_t> heap;
size_t loop_len = 0;
v1 = vert;
do {
++loop_len;
v1 = v1->next;
} while (v1 != vert);
v1 = vert;
do {
v2 = v1->next->next;
size_t dist = 2;
do {
if (diagonalIsCandidate(diag_t(v1, v2))) {
double score = std::min(dist, loop_len - dist);
// double score = (v1->edge->vert->v - v2->edge->vert->v).length2();
heap.push_back(heap_entry_t(score, diag_t(v1, v2)));
}
v2 = v2->next;
++dist;
} while (v2 != vert && v2 != v1->prev);
v1 = v1->next;
} while (v1->next->next != vert);
std::make_heap(heap.begin(), heap.end());
while (heap.size()) {
std::pop_heap(heap.begin(), heap.end());
heap_entry_t h = heap.back();
heap.pop_back();
if (testDiagonal(h.second)) return h.second;
}
// couldn't find a diagonal that was ok.
return diag_t(NULL, NULL);
}
void splitEdgeLoop(VertexInfo *v1, VertexInfo *v2) {
VertexInfo *v1_copy = new VertexInfo(new Edge<ndim>(v1->edge->vert, NULL), v1->p);
VertexInfo *v2_copy = new VertexInfo(new Edge<ndim>(v2->edge->vert, NULL), v2->p);
v1_copy->edge->rev = v2_copy->edge;
v2_copy->edge->rev = v1_copy->edge;
v1_copy->edge->prev = v1->edge->prev;
v1_copy->edge->next = v2->edge;
v2_copy->edge->prev = v2->edge->prev;
v2_copy->edge->next = v1->edge;
v1->edge->prev->next = v1_copy->edge;
v1->edge->prev = v2_copy->edge;
v2->edge->prev->next = v2_copy->edge;
v2->edge->prev = v1_copy->edge;
v1_copy->prev = v1->prev;
v1_copy->next = v2;
v2_copy->prev = v2->prev;
v2_copy->next = v1;
v1->prev->next = v1_copy;
v1->prev = v2_copy;
v2->prev->next = v2_copy;
v2->prev = v1_copy;
}
VertexInfo *findDegenerateEar(VertexInfo *edge) {
VertexInfo *v = edge;
if (v->next == v || v->next->next == v) return NULL;
do {
if (P(v) == P(v->next)) {
return v;
} else if (P(v) == P(v->next->next)) {
if (P(v->next) == P(v->next->next->next)) {
// a 'z' in the loop: z (a) b a b c -> remove a-b-a -> z (a) a b c -> remove a-a-b (next loop) -> z a b c
// z --(a)-- b
// /
// /
// a -- b -- d
return v->next;
} else {
// a 'shard' in the loop: z (a) b a c d -> remove a-b-a -> z (a) a b c d -> remove a-a-b (next loop) -> z a b c d
// z --(a)-- b
// /
// /
// a -- c -- d
// n.b. can only do this if the shard is pointing out of the polygon. i.e. b is outside z-a-c
if (!carve::geom2d::internalToAngle(P(v->next->next->next), P(v), P(v->prev), P(v->next))) {
return v->next;
}
}
}
v = v->next;
} while (v != edge);
return NULL;
}
// Clip off a vertex at vert, producing a triangle (with appropriate rev pointers)
template<typename out_iter_t>
VertexInfo *clipEar(VertexInfo *vert, out_iter_t out) {
CARVE_ASSERT(testForConvexVertex(vert->edge));
edge_t *p_edge = vert->edge->prev;
edge_t *n_edge = vert->edge->next;
edge_t *p_copy = new edge_t(p_edge->vert, NULL);
edge_t *n_copy = new edge_t(n_edge->vert, NULL);
n_copy->next = p_copy;
n_copy->prev = vert->edge;
p_copy->next = vert->edge;
p_copy->prev = n_copy;
vert->edge->next = n_copy;
vert->edge->prev = p_copy;
p_edge->next = n_edge;
n_edge->prev = p_edge;
if (p_edge->rev) {
p_edge->rev->rev = p_copy;
}
p_copy->rev = p_edge->rev;
p_edge->rev = n_copy;
n_copy->rev = p_edge;
*out++ = vert->edge;
if (vert->edge->face) {
if (vert->edge->face->edge == vert->edge) {
vert->edge->face->edge = n_edge;
}
vert->edge->face->n_edges--;
vert->edge->face = NULL;
}
vert->next->prev = vert->prev;
vert->prev->next = vert->next;
VertexInfo *n = vert->next;
delete vert;
return n;
}
template<typename out_iter_t>
size_t removeDegeneracies(VertexInfo *&begin, out_iter_t out) {
VertexInfo *v;
size_t count = 0;
while ((v = findDegenerateEar(begin)) != NULL) {
begin = clipEar(v, out);
++count;
}
return count;
}
template<typename out_iter_t>
bool splitAndResume(VertexInfo *begin, out_iter_t out) {
diag_t diag;
diag = findDiagonal(begin);
if (diag == diag_t(NULL, NULL)) {
std::cerr << "failed to find diagonal" << std::endl;
return false;
}
// add a splitting edge between v1 and v2.
VertexInfo *v1 = diag.first;
VertexInfo *v2 = diag.second;
splitEdgeLoop(v1, v2);
v1->recompute();
v1->next->recompute();
v2->recompute();
v2->next->recompute();
#if defined(CARVE_DEBUG)
dumpPoly(v1->edge, v2->edge);
#endif
#if defined(CARVE_DEBUG)
CARVE_ASSERT(!checkSelfIntersection(v1));
CARVE_ASSERT(!checkSelfIntersection(v2));
#endif
bool r1 = doTriangulate(v1, out);
bool r2 = doTriangulate(v2, out);
return r1 && r2;
}
template<typename out_iter_t>
bool doTriangulate(VertexInfo *begin, out_iter_t out);
TriangulationData(proj_t _proj) : proj(_proj) {
}
VertexInfo *init(edge_t *begin) {
edge_t *e = begin;
VertexInfo *head = NULL, *tail = NULL, *v;
do {
VertexInfo *v = new VertexInfo(e, proj(e->vert->v));
if (tail != NULL) {
tail->next = v;
v->prev = tail;
} else {
head = v;
}
tail = v;
e = e->next;
} while (e != begin);
tail->next = head;
head->prev = tail;
v = head;
do {
v->recompute();
v = v->next;
} while (v != head);
return head;
}
class EarQueue {
TriangulationData &data;
std::vector<VertexInfo *> queue;
void checkheap() {
#if defined(HAVE_IS_HEAP)
CARVE_ASSERT(std::__is_heap(queue.begin(), queue.end(), order_by_score()));
#endif
}
public:
EarQueue(TriangulationData &_data) : data(_data), queue() {
}
size_t size() const {
return queue.size();
}
void push(VertexInfo *v) {
#if defined(CARVE_DEBUG)
checkheap();
#endif
queue.push_back(v);
std::push_heap(queue.begin(), queue.end(), order_by_score());
}
VertexInfo *pop() {
#if defined(CARVE_DEBUG)
checkheap();
#endif
std::pop_heap(queue.begin(), queue.end(), order_by_score());
VertexInfo *v = queue.back();
queue.pop_back();
return v;
}
void remove(VertexInfo *v) {
#if defined(CARVE_DEBUG)
checkheap();
#endif
CARVE_ASSERT(std::find(queue.begin(), queue.end(), v) != queue.end());
double score = v->score;
if (v != queue[0]) {
v->score = queue[0]->score + 1;
std::make_heap(queue.begin(), queue.end(), order_by_score());
}
CARVE_ASSERT(v == queue[0]);
std::pop_heap(queue.begin(), queue.end(), order_by_score());
CARVE_ASSERT(queue.back() == v);
queue.pop_back();
v->score = score;
}
void changeScore(VertexInfo *v, double s_from, double s_to) {
#if defined(CARVE_DEBUG)
checkheap();
#endif
CARVE_ASSERT(std::find(queue.begin(), queue.end(), v) != queue.end());
if (s_from != s_to) {
v->score = s_to;
std::make_heap(queue.begin(), queue.end(), order_by_score());
}
}
void update(VertexInfo *v) {
VertexInfo pre = *v;
v->recompute();
VertexInfo post = *v;
if (pre.isCandidate()) {
if (post.isCandidate()) {
changeScore(v, pre.score, post.score);
} else {
remove(v);
}
} else {
if (post.isCandidate()) {
push(v);
}
}
}
};
bool checkSelfIntersection(const VertexInfo *vert) {
const VertexInfo *v1 = vert;
do {
const VertexInfo *v2 = vert->next->next;
do {
carve::geom2d::P2 a = v1->p;
carve::geom2d::P2 b = v1->next->p;
CARVE_ASSERT(a == proj(v1->edge->vert->v));
CARVE_ASSERT(b == proj(v1->edge->next->vert->v));
carve::geom2d::P2 c = v2->p;
carve::geom2d::P2 d = v2->next->p;
CARVE_ASSERT(c == proj(v2->edge->vert->v));
CARVE_ASSERT(d == proj(v2->edge->next->vert->v));
bool intersected = false;
if (a == c || a == d || b == c || b == d) {
} else {
intersected = true;
double l_a1 = carve::geom2d::orient2d(a, b, c);
double l_a2 = carve::geom2d::orient2d(a, b, d);
if (l_a1 > l_a2) std::swap(l_a1, l_a2);
if (l_a2 <= 0.0 || l_a1 >= 0.0) {
intersected = false;
}
double l_b1 = carve::geom2d::orient2d(c, d, a);
double l_b2 = carve::geom2d::orient2d(c, d, b);
if (l_b1 > l_b2) std::swap(l_b1, l_b2);
if (l_b2 <= 0.0 || l_b1 >= 0.0) {
intersected = false;
}
if (l_a1 == 0.0 && l_a2 == 0.0 && l_b1 == 0.0 && l_b2 == 0.0) {
if (std::max(a.x, b.x) >= std::min(c.x, d.x) && std::min(a.x, b.x) <= std::max(c.x, d.x)) {
// colinear and intersecting.
} else {
// colinear but not intersecting.
intersected = false;
}
}
}
if (intersected) {
carve::geom2d::P2 p[4] = { a, b, c, d };
carve::geom::aabb<2> A(p, p+4);
A.expand(5);
std::cerr << "\
<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\
<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n\
<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n\
x=\"" << A.min().x << "px\" y=\"" << A.min().y << "\"\n\
width=\"" << A.extent.x * 2 << "\" height=\"" << A.extent.y * 2 << "\"\n\
viewBox=\"" << A.min().x << " " << A.min().y << " " << A.max().x << " " << A.max().y << "\"\n\
enable-background=\"new " << A.min().x << " " << A.min().y << " " << A.max().x << " " << A.max().y << "\"\n\
xml:space=\"preserve\">\n\
<line fill=\"none\" stroke=\"#000000\" x1=\"" << a.x << "\" y1=\"" << a.y << "\" x2=\"" << b.x << "\" y2=\"" << b.y << "\"/>\n\
<line fill=\"none\" stroke=\"#000000\" x1=\"" << c.x << "\" y1=\"" << c.y << "\" x2=\"" << d.x << "\" y2=\"" << d.y << "\"/>\n\
</svg>\n";
return true;
}
v2 = v2->next;
} while (v2 != vert);
v1 = v1->next;
} while (v1 != vert);
return false;
}
carve::geom::aabb<2> make2d(const edge_t *edge, std::vector<geom2d::P2> &points) {
const edge_t *e = edge;
do {
points.push_back(P(e));
e = e->next;
} while(e != edge);
return carve::geom::aabb<2>(points.begin(), points.end());
}
void dumpLoop(std::ostream &out,
const std::vector<carve::geom2d::P2> &points,
const char *fill,
const char *stroke,
double stroke_width,
double offx,
double offy,
double scale
) {
out << "<polygon fill=\"" << fill << "\" stroke=\"" << stroke << "\" stroke-width=\"" << stroke_width << "\" points=\"";
for (size_t i = 0; i < points.size(); ++i) {
if (i) out << ' ';
double x, y;
x = scale * (points[i].x - offx) + 5;
y = scale * (points[i].y - offy) + 5;
out << x << ',' << y;
}
out << "\" />" << std::endl;
}
void dumpPoly(const edge_t *edge, const edge_t *edge2 = NULL, const char *pfx = "poly_") {
static int step = 0;
std::ostringstream filename;
filename << pfx << step++ << ".svg";
std::cerr << "dumping to " << filename.str() << std::endl;
std::ofstream out(filename.str().c_str());
std::vector <geom2d::P2> points, points2;
carve::geom::aabb<2> A = make2d(edge, points);
if (edge2) {
A.unionAABB(make2d(edge2, points2));
}
A.expand(5);
out << "\
<?xml version=\"1.0\"?>\n\
<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n\
<svg\n\
x=\"" << A.min().x << "px\" y=\"" << A.min().y << "\"\n\
width=\"" << A.extent.x * 2 << "\" height=\"" << A.extent.y * 2 << "\"\n\
viewBox=\"" << A.min().x << " " << A.min().y << " " << A.max().x << " " << A.max().y << "\"\n\
enable-background=\"new " << A.min().x << " " << A.min().y << " " << A.max().x << " " << A.max().y << "\"\n\
xml:space=\"preserve\">\n";
dumpLoop(out, points, "rgb(0,0,0)", "blue", 0.1, 0, 0, 1);
if (points2.size()) dumpLoop(out, points2, "rgb(255,0,0)", "blue", 0.1, 0, 0, 1);
out << "</svg>" << std::endl;
}
};
template<unsigned ndim, typename proj_t>
template<typename out_iter_t>
bool TriangulationData<ndim, proj_t>::doTriangulate(VertexInfo *begin, out_iter_t out) {
EarQueue vq(*this);
#if defined(CARVE_DEBUG)
dumpPoly(begin->edge, NULL, "input_");
CARVE_ASSERT(!checkSelfIntersection(begin));
#endif
VertexInfo *v = begin, *n, *p;
size_t remain = 0;
do {
if (v->isCandidate()) vq.push(v);
v = v->next;
remain++;
} while (v != begin);
while (remain > 3 && vq.size()) {
{ static int __c = 0; if (++__c % 50 == 0) { break; } }
v = vq.pop();
if (!v->isClipable()) {
v->fail();
continue;
}
continue_clipping:
n = clipEar(v, out);
p = n->prev;
begin = n;
if (--remain == 3) break;
// if (checkSelfIntersection(begin)) {
// dumpPoly(begin->edge, NULL, "badclip_");
// CARVE_ASSERT(!!!"clip created self intersection");
// }
vq.update(n);
vq.update(p);
if (n->score < p->score) { std::swap(n, p); }
if (n->score > 0.25 && n->isCandidate() && n->isClipable()) {
vq.remove(n);
v = n;
goto continue_clipping;
}
if (p->score > 0.25 && p->isCandidate() && p->isClipable()) {
vq.remove(p);
v = p;
goto continue_clipping;
}
}
bool ret = false;
#if defined(CARVE_DEBUG)
dumpPoly(begin->edge, NULL, "remainder_");
#endif
if (remain > 3) {
std::vector<carve::geom2d::P2> temp;
temp.reserve(remain);
VertexInfo *v = begin;
do {
temp.push_back(P(v));
v = v->next;
} while (v != begin);
if (carve::geom2d::signedArea(temp) == 0) {
// XXX: this test will fail in cases where the boundary is
// twisted so that a negative area balances a positive area.
std::cerr << "got to here" << std::endl;
dumpPoly(begin->edge, NULL, "interesting_case_");
goto done;
}
}
if (remain > 3) {
remain -= removeDegeneracies(begin, out);
}
if (remain > 3) {
return splitAndResume(begin, out);
}
{ double a = loopArea(begin->edge, proj); CARVE_ASSERT(a <= 0.0); }
*out++ = begin->edge;
v = begin;
do {
n = v->next;
delete v;
v = n;
} while (v != begin);
ret = true;
done:
return ret;
}
}
template<unsigned ndim, typename proj_t, typename out_iter_t>
void triangulate(Edge<ndim> *edge, proj_t proj, out_iter_t out) {
detail::TriangulationData<ndim, proj_t> triangulator(proj);
typename detail::TriangulationData<ndim, proj_t>::VertexInfo *v = triangulator.init(edge);
triangulator.removeDegeneracies(v, out);
triangulator.doTriangulate(v, out);
}
// given edge a-b, part of triangles a-b-c and b-a-d, make triangles c-a-d and b-c-d
template<unsigned ndim>
void flipTriEdge(Edge<ndim> *edge) {
CARVE_ASSERT(edge->rev != NULL);
CARVE_ASSERT(edge->face->nEdges() == 3);
CARVE_ASSERT(edge->rev->face->nEdges() == 3);
CARVE_ASSERT(edge->prev != edge);
CARVE_ASSERT(edge->next != edge);
CARVE_ASSERT(edge->rev->prev != edge->rev);
CARVE_ASSERT(edge->rev->next != edge->rev);
typedef Edge<ndim> edge_t;
typedef Face<ndim> face_t;
edge_t *t1[3], *t2[3];
face_t *f1, *f2;
t1[1] = edge; t2[1] = edge->rev;
t1[0] = t1[1]->prev; t1[2] = t1[1]->next;
t2[0] = t2[1]->prev; t2[2] = t2[1]->next;
f1 = t1[1]->face; f2 = t2[1]->face;
// std::cerr << t1[0]->vert << "->" << t1[1]->vert << "->" << t1[2]->vert << std::endl;
// std::cerr << t2[0]->vert << "->" << t2[1]->vert << "->" << t2[2]->vert << std::endl;
t1[1]->vert = t2[0]->vert;
t2[1]->vert = t1[0]->vert;
// std::cerr << t1[0]->vert << "->" << t2[2]->vert << "->" << t1[1]->vert << std::endl;
// std::cerr << t2[0]->vert << "->" << t1[2]->vert << "->" << t2[1]->vert << std::endl;
detail::link(t1[0], t2[2], t1[1], f1);
detail::link(t2[0], t1[2], t2[1], f2);
if (t1[0]->rev) CARVE_ASSERT(t1[0]->v2() == t1[0]->rev->v1());
if (t2[0]->rev) CARVE_ASSERT(t2[0]->v2() == t2[0]->rev->v1());
if (t1[2]->rev) CARVE_ASSERT(t1[2]->v2() == t1[2]->rev->v1());
if (t2[2]->rev) CARVE_ASSERT(t2[2]->v2() == t2[2]->rev->v1());
}
template<unsigned ndim>
void splitEdgeLoop(Edge<ndim> *v1, Edge<ndim> *v2) {
// v1 and v2 end up on different sides of the split.
Edge<ndim> *v1_copy = new Edge<ndim>(v1->vert, NULL);
Edge<ndim> *v2_copy = new Edge<ndim>(v2->vert, NULL);
v1_copy->rev = v2_copy;
v2_copy->rev = v1_copy;
v1_copy->prev = v1->prev;
v1_copy->next = v2;
v2_copy->prev = v2->prev;
v2_copy->next = v1;
v1->prev->next = v1_copy;
v1->prev = v2_copy;
v2->prev->next = v2_copy;
v2->prev = v1_copy;
}
template<unsigned ndim>
Edge<ndim> *clipVertex(Edge<ndim> *edge) {
Edge<ndim> *prev = edge->prev;
Edge<ndim> *next = edge->next;
splitEdgeLoop(edge->prev, edge->next);
return next;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,193 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom3d.hpp>
#include <carve/aabb.hpp>
#include <carve/polyhedron_base.hpp>
namespace carve {
namespace csg {
const double SLACK_FACTOR=1.0009765625;
const unsigned FACE_SPLIT_THRESHOLD=50U;
const unsigned EDGE_SPLIT_THRESHOLD=50U;
const unsigned POINT_SPLIT_THRESHOLD=20U;
const unsigned MAX_SPLIT_DEPTH=32;
class Octree {
public:
class Node {
private:
Node(const Node &node); // undefined.
Node &operator=(const Node &node); // undefined.
public:
Node *parent;
Node *children[8];
bool is_leaf;
carve::geom3d::Vector min;
carve::geom3d::Vector max;
std::vector<const carve::poly::Geometry<3>::face_t *> faces;
std::vector<const carve::poly::Geometry<3>::edge_t *> edges;
std::vector<const carve::poly::Geometry<3>::vertex_t *> vertices;
carve::geom3d::AABB aabb;
Node();
Node(const carve::geom3d::Vector &newMin, const carve::geom3d::Vector &newMax);
Node(Node *p, double x1, double y1, double z1, double x2, double y2, double z2);
~Node();
bool mightContain(const carve::poly::Geometry<3>::face_t &face);
bool mightContain(const carve::poly::Geometry<3>::edge_t &edge);
bool mightContain(const carve::poly::Geometry<3>::vertex_t &p);
bool hasChildren();
bool hasGeometry();
template <class T>
void putInside(const T &input, Node *child, T &output);
bool split();
};
Node *root;
struct no_filter {
bool operator()(const carve::poly::Geometry<3>::edge_t *) { return true; }
bool operator()(const carve::poly::Geometry<3>::face_t *) { return true; }
};
Octree();
~Octree();
void setBounds(const carve::geom3d::Vector &min, const carve::geom3d::Vector &max);
void setBounds(carve::geom3d::AABB aabb);
void addEdges(const std::vector<carve::poly::Geometry<3>::edge_t > &edges);
void addFaces(const std::vector<carve::poly::Geometry<3>::face_t > &faces);
void addVertices(const std::vector<const carve::poly::Geometry<3>::vertex_t *> &vertices);
static carve::geom3d::AABB makeAABB(const Node *node);
void doFindEdges(const carve::geom::aabb<3> &aabb,
Node *node,
std::vector<const carve::poly::Geometry<3>::edge_t *> &out,
unsigned depth) const;
void doFindEdges(const carve::geom3d::LineSegment &l,
Node *node,
std::vector<const carve::poly::Geometry<3>::edge_t *> &out,
unsigned depth) const;
void doFindEdges(const carve::geom3d::Vector &v,
Node *node,
std::vector<const carve::poly::Geometry<3>::edge_t *> &out,
unsigned depth) const;
void doFindFaces(const carve::geom::aabb<3> &aabb,
Node *node,
std::vector<const carve::poly::Geometry<3>::face_t *> &out,
unsigned depth) const;
void doFindFaces(const carve::geom3d::LineSegment &l,
Node *node,
std::vector<const carve::poly::Geometry<3>::face_t *> &out,
unsigned depth) const;
void doFindVerticesAllowDupes(const carve::geom3d::Vector &v,
Node *node,
std::vector<const carve::poly::Geometry<3>::vertex_t *> &out,
unsigned depth) const;
void findVerticesNearAllowDupes(const carve::geom3d::Vector &v,
std::vector<const carve::poly::Geometry<3>::vertex_t *> &out) const;
template<typename filter_t>
void doFindEdges(const carve::poly::Geometry<3>::face_t &f, Node *node,
std::vector<const carve::poly::Geometry<3>::edge_t *> &out,
unsigned depth,
filter_t filter) const;
template<typename filter_t>
void findEdgesNear(const carve::poly::Geometry<3>::face_t &f,
std::vector<const carve::poly::Geometry<3>::edge_t *> &out,
filter_t filter) const;
void findEdgesNear(const carve::poly::Geometry<3>::face_t &f,
std::vector<const carve::poly::Geometry<3>::edge_t *> &out) const {
return findEdgesNear(f, out, no_filter());
}
void findEdgesNear(const carve::geom::aabb<3> &aabb, std::vector<const carve::poly::Geometry<3>::edge_t *> &out) const;
void findEdgesNear(const carve::geom3d::LineSegment &l, std::vector<const carve::poly::Geometry<3>::edge_t *> &out) const;
void findEdgesNear(const carve::poly::Geometry<3>::edge_t &e, std::vector<const carve::poly::Geometry<3>::edge_t *> &out) const;
void findEdgesNear(const carve::geom3d::Vector &v, std::vector<const carve::poly::Geometry<3>::edge_t *> &out) const;
void findFacesNear(const carve::geom::aabb<3> &aabb, std::vector<const carve::poly::Geometry<3>::face_t *> &out) const;
void findFacesNear(const carve::geom3d::LineSegment &l, std::vector<const carve::poly::Geometry<3>::face_t *> &out) const;
void findFacesNear(const carve::poly::Geometry<3>::edge_t &e, std::vector<const carve::poly::Geometry<3>::face_t *> &out) const;
static void doSplit(int maxSplit, Node *node);
template <typename FUNC>
void doIterate(int level, Node *node, const FUNC &f) const;
template <typename FUNC>
void iterateNodes(const FUNC &f) const;
void splitTree();
};
}
}

View File

@@ -0,0 +1,79 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
namespace carve {
namespace csg {
template<typename filter_t>
void Octree::doFindEdges(const carve::poly::Geometry<3>::face_t &f,
Node *node,
std::vector<const carve::poly::Geometry<3>::edge_t *> &out,
unsigned depth,
filter_t filter) const {
if (node == NULL) {
return;
}
if (node->aabb.intersects(f.aabb) && node->aabb.intersects(f.plane_eqn)) {
if (node->hasChildren()) {
for (int i = 0; i < 8; ++i) {
doFindEdges(f, node->children[i], out, depth + 1, filter);
}
} else {
if (depth < MAX_SPLIT_DEPTH && node->edges.size() > EDGE_SPLIT_THRESHOLD) {
if (!node->split()) {
for (int i = 0; i < 8; ++i) {
doFindEdges(f, node->children[i], out, depth + 1, filter);
}
return;
}
}
for (std::vector<const carve::poly::Geometry<3>::edge_t*>::const_iterator it = node->edges.begin(), e = node->edges.end(); it != e; ++it) {
if ((*it)->tag_once()) {
if (filter(*it)) {
out.push_back(*it);
}
}
}
}
}
}
template<typename filter_t>
void Octree::findEdgesNear(const carve::poly::Geometry<3>::face_t &f, std::vector<const carve::poly::Geometry<3>::edge_t *> &out, filter_t filter) const {
tagable::tag_begin();
doFindEdges(f, root, out, 0, filter);
}
template <typename func_t>
void Octree::doIterate(int level, Node *node, const func_t &f) const{
f(level, node);
if (node->hasChildren()) {
for (int i = 0; i < 8; ++i) {
doIterate(level + 1, node->children[i], f);
}
}
}
template <typename func_t>
void Octree::iterateNodes(const func_t &f) const {
doIterate(0, root, f);
}
}
}

24
extern/carve/include/carve/pointset.hpp vendored Normal file
View File

@@ -0,0 +1,24 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/pointset_decl.hpp>
#include <carve/pointset_impl.hpp>
#include <carve/pointset_iter.hpp>

View File

@@ -0,0 +1,61 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <iterator>
#include <list>
#include <iterator>
#include <limits>
#include <carve/carve.hpp>
#include <carve/tag.hpp>
#include <carve/geom.hpp>
#include <carve/kd_node.hpp>
#include <carve/geom3d.hpp>
#include <carve/aabb.hpp>
namespace carve {
namespace point {
struct Vertex : public tagable {
carve::geom3d::Vector v;
};
struct vec_adapt_vertex_ptr {
const carve::geom3d::Vector &operator()(const Vertex * const &v) { return v->v; }
carve::geom3d::Vector &operator()(Vertex *&v) { return v->v; }
};
struct PointSet {
std::vector<Vertex> vertices;
carve::geom3d::AABB aabb;
PointSet(const std::vector<carve::geom3d::Vector> &points);
PointSet() {
}
void sortVertices(const carve::geom3d::Vector &axis);
size_t vertexToIndex_fast(const Vertex *v) const;
};
}
}

View File

@@ -0,0 +1,36 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <vector>
#include <carve/carve.hpp>
#include <carve/tag.hpp>
#include <carve/geom.hpp>
#include <carve/kd_node.hpp>
#include <carve/geom3d.hpp>
#include <carve/aabb.hpp>
namespace carve {
namespace point {
inline size_t PointSet::vertexToIndex_fast(const Vertex *v) const {
return (size_t)(v - &vertices[0]);
}
}
}

View File

@@ -0,0 +1,18 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once

24
extern/carve/include/carve/poly.hpp vendored Normal file
View File

@@ -0,0 +1,24 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/poly_decl.hpp>
#include <carve/poly_impl.hpp>

View File

@@ -0,0 +1,25 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/vertex_decl.hpp>
#include <carve/edge_decl.hpp>
#include <carve/face_decl.hpp>
#include <carve/polyhedron_decl.hpp>

View File

@@ -0,0 +1,25 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/vertex_impl.hpp>
#include <carve/edge_impl.hpp>
#include <carve/face_impl.hpp>
#include <carve/polyhedron_impl.hpp>

View File

@@ -0,0 +1,149 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom3d.hpp>
#include <carve/vertex_decl.hpp>
#include <carve/edge_decl.hpp>
#include <carve/face_decl.hpp>
#include <stddef.h>
namespace carve {
namespace poly {
struct Object {
};
template<typename array_t>
ptrdiff_t ptrToIndex_fast(const array_t &a, const typename array_t::value_type *v) {
return v - &a[0];
}
template<typename array_t>
ptrdiff_t ptrToIndex(const array_t &a, const typename array_t::value_type *v) {
if (v < &a.front() || v > &a.back()) return -1;
return v - &a[0];
}
template<unsigned ndim>
struct Geometry : public Object {
struct Connectivity {
} connectivity;
};
template<>
struct Geometry<2> : public Object {
typedef Vertex<2> vertex_t;
typedef Edge<2> edge_t;
struct Connectivity {
std::vector<std::vector<const edge_t *> > vertex_to_edge;
} connectivity;
std::vector<vertex_t> vertices;
std::vector<edge_t> edges;
ptrdiff_t vertexToIndex_fast(const vertex_t *v) const { return ptrToIndex_fast(vertices, v); }
ptrdiff_t vertexToIndex(const vertex_t *v) const { return ptrToIndex(vertices, v); }
ptrdiff_t edgeToIndex_fast(const edge_t *e) const { return ptrToIndex_fast(edges, e); }
ptrdiff_t edgeToIndex(const edge_t *e) const { return ptrToIndex(edges, e); }
// *** connectivity queries
template<typename T>
int vertexToEdges(const vertex_t *v, T result) const;
};
template<>
struct Geometry<3> : public Object {
typedef Vertex<3> vertex_t;
typedef Edge<3> edge_t;
typedef Face<3> face_t;
struct Connectivity {
std::vector<std::vector<const edge_t *> > vertex_to_edge;
std::vector<std::vector<const face_t *> > vertex_to_face;
std::vector<std::vector<const face_t *> > edge_to_face;
} connectivity;
std::vector<vertex_t> vertices;
std::vector<edge_t> edges;
std::vector<face_t> faces;
ptrdiff_t vertexToIndex_fast(const vertex_t *v) const { return ptrToIndex_fast(vertices, v); }
ptrdiff_t vertexToIndex(const vertex_t *v) const { return ptrToIndex(vertices, v); }
ptrdiff_t edgeToIndex_fast(const edge_t *e) const { return ptrToIndex_fast(edges, e); }
ptrdiff_t edgeToIndex(const edge_t *e) const { return ptrToIndex(edges, e); }
ptrdiff_t faceToIndex_fast(const face_t *f) const { return ptrToIndex_fast(faces, f); }
ptrdiff_t faceToIndex(const face_t *f) const { return ptrToIndex(faces, f); }
template<typename order_t>
bool orderVertices(order_t order);
bool orderVertices() { return orderVertices(std::less<vertex_t::vector_t>()); }
// *** connectivity queries
const face_t *connectedFace(const face_t *, const edge_t *) const;
template<typename T>
int _faceNeighbourhood(const face_t *f, int depth, T *result) const;
template<typename T>
int faceNeighbourhood(const face_t *f, int depth, T result) const;
template<typename T>
int faceNeighbourhood(const edge_t *e, int m_id, int depth, T result) const;
template<typename T>
int faceNeighbourhood(const vertex_t *v, int m_id, int depth, T result) const;
template<typename T>
int vertexToEdges(const vertex_t *v, T result) const;
template<typename T>
int edgeToFaces(const edge_t *e, T result) const;
template<typename T>
int vertexToFaces(const vertex_t *v, T result) const;
};
}
}

View File

@@ -0,0 +1,184 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom3d.hpp>
#include <carve/polyhedron_base.hpp>
#include <carve/octree_decl.hpp>
#include <carve/collection_types.hpp>
#include <assert.h>
#include <list>
namespace carve {
namespace mesh {
template<unsigned ndim>
class MeshSet;
}
namespace poly {
class Polyhedron;
}
poly::Polyhedron *polyhedronFromMesh(const mesh::MeshSet<3> *, int);
namespace poly {
class Polyhedron : public Geometry<3> {
private:
friend Polyhedron *carve::polyhedronFromMesh(const mesh::MeshSet<3> *, int);
Polyhedron() {
}
Polyhedron &operator=(const Polyhedron &); // not implemented
// *** initialization
bool initSpatialIndex();
void initVertexConnectivity();
void setFaceAndVertexOwner();
bool initConnectivity();
bool markManifolds();
bool calcManifoldEmbedding();
bool init();
void faceRecalc();
void commonFaceInit(bool _recalc);
public:
static void collectFaceVertices(std::vector<face_t > &faces,
std::vector<vertex_t > &vertices,
std::unordered_map<const vertex_t *, const vertex_t *> &vmap);
static void collectFaceVertices(std::vector<face_t > &faces,
std::vector<vertex_t > &vertices);
std::vector<bool> manifold_is_closed;
std::vector<bool> manifold_is_negative;
carve::geom3d::AABB aabb;
carve::csg::Octree octree;
// *** construction of Polyhedron objects
Polyhedron(const Polyhedron &);
// copy a single manifold
Polyhedron(const Polyhedron &, int m_id);
// copy a subset of manifolds
Polyhedron(const Polyhedron &, const std::vector<bool> &selected_manifolds);
Polyhedron(std::vector<face_t > &_faces,
std::vector<vertex_t > &_vertices,
bool _recalc = false);
Polyhedron(std::vector<face_t > &_faces,
bool _recalc = false);
Polyhedron(std::list<face_t > &_faces,
bool _recalc = false);
Polyhedron(const std::vector<carve::geom3d::Vector> &vertices,
int n_faces,
const std::vector<int> &face_indices);
~Polyhedron();
// *** containment queries
void testVertexAgainstClosedManifolds(const carve::geom3d::Vector &v,
std::map<int, PointClass> &result,
bool ignore_orentation) const;
PointClass containsVertex(const carve::geom3d::Vector &v,
const face_t **hit_face = NULL,
bool even_odd = false,
int manifold_id = -1) const;
// *** locality queries
void findEdgesNear(const carve::geom::aabb<3> &aabb, std::vector<const edge_t *> &edges) const;
void findEdgesNear(const carve::geom3d::LineSegment &l, std::vector<const edge_t *> &edges) const;
void findEdgesNear(const carve::geom3d::Vector &v, std::vector<const edge_t *> &edges) const;
void findEdgesNear(const face_t &face, std::vector<const edge_t *> &edges) const;
void findEdgesNear(const edge_t &edge, std::vector<const edge_t *> &edges) const;
void findFacesNear(const carve::geom::aabb<3> &aabb, std::vector<const face_t *> &faces) const;
void findFacesNear(const carve::geom3d::LineSegment &l, std::vector<const face_t *> &faces) const;
void findFacesNear(const edge_t &edge, std::vector<const face_t *> &faces) const;
// *** manifold queries
inline bool vertexOnManifold(const vertex_t *v, int m_id) const;
inline bool edgeOnManifold(const edge_t *e, int m_id) const;
template<typename T>
int vertexManifolds(const vertex_t *v, T result) const;
template<typename T>
int edgeManifolds(const edge_t *e, T result) const;
size_t manifoldCount() const;
bool hasOpenManifolds() const;
// *** transformation
// flip face directions
void invertAll();
void invert(const std::vector<bool> &selected_manifolds);
void invert(int m_id);
void invert();
// matrix transform of vertices
void transform(const carve::math::Matrix &xform);
// arbitrary function transform of vertices
template<typename T>
void transform(const T &xform);
void print(std::ostream &) const;
void canonicalize();
};
std::ostream &operator<<(std::ostream &, const Polyhedron &);
}
}

View File

@@ -0,0 +1,286 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/timing.hpp>
#include <assert.h>
#include <list>
namespace carve {
namespace poly {
template<typename order_t>
struct VPtrSort {
order_t order;
VPtrSort(const order_t &_order) : order(_order) {}
bool operator()(carve::poly::Polyhedron::vertex_t const *a,
carve::poly::Polyhedron::vertex_t const *b) const {
return order(a->v, b->v);
}
};
template<typename order_t>
bool Geometry<3>::orderVertices(order_t order) {
static carve::TimingName FUNC_NAME("Geometry<3>::orderVertices()");
carve::TimingBlock block(FUNC_NAME);
std::vector<vertex_t *> vptr;
std::vector<vertex_t *> vmap;
std::vector<vertex_t> vout;
const size_t N = vertices.size();
vptr.reserve(N);
vout.reserve(N);
vmap.resize(N);
for (size_t i = 0; i != N; ++i) {
vptr.push_back(&vertices[i]);
}
std::sort(vptr.begin(), vptr.end(), VPtrSort<order_t>(order));
for (size_t i = 0; i != N; ++i) {
vout.push_back(*vptr[i]);
vmap[(size_t)vertexToIndex_fast(vptr[i])] = &vout[i];
}
for (size_t i = 0; i < faces.size(); ++i) {
face_t &f = faces[i];
for (size_t j = 0; j < f.nVertices(); ++j) {
f.vertex(j) = vmap[(size_t)vertexToIndex_fast(f.vertex(j))];
}
}
for (size_t i = 0; i < edges.size(); ++i) {
edges[i].v1 = vmap[(size_t)vertexToIndex_fast(edges[i].v1)];
edges[i].v2 = vmap[(size_t)vertexToIndex_fast(edges[i].v2)];
}
vout.swap(vertices);
return true;
}
template<typename T>
int Geometry<3>::_faceNeighbourhood(const face_t *f, int depth, T *result) const {
if (depth < 0 || f->is_tagged()) return 0;
f->tag();
*(*result)++ = f;
int r = 1;
for (size_t i = 0; i < f->nEdges(); ++i) {
const face_t *f2 = connectedFace(f, f->edge(i));
if (f2) {
r += _faceNeighbourhood(f2, depth - 1, (*result));
}
}
return r;
}
template<typename T>
int Geometry<3>::faceNeighbourhood(const face_t *f, int depth, T result) const {
tagable::tag_begin();
return _faceNeighbourhood(f, depth, &result);
}
template<typename T>
int Geometry<3>::faceNeighbourhood(const edge_t *e, int m_id, int depth, T result) const {
tagable::tag_begin();
int r = 0;
const std::vector<const face_t *> &edge_faces = connectivity.edge_to_face[(size_t)edgeToIndex_fast(e)];
for (size_t i = 0; i < edge_faces.size(); ++i) {
const face_t *f = edge_faces[i];
if (f && f->manifold_id == m_id) { r += _faceNeighbourhood(f, depth, &result); }
}
return r;
}
template<typename T>
int Geometry<3>::faceNeighbourhood(const vertex_t *v, int m_id, int depth, T result) const {
tagable::tag_begin();
int r = 0;
const std::vector<const face_t *> &vertex_faces = connectivity.vertex_to_face[(size_t)vertexToIndex_fast(v)];
for (size_t i = 0; i < vertex_faces.size(); ++i) {
const face_t *f = vertex_faces[i];
if (f && f->manifold_id == m_id) { r += _faceNeighbourhood(f, depth, &result); }
}
return r;
}
// accessing connectivity information.
template<typename T>
int Geometry<3>::vertexToEdges(const vertex_t *v, T result) const {
const std::vector<const edge_t *> &e = connectivity.vertex_to_edge[(size_t)vertexToIndex_fast(v)];
std::copy(e.begin(), e.end(), result);
return e.size();
}
template<typename T>
int Geometry<3>::vertexToFaces(const vertex_t *v, T result) const {
const std::vector<const face_t *> &vertex_faces = connectivity.vertex_to_face[(size_t)vertexToIndex_fast(v)];
int c = 0;
for (size_t i = 0; i < vertex_faces.size(); ++i) {
*result++ = vertex_faces[i]; ++c;
}
return c;
}
template<typename T>
int Geometry<3>::edgeToFaces(const edge_t *e, T result) const {
const std::vector<const face_t *> &edge_faces = connectivity.edge_to_face[(size_t)edgeToIndex_fast(e)];
int c = 0;
for (size_t i = 0; i < edge_faces.size(); ++i) {
if (edge_faces[i] != NULL) { *result++ = edge_faces[i]; ++c; }
}
return c;
}
inline const Geometry<3>::face_t *Geometry<3>::connectedFace(const face_t *f, const edge_t *e) const {
const std::vector<const face_t *> &edge_faces = connectivity.edge_to_face[(size_t)edgeToIndex_fast(e)];
for (size_t i = 0; i < (edge_faces.size() & ~1U); i++) {
if (edge_faces[i] == f) return edge_faces[i^1];
}
return NULL;
}
inline void Polyhedron::invert(int m_id) {
std::vector<bool> selected_manifolds(manifold_is_closed.size(), false);
if (m_id >=0 && (size_t)m_id < selected_manifolds.size()) selected_manifolds[(size_t)m_id] = true;
invert(selected_manifolds);
}
inline void Polyhedron::invert() {
invertAll();
}
inline bool Polyhedron::edgeOnManifold(const edge_t *e, int m_id) const {
const std::vector<const face_t *> &edge_faces = connectivity.edge_to_face[(size_t)edgeToIndex_fast(e)];
for (size_t i = 0; i < edge_faces.size(); ++i) {
if (edge_faces[i] && edge_faces[i]->manifold_id == m_id) return true;
}
return false;
}
inline bool Polyhedron::vertexOnManifold(const vertex_t *v, int m_id) const {
const std::vector<const face_t *> &f = connectivity.vertex_to_face[(size_t)vertexToIndex_fast(v)];
for (size_t i = 0; i < f.size(); ++i) {
if (f[i]->manifold_id == m_id) return true;
}
return false;
}
template<typename T>
int Polyhedron::edgeManifolds(const edge_t *e, T result) const {
const std::vector<const face_t *> &edge_faces = connectivity.edge_to_face[(size_t)edgeToIndex_fast(e)];
for (size_t i = 0; i < (edge_faces.size() & ~1U); i += 2) {
const face_t *f1 = edge_faces[i];
const face_t *f2 = edge_faces[i+1];
assert (f1 || f2);
if (f1)
*result++ = f1->manifold_id;
else if (f2)
*result++ = f2->manifold_id;
}
return (int)(edge_faces.size() >> 1);
}
template<typename T>
int Polyhedron::vertexManifolds(const vertex_t *v, T result) const {
const std::vector<const face_t *> &f = connectivity.vertex_to_face[(size_t)vertexToIndex_fast(v)];
std::set<int> em;
for (size_t i = 0; i < f.size(); ++i) {
em.insert(f[i]->manifold_id);
}
std::copy(em.begin(), em.end(), result);
return em.size();
}
template<typename T>
void Polyhedron::transform(const T &xform) {
for (size_t i = 0; i < vertices.size(); i++) {
vertices[i].v = xform(vertices[i].v);
}
faceRecalc();
init();
}
inline size_t Polyhedron::manifoldCount() const {
return manifold_is_closed.size();
}
inline bool Polyhedron::hasOpenManifolds() const {
for (size_t i = 0; i < manifold_is_closed.size(); ++i) {
if (!manifold_is_closed[i]) return true;
}
return false;
}
inline std::ostream &operator<<(std::ostream &o, const Polyhedron &p) {
p.print(o);
return o;
}
}
}

24
extern/carve/include/carve/polyline.hpp vendored Normal file
View File

@@ -0,0 +1,24 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/polyline_decl.hpp>
#include <carve/polyline_impl.hpp>
#include <carve/polyline_iter.hpp>

View File

@@ -0,0 +1,156 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <iterator>
#include <list>
#include <iterator>
#include <limits>
#include <carve/carve.hpp>
#include <carve/tag.hpp>
#include <carve/geom.hpp>
#include <carve/kd_node.hpp>
#include <carve/geom3d.hpp>
#include <carve/aabb.hpp>
namespace carve {
namespace line {
struct PolylineEdge;
struct Polyline;
struct polyline_vertex_const_iter;
struct polyline_vertex_iter;
struct polyline_edge_const_iter;
struct polyline_edge_iter;
struct Vertex : public tagable {
carve::geom3d::Vector v;
std::list<std::pair<PolylineEdge *, PolylineEdge *> > edge_pairs;
void addEdgePair(PolylineEdge *in, PolylineEdge *out) {
edge_pairs.push_back(std::make_pair(in, out));
}
};
struct vec_adapt_vertex_ptr {
const carve::geom3d::Vector &operator()(const Vertex * const &v) { return v->v; }
carve::geom3d::Vector &operator()(Vertex *&v) { return v->v; }
};
struct PolylineEdge : public tagable {
Polyline *parent;
size_t edgenum;
Vertex *v1, *v2;
PolylineEdge(Polyline *_parent, size_t _edgenum, Vertex *_v1, Vertex *_v2);
carve::geom3d::AABB aabb() const;
inline PolylineEdge *prevEdge() const;
inline PolylineEdge *nextEdge() const;
};
struct Polyline {
bool closed;
std::vector<PolylineEdge *> edges;
Polyline();
size_t vertexCount() const;
size_t edgeCount() const;
const PolylineEdge *edge(size_t e) const;
PolylineEdge *edge(size_t e);
const Vertex *vertex(size_t v) const;
Vertex *vertex(size_t v);
bool isClosed() const;
polyline_vertex_const_iter vbegin() const;
polyline_vertex_const_iter vend() const;
polyline_vertex_iter vbegin();
polyline_vertex_iter vend();
polyline_edge_const_iter ebegin() const;
polyline_edge_const_iter eend() const;
polyline_edge_iter ebegin();
polyline_edge_iter eend();
carve::geom3d::AABB aabb() const;
template<typename iter_t>
void _init(bool c, iter_t begin, iter_t end, std::vector<Vertex> &vertices);
template<typename iter_t>
void _init(bool closed, iter_t begin, iter_t end, std::vector<Vertex> &vertices, std::forward_iterator_tag);
template<typename iter_t>
void _init(bool closed, iter_t begin, iter_t end, std::vector<Vertex> &vertices, std::random_access_iterator_tag);
template<typename iter_t>
Polyline(bool closed, iter_t begin, iter_t end, std::vector<Vertex> &vertices);
~Polyline() {
for (size_t i = 0; i < edges.size(); ++i) {
delete edges[i];
}
}
};
struct PolylineSet {
typedef std::list<Polyline *> line_list;
typedef line_list::iterator line_iter;
typedef line_list::const_iterator const_line_iter;
std::vector<Vertex> vertices;
line_list lines;
carve::geom3d::AABB aabb;
PolylineSet(const std::vector<carve::geom3d::Vector> &points);
PolylineSet() {
}
~PolylineSet() {
for (line_iter i = lines.begin(); i != lines.end(); ++i) {
delete *i;
}
}
template<typename iter_t>
void addPolyline(bool closed, iter_t begin, iter_t end);
void sortVertices(const carve::geom3d::Vector &axis);
size_t vertexToIndex_fast(const Vertex *v) const;
};
}
}

View File

@@ -0,0 +1,160 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
namespace carve {
namespace line {
inline PolylineEdge::PolylineEdge(Polyline *_parent, size_t _edgenum, Vertex *_v1, Vertex *_v2) :
tagable(), parent(_parent), edgenum(_edgenum), v1(_v1), v2(_v2) {
}
inline carve::geom3d::AABB PolylineEdge::aabb() const {
carve::geom3d::AABB a;
a.fit(v1->v, v2->v);
return a;
}
inline PolylineEdge *PolylineEdge::prevEdge() const {
if (edgenum) {
return parent->edge(edgenum - 1);
} else {
if (parent->closed) {
return parent->edge(parent->edgeCount() - 1);
} else {
return NULL;
}
}
}
inline PolylineEdge *PolylineEdge::nextEdge() const {
if (edgenum + 1 < parent->edgeCount()) {
return parent->edge(edgenum + 1);
} else {
if (parent->closed) {
return parent->edge(0);
} else {
return NULL;
}
}
}
inline Polyline::Polyline() : edges() {
}
inline size_t Polyline::vertexCount() const {
return edgeCount() + (closed ? 0 : 1);
}
inline size_t Polyline::edgeCount() const {
return edges.size();
}
inline const PolylineEdge *Polyline::edge(size_t e) const {
return edges[e % edges.size()];
}
inline PolylineEdge *Polyline::edge(size_t e) {
return edges[e % edges.size()];
}
inline const Vertex *Polyline::vertex(size_t v) const {
if (closed) {
v %= edgeCount();
} else if (v >= edgeCount()) {
return v == edgeCount() ? edges.back()->v2 : NULL;
}
return edges[v]->v1;
}
inline Vertex *Polyline::vertex(size_t v) {
if (closed) {
v %= edgeCount();
} else if (v >= edgeCount()) {
return v == edgeCount() ? edges.back()->v2 : NULL;
}
return edges[v]->v1;
}
inline bool Polyline::isClosed() const {
return closed;
}
template<typename iter_t>
void Polyline::_init(bool c, iter_t begin, iter_t end, std::vector<Vertex> &vertices) {
closed = c;
PolylineEdge *e;
if (begin == end) return;
size_t v1 = (size_t)*begin++;
if (begin == end) return;
while (begin != end) {
size_t v2 = (size_t)*begin++;
e = new PolylineEdge(this, edges.size(), &vertices[v1], &vertices[v2]);
edges.push_back(e);
v1 = v2;
}
if (closed) {
e = new PolylineEdge(this, edges.size(), edges.back()->v2, edges.front()->v1);
edges.push_back(e);
edges.front()->v1->addEdgePair(edges.back(), edges.front());
for (size_t i = 1; i < edges.size(); ++i) {
edges[i]->v1->addEdgePair(edges[i-1], edges[i]);
}
} else {
edges.front()->v1->addEdgePair(NULL, edges.front());
for (size_t i = 1; i < edges.size(); ++i) {
edges[i]->v1->addEdgePair(edges[i-1], edges[i]);
}
edges.back()->v2->addEdgePair(edges.back(), NULL);
}
}
template<typename iter_t>
void Polyline::_init(bool closed, iter_t begin, iter_t end, std::vector<Vertex> &vertices, std::forward_iterator_tag) {
_init(closed, begin, end, vertices);
}
template<typename iter_t>
void Polyline::_init(bool closed, iter_t begin, iter_t end, std::vector<Vertex> &vertices, std::random_access_iterator_tag) {
edges.reserve(end - begin - (closed ? 0 : 1));
_init(closed, begin, end, vertices);
}
template<typename iter_t>
Polyline::Polyline(bool closed, iter_t begin, iter_t end, std::vector<Vertex> &vertices) {
_init(closed, begin, end, vertices, typename std::iterator_traits<iter_t>::iterator_category());
}
template<typename iter_t>
void PolylineSet::addPolyline(bool closed, iter_t begin, iter_t end) {
Polyline *p = new Polyline(closed, begin, end, vertices);
lines.push_back(p);
}
inline size_t PolylineSet::vertexToIndex_fast(const Vertex *v) const {
return (size_t)(v - &vertices[0]);
}
}
}

View File

@@ -0,0 +1,203 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <iterator>
#include <list>
#include <iterator>
#include <limits>
#include <cstddef>
#include <carve/polyline_decl.hpp>
namespace carve {
namespace line {
struct polyline_vertex_iter : public std::iterator<std::random_access_iterator_tag, Vertex *> {
Polyline *base;
ssize_t idx;
polyline_vertex_iter(Polyline *_base) : base(_base), idx(0) {
}
polyline_vertex_iter(Polyline *_base, ssize_t _idx) : base(_base), idx(_idx) {
}
polyline_vertex_iter operator++(int) { return polyline_vertex_iter(base, idx++); }
polyline_vertex_iter &operator++() { ++idx; return *this; }
polyline_vertex_iter &operator+=(int v) { idx += v; return *this; }
polyline_vertex_iter operator--(int) { return polyline_vertex_iter(base, idx--); }
polyline_vertex_iter &operator--() { --idx; return *this; }
polyline_vertex_iter &operator-=(int v) { idx -= v; return *this; }
Vertex *operator*() const {
CARVE_ASSERT(idx >= 0 && idx < base->vertexCount());
return base->vertex((size_t)idx);
}
};
static inline ssize_t operator-(const polyline_vertex_iter &a, const polyline_vertex_iter &b) { return a.idx - b.idx; }
static inline bool operator==(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx == b.idx; }
static inline bool operator!=(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx != b.idx; }
static inline bool operator<(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx < b.idx; }
static inline bool operator>(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx > b.idx; }
static inline bool operator<=(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx <= b.idx; }
static inline bool operator>=(const polyline_vertex_iter&a, const polyline_vertex_iter &b) { return a.idx >= b.idx; }
struct polyline_vertex_const_iter : public std::iterator<std::random_access_iterator_tag, Vertex *> {
const Polyline *base;
ssize_t idx;
polyline_vertex_const_iter(const Polyline *_base) : base(_base), idx(0) {
}
polyline_vertex_const_iter(const Polyline *_base, ssize_t _idx) : base(_base), idx(_idx) {
}
polyline_vertex_const_iter operator++(int) { return polyline_vertex_const_iter(base, idx++); }
polyline_vertex_const_iter &operator++() { ++idx; return *this; }
polyline_vertex_const_iter &operator+=(int v) { idx += v; return *this; }
polyline_vertex_const_iter operator--(int) { return polyline_vertex_const_iter(base, idx--); }
polyline_vertex_const_iter &operator--() { --idx; return *this; }
polyline_vertex_const_iter &operator-=(int v) { idx -= v; return *this; }
const Vertex *operator*() const {
CARVE_ASSERT(idx >= 0 && idx < base->vertexCount());
return base->vertex((size_t)idx);
}
};
static inline ssize_t operator-(const polyline_vertex_const_iter &a, const polyline_vertex_const_iter &b) { return a.idx - b.idx; }
static inline bool operator==(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx == b.idx; }
static inline bool operator!=(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx != b.idx; }
static inline bool operator<(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx < b.idx; }
static inline bool operator>(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx > b.idx; }
static inline bool operator<=(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx <= b.idx; }
static inline bool operator>=(const polyline_vertex_const_iter&a, const polyline_vertex_const_iter &b) { return a.idx >= b.idx; }
inline polyline_vertex_const_iter Polyline::vbegin() const {
return polyline_vertex_const_iter(this, 0);
}
inline polyline_vertex_const_iter Polyline::vend() const {
return polyline_vertex_const_iter(this, (ssize_t)vertexCount());
}
inline polyline_vertex_iter Polyline::vbegin() {
return polyline_vertex_iter(this, 0);
}
inline polyline_vertex_iter Polyline::vend() {
return polyline_vertex_iter(this, (ssize_t)vertexCount());
}
struct polyline_edge_iter : public std::iterator<std::random_access_iterator_tag, PolylineEdge *> {
Polyline *base;
ssize_t idx;
polyline_edge_iter(Polyline *_base) : base(_base), idx(0) {
}
polyline_edge_iter(Polyline *_base, ssize_t _idx) : base(_base), idx(_idx) {
}
polyline_edge_iter operator++(int) { return polyline_edge_iter(base, idx++); }
polyline_edge_iter &operator++() { ++idx; return *this; }
polyline_edge_iter &operator+=(int v) { idx += v; return *this; }
polyline_edge_iter operator--(int) { return polyline_edge_iter(base, idx--); }
polyline_edge_iter &operator--() { --idx; return *this; }
polyline_edge_iter &operator-=(int v) { idx -= v; return *this; }
PolylineEdge *operator*() const {
CARVE_ASSERT(idx >= 0 && idx < base->edgeCount());
return base->edge((size_t)idx);
}
};
static inline ssize_t operator-(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx - b.idx; }
static inline bool operator==(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx == b.idx; }
static inline bool operator!=(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx != b.idx; }
static inline bool operator<(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx < b.idx; }
static inline bool operator>(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx > b.idx; }
static inline bool operator<=(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx <= b.idx; }
static inline bool operator>=(const polyline_edge_iter&a, const polyline_edge_iter &b) { return a.idx >= b.idx; }
struct polyline_edge_const_iter : public std::iterator<std::random_access_iterator_tag, PolylineEdge *> {
const Polyline *base;
ssize_t idx;
polyline_edge_const_iter(const Polyline *_base) : base(_base), idx(0) {
}
polyline_edge_const_iter(const Polyline *_base, ssize_t _idx) : base(_base), idx(_idx) {
}
polyline_edge_const_iter operator++(int) { return polyline_edge_const_iter(base, idx++); }
polyline_edge_const_iter &operator++() { ++idx; return *this; }
polyline_edge_const_iter &operator+=(int v) { idx += v; return *this; }
polyline_edge_const_iter operator--(int) { return polyline_edge_const_iter(base, idx--); }
polyline_edge_const_iter &operator--() { --idx; return *this; }
polyline_edge_const_iter &operator-=(int v) { idx -= v; return *this; }
const PolylineEdge *operator*() const {
CARVE_ASSERT(idx >= 0 && idx < base->edgeCount());
return base->edge((size_t)idx);
}
};
static inline ssize_t operator-(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx - b.idx; }
static inline bool operator==(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx == b.idx; }
static inline bool operator!=(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx != b.idx; }
static inline bool operator<(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx < b.idx; }
static inline bool operator>(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx > b.idx; }
static inline bool operator<=(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx <= b.idx; }
static inline bool operator>=(const polyline_edge_const_iter&a, const polyline_edge_const_iter &b) { return a.idx >= b.idx; }
inline polyline_edge_const_iter Polyline::ebegin() const {
return polyline_edge_const_iter(this, 0);
}
inline polyline_edge_const_iter Polyline::eend() const {
return polyline_edge_const_iter(this, (ssize_t)edgeCount());
}
inline polyline_edge_iter Polyline::ebegin() {
return polyline_edge_iter(this, 0);
}
inline polyline_edge_iter Polyline::eend() {
return polyline_edge_iter(this, (ssize_t)edgeCount());
}
}
}

View File

@@ -0,0 +1,61 @@
#include <cassert>
#include <cmath>
#include <vector>
namespace boost {
#if __cplusplus > 199711L
# include <random>
typedef std::mt19937 mt19937;
#else
# include <stdlib.h>
struct mt19937 {
int operator()() {
return rand();
}
int max() {
return RAND_MAX;
}
};
#endif
template<typename T>
struct uniform_on_sphere {
typedef std::vector<T> result_type;
uniform_on_sphere(int dimension) {
assert(dimension == 3);
}
std::vector<T>
operator()(float u1, float u2) {
T z = 1.0 - 2.0*u1;
T r = std::sqrt(std::max(0.0, 1.0 - z*z));
T phi = 2.0*M_PI*u2;
T x = r*std::cos(phi);
T y = r*std::sin(phi);
std::vector<T> result;
result.push_back(x);
result.push_back(y);
result.push_back(z);
return result;
}
};
template<typename RNG, typename DISTR>
struct variate_generator {
variate_generator(RNG rng, DISTR distr)
: rng_(rng), distr_(distr) {}
typename DISTR::result_type
operator()() {
float rng_max_inv = 1.0 / rng_.max();
return distr_(rng_() * rng_max_inv, rng_() * rng_max_inv);
}
RNG rng_;
DISTR distr_;
};
}

100
extern/carve/include/carve/rescale.hpp vendored Normal file
View File

@@ -0,0 +1,100 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/vector.hpp>
#include <carve/aabb.hpp>
#include <carve/matrix.hpp>
#include <limits>
namespace carve {
namespace rescale {
template<typename T>
T calc_scale(T max) {
const int radix = std::numeric_limits<T>::radix;
T div = T(1);
T m = fabs(max);
while (div < m) div *= radix;
m *= radix;
while (div > m) div /= radix;
return div;
}
template<typename T>
T calc_delta(T min, T max) {
const int radix = std::numeric_limits<T>::radix;
if (min >= T(0) || max <= T(0)) {
bool neg = false;
if (max <= T(0)) {
min = -min;
max = -max;
std::swap(min, max);
neg = true;
}
T t = T(1);
while (t > max) t /= radix;
while (t <= max/radix) t *= radix;
volatile T temp = t + min;
temp -= t;
if (neg) temp = -temp;
return temp;
} else {
return T(0);
}
}
struct rescale {
double dx, dy, dz, scale;
void init(double minx, double miny, double minz, double maxx, double maxy, double maxz) {
dx = calc_delta(minx, maxx); minx -= dx; maxx -= dx;
dy = calc_delta(miny, maxy); miny -= dy; maxy -= dy;
dz = calc_delta(minz, maxz); minz -= dz; maxz -= dz;
scale = calc_scale(std::max(std::max(fabs(minz), fabs(maxz)),
std::max(std::max(fabs(minx), fabs(maxx)),
std::max(fabs(miny), fabs(maxy)))));
}
rescale(double minx, double miny, double minz, double maxx, double maxy, double maxz) {
init(minx, miny, minz, maxx, maxy, maxz);
}
rescale(const carve::geom3d::Vector &min, const carve::geom3d::Vector &max) {
init(min.x, min.y, min.z, max.x, max.y, max.z);
}
};
struct fwd {
rescale r;
fwd(const rescale &_r) : r(_r) { }
carve::geom3d::Vector operator()(const carve::geom3d::Vector &v) const { return carve::geom::VECTOR((v.x - r.dx) / r.scale, (v.y - r.dy) / r.scale, (v.z - r.dz) / r.scale); }
};
struct rev {
rescale r;
rev(const rescale &_r) : r(_r) { }
carve::geom3d::Vector operator()(const carve::geom3d::Vector &v) const { return carve::geom::VECTOR((v.x * r.scale) + r.dx, (v.y * r.scale) + r.dy, (v.z * r.scale) + r.dz); }
};
}
}

514
extern/carve/include/carve/rtree.hpp vendored Normal file
View File

@@ -0,0 +1,514 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom.hpp>
#include <carve/aabb.hpp>
#include <iostream>
#include <cmath>
#include <limits>
#if defined(HAVE_STDINT_H)
# include <stdint.h>
#endif
namespace carve {
namespace geom {
template<unsigned ndim,
typename data_t,
typename aabb_calc_t = carve::geom::get_aabb<ndim, data_t> >
struct RTreeNode {
typedef aabb<ndim> aabb_t;
typedef vector<ndim> vector_t;
typedef RTreeNode<ndim, data_t, aabb_calc_t> node_t;
aabb_t bbox;
node_t *child;
node_t *sibling;
std::vector<data_t> data;
aabb_t getAABB() const { return bbox; }
struct data_aabb_t {
aabb_t bbox;
data_t data;
data_aabb_t() { }
data_aabb_t(const data_t &_data) : bbox(aabb_calc_t()(_data)), data(_data) {
}
aabb_t getAABB() const { return bbox; }
struct cmp {
size_t dim;
cmp(size_t _dim) : dim(_dim) { }
bool operator()(const data_aabb_t &a, const data_aabb_t &b) {
return a.bbox.pos.v[dim] < b.bbox.pos.v[dim];
}
};
};
// Fill an rtree node with a set of (data, aabb) pairs.
template<typename iter_t>
void _fill(iter_t begin, iter_t end, data_aabb_t) {
data.reserve(std::distance(begin, end));
for (iter_t i = begin; i != end; ++i) {
data.push_back((*i).data);
}
bbox.fit(begin, end);
}
// Fill an rtree node with a set of data.
template<typename iter_t>
void _fill(iter_t begin, iter_t end, data_t) {
data.reserve(std::distance(begin, end));
std::copy(begin, end, std::back_inserter(data));
bbox.fit(begin, end, aabb_calc_t());
}
// Fill an rtree node with a set of child nodes.
template<typename iter_t>
void _fill(iter_t begin, iter_t end, node_t *) {
iter_t i = begin;
node_t *curr = child = *i;
while (++i != end) {
curr->sibling = *i;
curr = curr->sibling;
}
bbox.fit(begin, end);
}
// Search the rtree for objects that intersect obj (generally an aabb).
// The aabb class must provide a method intersects(obj_t).
template<typename obj_t, typename out_iter_t>
void search(const obj_t &obj, out_iter_t out) const {
if (!bbox.intersects(obj)) return;
if (child) {
for (node_t *node = child; node; node = node->sibling) {
node->search(obj, out);
}
} else {
std::copy(data.begin(), data.end(), out);
}
}
// update the bounding box extents of nodes that intersect obj (generally an aabb).
// The aabb class must provide a method intersects(obj_t).
template<typename obj_t>
void updateExtents(const obj_t &obj) {
if (!bbox.intersects(obj)) return;
if (child) {
node_t *node = child;
node->updateExtents(obj);
bbox = node->bbox;
for (node = node->sibling; node; node = node->sibling) {
node->updateExtents(obj);
bbox.unionAABB(node->bbox);
}
} else {
bbox.fit(data.begin(), data.end());
}
}
// update the bounding box extents of nodes that intersect obj (generally an aabb).
// The aabb class must provide a method intersects(obj_t).
bool remove(const data_t &val, const aabb_t &val_aabb) {
if (!bbox.intersects(val_aabb)) return false;
if (child) {
node_t *node = child;
node->remove(val, val_aabb);
bbox = node->bbox;
bool removed = false;
for (node = node->sibling; node; node = node->sibling) {
if (!removed) removed = node->remove(val, val_aabb);
bbox.unionAABB(node->bbox);
}
return removed;
} else {
typename std::vector<data_t>::iterator i = std::remove(data.begin(), data.end(), val);
if (i == data.end()) {
return false;
}
data.erase(i, data.end());
bbox.fit(data.begin(), data.end());
return true;
}
}
template<typename iter_t>
RTreeNode(iter_t begin, iter_t end) : bbox(), child(NULL), sibling(NULL), data() {
_fill(begin, end, typename std::iterator_traits<iter_t>::value_type());
}
~RTreeNode() {
if (child) {
RTreeNode *next = child;
while (next) {
RTreeNode *curr = next;
next = next->sibling;
delete curr;
}
}
}
// functor for ordering nodes by increasing aabb midpoint, along a specified axis.
struct aabb_cmp_mid {
size_t dim;
aabb_cmp_mid(size_t _dim) : dim(_dim) { }
bool operator()(const node_t *a, const node_t *b) {
return a->bbox.mid(dim) < b->bbox.mid(dim);
}
bool operator()(const data_aabb_t &a, const data_aabb_t &b) {
return a.bbox.mid(dim) < b.bbox.mid(dim);
}
};
// functor for ordering nodes by increasing aabb minimum, along a specified axis.
struct aabb_cmp_min {
size_t dim;
aabb_cmp_min(size_t _dim) : dim(_dim) { }
bool operator()(const node_t *a, const node_t *b) {
return a->bbox.min(dim) < b->bbox.min(dim);
}
bool operator()(const data_aabb_t &a, const data_aabb_t &b) {
return a.bbox.min(dim) < b.bbox.min(dim);
}
};
// functor for ordering nodes by increasing aabb maximum, along a specified axis.
struct aabb_cmp_max {
size_t dim;
aabb_cmp_max(size_t _dim) : dim(_dim) { }
bool operator()(const node_t *a, const node_t *b) {
return a->bbox.max(dim) < b->bbox.max(dim);
}
bool operator()(const data_aabb_t &a, const data_aabb_t &b) {
return a.bbox.max(dim) < b.bbox.max(dim);
}
};
// facade for projecting node bounding box onto an axis.
struct aabb_extent {
size_t dim;
aabb_extent(size_t _dim) : dim(_dim) { }
double min(const node_t *a) { return a->bbox.pos.v[dim] - a->bbox.extent.v[dim]; }
double max(const node_t *a) { return a->bbox.pos.v[dim] + a->bbox.extent.v[dim]; }
double len(const node_t *a) { return 2.0 * a->bbox.extent.v[dim]; }
double min(const data_aabb_t &a) { return a.bbox.pos.v[dim] - a.bbox.extent.v[dim]; }
double max(const data_aabb_t &a) { return a.bbox.pos.v[dim] + a.bbox.extent.v[dim]; }
double len(const data_aabb_t &a) { return 2.0 * a.bbox.extent.v[dim]; }
};
template<typename iter_t>
static void makeNodes(const iter_t begin,
const iter_t end,
size_t dim_num,
uint32_t dim_mask,
size_t child_size,
std::vector<node_t *> &out) {
const size_t N = std::distance(begin, end);
size_t dim = ndim;
double r_best = N+1;
// find the sparsest remaining dimension to partition by.
for (size_t i = 0; i < ndim; ++i) {
if (dim_mask & (1U << i)) continue;
aabb_extent extent(i);
double dmin, dmax, dsum;
dmin = extent.min(*begin);
dmax = extent.max(*begin);
dsum = 0.0;
for (iter_t j = begin; j != end; ++j) {
dmin = std::min(dmin, extent.min(*j));
dmax = std::max(dmax, extent.max(*j));
dsum += extent.len(*j);
}
double r = dsum ? dsum / (dmax - dmin) : 0.0;
if (r_best > r) {
dim = i;
r_best = r;
}
}
CARVE_ASSERT(dim < ndim);
// dim = dim_num;
const size_t P = (N + child_size - 1) / child_size;
const size_t n_parts = (size_t)std::ceil(std::pow((double)P, 1.0 / (ndim - dim_num)));
std::sort(begin, end, aabb_cmp_mid(dim));
if (dim_num == ndim - 1 || n_parts == 1) {
for (size_t i = 0, s = 0, e = 0; i < P; ++i, s = e) {
e = N * (i+1) / P;
CARVE_ASSERT(e - s <= child_size);
out.push_back(new node_t(begin + s, begin + e));
}
} else {
for (size_t i = 0, s = 0, e = 0; i < n_parts; ++i, s = e) {
e = N * (i+1) / n_parts;
makeNodes(begin + s, begin + e, dim_num + 1, dim_mask | (1U << dim), child_size, out);
}
}
}
static node_t *construct_STR(std::vector<data_aabb_t> &data, size_t leaf_size, size_t internal_size) {
std::vector<node_t *> out;
makeNodes(data.begin(), data.end(), 0, 0, leaf_size, out);
while (out.size() > 1) {
std::vector<node_t *> next;
makeNodes(out.begin(), out.end(), 0, 0, internal_size, next);
std::swap(out, next);
}
CARVE_ASSERT(out.size() == 1);
return out[0];
}
template<typename iter_t>
static node_t *construct_STR(const iter_t &begin,
const iter_t &end,
size_t leaf_size,
size_t internal_size) {
std::vector<data_aabb_t> data;
data.reserve(std::distance(begin, end));
for (iter_t i = begin; i != end; ++i) {
data.push_back(*i);
}
return construct_STR(data, leaf_size, internal_size);
}
template<typename iter_t>
static node_t *construct_STR(const iter_t &begin1,
const iter_t &end1,
const iter_t &begin2,
const iter_t &end2,
size_t leaf_size,
size_t internal_size) {
std::vector<data_aabb_t> data;
data.reserve(std::distance(begin1, end1) + std::distance(begin2, end2));
for (iter_t i = begin1; i != end1; ++i) {
data.push_back(*i);
}
for (iter_t i = begin2; i != end2; ++i) {
data.push_back(*i);
}
return construct_STR(data, leaf_size, internal_size);
}
struct partition_info {
double score;
size_t partition_pos;
partition_info() : score(std::numeric_limits<double>::max()), partition_pos(0) {
}
partition_info(double _score, size_t _partition_pos) :
score(_score),
partition_pos(_partition_pos) {
}
};
static partition_info findPartition(typename std::vector<data_aabb_t>::iterator base,
std::vector<size_t>::iterator begin,
std::vector<size_t>::iterator end,
size_t part_size) {
CARVE_ASSERT(begin < end);
partition_info best(std::numeric_limits<double>::max(), 0);
const size_t N = (size_t)std::distance(begin, end);
std::vector<double> rhs_vol(N, 0.0);
aabb_t rhs = base[begin[N-1]].aabb;
rhs_vol[N-1] = rhs.volume();
for (size_t i = N - 1; i > 0; ) {
rhs.unionAABB(base[begin[--i]].aabb);
rhs_vol[i] = rhs.volume();
}
aabb_t lhs = base[begin[0]].aabb;
for (size_t i = 1; i < N; ++i) {
lhs.unionAABB(base[begin[i]].aabb);
if (i % part_size == 0 || (N - i) % part_size == 0) {
partition_info curr(lhs.volume() + rhs_vol[i], i);
if (best.score > curr.score) best = curr;
}
}
return best;
}
static void partition(typename std::vector<data_aabb_t>::iterator base,
std::vector<size_t>::iterator begin,
std::vector<size_t>::iterator end,
size_t part_size,
std::vector<size_t> &part_num,
size_t &part_next) {
CARVE_ASSERT(begin < end);
const size_t N = (size_t)std::distance(begin, end);
partition_info best;
partition_info curr;
size_t part_curr = part_num[*begin];
std::vector<size_t> tmp(begin, end);
for (size_t dim = 0; dim < ndim; ++dim) {
std::sort(tmp.begin(), tmp.end(), make_index_sort(base, aabb_cmp_min(dim)));
curr = findPartition(base, tmp.begin(), tmp.end(), part_size);
if (best.score > curr.score) {
best = curr;
std::copy(tmp.begin(), tmp.end(), begin);
}
std::sort(tmp.begin(), tmp.end(), make_index_sort(base, aabb_cmp_mid(dim)));
curr = findPartition(base, tmp.begin(), tmp.end(), part_size);
if (best.score > curr.score) {
best = curr;
std::copy(tmp.begin(), tmp.end(), begin);
}
std::sort(tmp.begin(), tmp.end(), make_index_sort(base, aabb_cmp_max(dim)));
curr = findPartition(base, tmp.begin(), tmp.end(), part_size);
if (best.score > curr.score) {
best = curr;
std::copy(tmp.begin(), tmp.end(), begin);
}
}
for (size_t j = 0; j < best.partition_pos; ++j) part_num[begin[(ssize_t)j]] = part_curr;
for (size_t j = best.partition_pos; j < N; ++j) part_num[begin[(ssize_t)j]] = part_next;
++part_next;
if (best.partition_pos > part_size) {
partition(base, begin, begin + best.partition_pos, part_size, part_num, part_next);
}
if (N - best.partition_pos > part_size) {
partition(base, begin + best.partition_pos, end, part_size, part_num, part_next);
}
}
static size_t makePartitions(typename std::vector<data_aabb_t>::iterator begin,
typename std::vector<data_aabb_t>::iterator end,
size_t part_size,
std::vector<size_t> &part_num) {
const size_t N = std::distance(begin, end);
std::vector<size_t> idx;
idx.reserve(N);
for (size_t i = 0; i < N; ++i) { idx.push_back(i); }
size_t part_next = 1;
partition(begin, idx.begin(), idx.end(), part_size, part_num, part_next);
return part_next;
}
static node_t *construct_TGS(typename std::vector<data_aabb_t>::iterator begin,
typename std::vector<data_aabb_t>::iterator end,
size_t leaf_size,
size_t internal_size) {
size_t N = std::distance(begin, end);
if (N <= leaf_size) {
return new node_t(begin, end);
} else {
size_t P = (N + internal_size - 1) / internal_size;
std::vector<size_t> part_num(N, 0);
P = makePartitions(begin, end, P, part_num);
size_t S = 0, E = 0;
std::vector<node_t *> children;
for (size_t i = 0; i < P; ++i) {
size_t j = S, k = N;
while (true) {
while (true) {
if (j == k) goto done;
else if (part_num[j] == i) ++j;
else break;
}
--k;
while (true) {
if (j == k) goto done;
else if (part_num[k] != i) --k;
else break;
}
std::swap(*(begin+j), *(begin+k));
std::swap(part_num[j], part_num[k]);
++j;
}
done:
E = j;
children.push_back(construct_TGS(begin + S, begin + E, leaf_size, internal_size));
S = E;
}
return new node_t(children.begin(), children.end());
}
}
template<typename iter_t>
static node_t *construct_TGS(const iter_t &begin,
const iter_t &end,
size_t leaf_size,
size_t internal_size) {
std::vector<data_aabb_t> data;
data.reserve(std::distance(begin, end));
for (iter_t i = begin; i != end; ++i) {
data.push_back(*i);
}
return construct_TGS(data.begin(), data.end(), leaf_size, internal_size);
}
template<typename iter_t>
static node_t *construct_TGS(const iter_t &begin1,
const iter_t &end1,
const iter_t &begin2,
const iter_t &end2,
size_t leaf_size,
size_t internal_size) {
std::vector<data_aabb_t> data;
data.reserve(std::distance(begin1, end1) + std::distance(begin2, end2));
for (iter_t i = begin1; i != end1; ++i) {
data.push_back(*i);
}
for (iter_t i = begin2; i != end2; ++i) {
data.push_back(*i);
}
return construct_TGS(data.begin(), data.end(), leaf_size, internal_size);
}
};
}
}

264
extern/carve/include/carve/spacetree.hpp vendored Normal file
View File

@@ -0,0 +1,264 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom.hpp>
#include <carve/aabb.hpp>
#include <carve/vertex_decl.hpp>
#include <carve/edge_decl.hpp>
#include <carve/face_decl.hpp>
namespace carve {
namespace space {
static inline bool intersection_test(const carve::geom::aabb<3> &aabb, const carve::poly::Face<3> *face) {
if (face->nVertices() == 3) {
return aabb.intersects(carve::geom::tri<3>(face->vertex(0)->v, face->vertex(1)->v, face->vertex(2)->v));
} else {
// partial, conservative SAT.
return aabb.intersects(face->aabb) && aabb.intersects(face->plane_eqn);
}
}
static inline bool intersection_test(const carve::geom::aabb<3> &aabb, const carve::poly::Edge<3> *edge) {
return aabb.intersectsLineSegment(edge->v1->v, edge->v2->v);
}
static inline bool intersection_test(const carve::geom::aabb<3> &aabb, const carve::poly::Vertex<3> *vertex) {
return aabb.intersects(vertex->v);
}
struct nodedata_FaceEdge {
std::vector<const carve::poly::Face<3> *> faces;
std::vector<const carve::poly::Edge<3> *> edges;
void add(const carve::poly::Face<3> *face) {
faces.push_back(face);
}
void add(const carve::poly::Edge<3> *edge) {
edges.push_back(edge);
}
template<typename iter_t>
void _fetch(iter_t &iter, const carve::poly::Edge<3> *) {
std::copy(edges.begin(), edges.end(), iter);
}
template<typename iter_t>
void _fetch(iter_t &iter, const carve::poly::Face<3> *) {
std::copy(faces.begin(), faces.end(), iter);
}
template<typename node_t>
void propagate(node_t *node) {
}
template<typename iter_t>
void fetch(iter_t &iter) {
return _fetch(iter, std::iterator_traits<iter_t>::value_type);
}
};
const static double SLACK_FACTOR = 1.0009765625;
const static unsigned MAX_SPLIT_DEPTH = 32;
template<unsigned n_dim, typename nodedata_t>
class SpatialSubdivTree {
typedef carve::geom::aabb<n_dim> aabb_t;
typedef carve::geom::vector<n_dim> vector_t;
public:
class Node {
enum {
n_children = 1 << n_dim
};
public:
Node *parent;
Node *children;
vector_t min;
vector_t max;
aabb_t aabb;
nodedata_t data;
private:
Node(const Node &node); // undefined.
Node &operator=(const Node &node); // undefined.
Node() {
}
inline aabb_t makeAABB() const {
vector_t centre = 0.5 * (min + max);
vector_t size = SLACK_FACTOR * 0.5 * (max - min);
return aabb_t(centre, size);
}
void setup(Node *_parent, const vector_t &_min, const vector_t &_max) {
parent = _parent;
min = _min;
max = _max;
aabb = makeAABB();
}
void alloc_children() {
vector_t mid = 0.5 * (min + max);
children = new Node[n_children];
for (size_t i = 0; i < (n_children); ++i) {
vector_t new_min, new_max;
for (size_t c = 0; c < n_dim; ++c) {
if (i & (1 << c)) {
new_min.v[c] = min.v[c];
new_max.v[c] = mid.v[c];
} else {
new_min.v[c] = mid.v[c];
new_max.v[c] = max.v[c];
}
}
children[i].setup(this, new_min, new_max);
}
}
void dealloc_children() {
delete [] children;
}
public:
inline bool isLeaf() const { return children == NULL; }
Node(Node *_parent, const vector_t &_min, const vector_t &_max) : parent(_parent), children(NULL), min(_min), max(_max) {
aabb = makeAABB();
}
~Node() {
dealloc_children();
}
bool split() {
if (isLeaf()) {
alloc_children();
data.propagate(this);
}
return isLeaf();
}
template<typename obj_t>
void insert(const obj_t &object) {
if (!isLeaf()) {
for (size_t i = 0; i < n_children; ++i) {
if (intersection_test(children[i].aabb, object)) {
children[i].insert(object);
}
}
} else {
data.add(object);
}
}
template<typename obj_t>
void insertVector(typename std::vector<obj_t>::iterator beg, typename std::vector<obj_t>::iterator end) {
if (isLeaf()) {
while (beg != end) {
data.add(*beg);
}
} else {
for (size_t i = 0; i < n_children; ++i) {
typename std::vector<obj_t>::iterator mid = std::partition(beg, end, std::bind1st(intersection_test, children[i].aabb));
children[i].insertVector(beg, mid);
}
}
}
template<typename iter_t>
void insertMany(iter_t begin, iter_t end) {
if (isLeaf()) {
}
}
template<typename obj_t, typename iter_t, typename filter_t>
void findObjectsNear(const obj_t &object, iter_t &output, filter_t filter) {
if (!isLeaf()) {
for (size_t i = 0; i < n_children; ++i) {
if (intersection_test(children[i].aabb, object)) {
children[i].findObjectsNear(object, output, filter);
}
}
return;
}
data.fetch(output);
}
// bool hasGeometry();
// template <class T>
// void putInside(const T &input, Node *child, T &output);
};
Node *root;
SpatialSubdivTree(const vector_t &_min, const vector_t &_max) : root(new Node(NULL, _min, _max)) {
}
~SpatialSubdivTree() {
delete root;
}
struct no_filter {
template<typename obj_t>
bool operator()(const obj_t &obj) const {
return true;
}
};
struct tag_filter {
template<typename obj_t>
bool operator()(const obj_t &obj) const {
return obj.tag_once();
}
};
// in order to be used as an input, aabb_t::intersect(const obj_t &) must exist.
template<typename obj_t, typename iter_t, typename filter_t>
void findObjectsNear(const obj_t &object, iter_t output, filter_t filter) {
if (!intersection_test(root->aabb, object)) return;
root->findObjectsNear(root, object, output, filter);
}
};
}
}

44
extern/carve/include/carve/tag.hpp vendored Normal file
View File

@@ -0,0 +1,44 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
namespace carve {
class tagable {
private:
static int s_count;
protected:
mutable int __tag;
public:
tagable(const tagable &) : __tag(s_count - 1) { }
tagable &operator=(const tagable &) { return *this; }
tagable() : __tag(s_count - 1) { }
void tag() const { __tag = s_count; }
void untag() const { __tag = s_count - 1; }
bool is_tagged() const { return __tag == s_count; }
bool tag_once() const { if (__tag == s_count) return false; __tag = s_count; return true; }
static void tag_begin() { s_count++; }
};
}

96
extern/carve/include/carve/timing.hpp vendored Normal file
View File

@@ -0,0 +1,96 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#ifndef CARVE_USE_TIMINGS
#define CARVE_USE_TIMINGS 0
#endif
namespace carve {
#if CARVE_USE_TIMINGS
class TimingName {
public:
TimingName(const char *name);
int id;
};
class TimingBlock {
public:
/**
* Starts timing at the end of this constructor, using the given ID. To
* associate an ID with a textual name, use Timing::registerID.
*/
TimingBlock(int id);
TimingBlock(const TimingName &name);
~TimingBlock();
};
class Timing {
public:
/**
* Starts timing against a particular ID.
*/
static void start(int id);
static void start(const TimingName &id) {
start(id.id);
}
/**
* Stops the most recent timing block.
*/
static double stop();
/**
* This will print out the current state of recorded time blocks. It will
* display the tree of timings, as well as the summaries down the bottom.
*/
static void printTimings();
/**
* Associates a particular ID with a text string. This is used when
* printing out the timings.
*/
static void registerID(int id, const char *name);
};
#else
struct TimingName {
TimingName(const char *) {}
};
struct TimingBlock {
TimingBlock(int /* id */) {}
TimingBlock(const TimingName & /* name */) {}
};
struct Timing {
static void start(int /* id */) {}
static void start(const TimingName & /* id */) {}
static double stop() { return 0; }
static void printTimings() {}
static void registerID(int /* id */, const char * /* name */) {}
};
#endif
}

324
extern/carve/include/carve/tree.hpp vendored Normal file
View File

@@ -0,0 +1,324 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/matrix.hpp>
#include <carve/timing.hpp>
#include <carve/rescale.hpp>
namespace carve {
namespace csg {
class CSG_TreeNode {
CSG_TreeNode(const CSG_TreeNode &);
CSG_TreeNode &operator=(const CSG_TreeNode &);
protected:
public:
CSG_TreeNode() {
}
virtual ~CSG_TreeNode() {
}
virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) =0;
virtual carve::mesh::MeshSet<3> *eval(CSG &csg) {
bool temp;
carve::mesh::MeshSet<3> *r = eval(temp, csg);
if (!temp) r = r->clone();
return r;
}
};
class CSG_TransformNode : public CSG_TreeNode {
carve::math::Matrix transform;
CSG_TreeNode *child;
public:
CSG_TransformNode(const carve::math::Matrix &_transform, CSG_TreeNode *_child) : transform(_transform), child(_child) {
}
virtual ~CSG_TransformNode() {
delete child;
}
virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) {
carve::mesh::MeshSet<3> *result = child->eval(is_temp, csg);
if (!is_temp) {
result = result->clone();
is_temp = true;
}
result->transform(carve::math::matrix_transformation(transform));
return result;
}
};
class CSG_InvertNode : public CSG_TreeNode {
std::vector<bool> selected_meshes;
CSG_TreeNode *child;
public:
CSG_InvertNode(CSG_TreeNode *_child) : selected_meshes(), child(_child) {
}
CSG_InvertNode(int g_id, CSG_TreeNode *_child) : selected_meshes(), child(_child) {
selected_meshes.resize(g_id + 1, false);
selected_meshes[g_id] = true;
}
virtual ~CSG_InvertNode() {
delete child;
}
template<typename T>
CSG_InvertNode(T start, T end, CSG_TreeNode *_child) : selected_meshes(), child(_child) {
while (start != end) {
int g_id = (int)(*start);
if (selected_meshes.size() < g_id + 1) selected_meshes.resize(g_id + 1, false);
selected_meshes[g_id] = true;
++start;
}
}
virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) {
bool c_temp;
carve::mesh::MeshSet<3> *c = child->eval(c_temp, csg);
if (!c_temp) c = c->clone();
if (!selected_meshes.size()) {
c->invert();
} else {
for (size_t i = 0; i < c->meshes.size() && i < selected_meshes.size(); ++i) {
if (selected_meshes[i]) {
c->meshes[i]->invert();
}
}
}
is_temp = true;
return c;
}
};
class CSG_SelectNode : public CSG_TreeNode {
std::vector<bool> selected_meshes;
CSG_TreeNode *child;
public:
CSG_SelectNode(int m_id, CSG_TreeNode *_child) : selected_meshes(), child(_child) {
selected_meshes.resize(m_id + 1, false);
selected_meshes[m_id] = true;
}
template<typename T>
CSG_SelectNode(T start, T end, CSG_TreeNode *_child) : selected_meshes(), child(_child) {
while (start != end) {
int m_id = (int)(*start);
if ((int)selected_meshes.size() < m_id + 1) selected_meshes.resize(m_id + 1, false);
selected_meshes[m_id] = true;
++start;
}
}
virtual ~CSG_SelectNode() {
delete child;
}
virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) {
bool c_temp;
carve::mesh::MeshSet<3> *c = child->eval(c_temp, csg);
if (!c_temp) c = c->clone();
size_t i = 0;
size_t j = 0;
for (size_t i = 0; i < c->meshes.size(); ++i) {
if (i >= selected_meshes.size() || !selected_meshes[i]) {
delete c->meshes[i];
c->meshes[i] = NULL;
} else {
c->meshes[j++] = c->meshes[i];
}
}
c->meshes.erase(c->meshes.begin() + j, c->meshes.end());
c->collectVertices();
is_temp = true;
return c;
}
};
class CSG_PolyNode : public CSG_TreeNode {
carve::mesh::MeshSet<3> *poly;
bool del;
public:
CSG_PolyNode(carve::mesh::MeshSet<3> *_poly, bool _del) : poly(_poly), del(_del) {
}
virtual ~CSG_PolyNode() {
static carve::TimingName FUNC_NAME("delete polyhedron");
carve::TimingBlock block(FUNC_NAME);
if (del) {
delete poly;
}
}
virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) {
is_temp = false;
return poly;
}
};
class CSG_OPNode : public CSG_TreeNode {
CSG_TreeNode *left, *right;
CSG::OP op;
bool rescale;
CSG::CLASSIFY_TYPE classify_type;
public:
CSG_OPNode(CSG_TreeNode *_left,
CSG_TreeNode *_right,
CSG::OP _op,
bool _rescale,
CSG::CLASSIFY_TYPE _classify_type = CSG::CLASSIFY_NORMAL) : left(_left), right(_right), op(_op), rescale(_rescale), classify_type(_classify_type) {
}
virtual ~CSG_OPNode() {
delete left;
delete right;
}
void minmax(double &min_x, double &min_y, double &min_z,
double &max_x, double &max_y, double &max_z,
const std::vector<carve::geom3d::Vector> &points) {
for (unsigned i = 1; i < points.size(); ++i) {
min_x = std::min(min_x, points[i].x);
max_x = std::max(max_x, points[i].x);
min_y = std::min(min_y, points[i].y);
max_y = std::max(max_y, points[i].y);
min_z = std::min(min_z, points[i].z);
max_z = std::max(max_z, points[i].z);
}
}
virtual carve::mesh::MeshSet<3> *evalScaled(bool &is_temp, CSG &csg) {
carve::mesh::MeshSet<3> *l, *r;
bool l_temp, r_temp;
l = left->eval(l_temp, csg);
r = right->eval(r_temp, csg);
if (!l_temp) { l = l->clone(); }
if (!r_temp) { r = r->clone(); }
carve::geom3d::Vector min, max;
carve::geom3d::Vector min_l, max_l;
carve::geom3d::Vector min_r, max_r;
carve::geom::bounds<3>(l->vertex_storage.begin(),
l->vertex_storage.end(),
carve::mesh::Face<3>::vector_mapping(),
min_l,
max_l);
carve::geom::bounds<3>(r->vertex_storage.begin(),
r->vertex_storage.end(),
carve::mesh::Face<3>::vector_mapping(),
min_r,
max_r);
carve::geom::assign_op(min, min_l, min_r, carve::util::min_functor());
carve::geom::assign_op(max, max_l, max_r, carve::util::max_functor());
carve::rescale::rescale scaler(min.x, min.y, min.z, max.x, max.y, max.z);
carve::rescale::fwd fwd_r(scaler);
carve::rescale::rev rev_r(scaler);
l->transform(fwd_r);
r->transform(fwd_r);
carve::mesh::MeshSet<3> *result = NULL;
{
static carve::TimingName FUNC_NAME("csg.compute()");
carve::TimingBlock block(FUNC_NAME);
result = csg.compute(l, r, op, NULL, classify_type);
}
{
static carve::TimingName FUNC_NAME("delete polyhedron");
carve::TimingBlock block(FUNC_NAME);
delete l;
delete r;
}
result->transform(rev_r);
is_temp = true;
return result;
}
virtual carve::mesh::MeshSet<3> *evalUnscaled(bool &is_temp, CSG &csg) {
carve::mesh::MeshSet<3> *l, *r;
bool l_temp, r_temp;
l = left->eval(l_temp, csg);
r = right->eval(r_temp, csg);
carve::mesh::MeshSet<3> *result = NULL;
{
static carve::TimingName FUNC_NAME("csg.compute()");
carve::TimingBlock block(FUNC_NAME);
result = csg.compute(l, r, op, NULL, classify_type);
}
{
static carve::TimingName FUNC_NAME("delete polyhedron");
carve::TimingBlock block(FUNC_NAME);
if (l_temp) delete l;
if (r_temp) delete r;
}
is_temp = true;
return result;
}
virtual carve::mesh::MeshSet<3> *eval(bool &is_temp, CSG &csg) {
if (rescale) {
return evalScaled(is_temp, csg);
} else {
return evalUnscaled(is_temp, csg);
}
}
};
}
}

View File

@@ -0,0 +1,53 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom.hpp>
namespace carve {
namespace geom {
enum TriangleIntType {
TR_TYPE_NONE = 0,
TR_TYPE_TOUCH = 1,
TR_TYPE_INT = 2
};
enum TriangleInt {
TR_INT_NONE = 0, // no intersection.
TR_INT_INT = 1, // intersection.
TR_INT_VERT = 2, // intersection due to shared vertex.
TR_INT_EDGE = 3, // intersection due to shared edge.
TR_INT_TRI = 4 // intersection due to identical triangle.
};
TriangleInt triangle_intersection(const vector<2> tri_a[3], const vector<2> tri_b[3]);
TriangleInt triangle_intersection(const vector<3> tri_a[3], const vector<3> tri_b[3]);
bool triangle_intersection_simple(const vector<2> tri_a[3], const vector<2> tri_b[3]);
bool triangle_intersection_simple(const vector<3> tri_a[3], const vector<3> tri_b[3]);
TriangleIntType triangle_intersection_exact(const vector<2> tri_a[3], const vector<2> tri_b[3]);
TriangleIntType triangle_intersection_exact(const vector<3> tri_a[3], const vector<3> tri_b[3]);
TriangleIntType triangle_linesegment_intersection_exact(const vector<2> tri_a[3], const vector<2> line_b[2]);
TriangleIntType triangle_point_intersection_exact(const vector<2> tri_a[3], const vector<2> &pt_b);
}
}

View File

@@ -0,0 +1,175 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <list>
#include <vector>
#include <algorithm>
#include <carve/carve.hpp>
#include <carve/geom2d.hpp>
namespace carve {
namespace triangulate {
/**
* \brief Merge a set of holes into a polygon. (templated)
*
* Take a polygon loop and a collection of hole loops, and patch
* the hole loops into the polygon loop, returning a vector of
* vertices from the polygon and holes, which describes a new
* polygon boundary with no holes. The new polygon boundary is
* constructed via the addition of edges * joining the polygon
* loop to the holes.
*
* This may be applied to arbitrary vertex data (generally
* carve::geom3d::Vertex pointers), but a projection function must
* be supplied to convert vertices to coordinates in 2-space, in
* which the work is performed.
*
* @tparam project_t A functor which converts vertices to a 2d
* projection.
* @tparam vert_t The vertex type.
* @param project The projection functor.
* @param f_loop The polygon loop into which holes are to be
* incorporated.
* @param h_loops The set of hole loops to be incorporated.
*
* @return A vector of vertex pointers.
*/
template<typename project_t, typename vert_t>
static std::vector<vert_t>
incorporateHolesIntoPolygon(const project_t &project,
const std::vector<vert_t> &f_loop,
const std::vector<std::vector<vert_t> > &h_loops);
void
incorporateHolesIntoPolygon(const std::vector<std::vector<carve::geom2d::P2> > &poly,
std::vector<std::pair<size_t, size_t> > &result,
size_t poly_loop,
const std::vector<size_t> &hole_loops);
/**
* \brief Merge a set of holes into a polygon. (2d)
*
* Take a polygon loop and a collection of hole loops, and patch
* the hole loops into the polygon loop, returning a vector of
* containing the vertices from the polygon and holes which
* describes a new polygon boundary with no holes, through the
* addition of edges joining the polygon loop to the holes.
*
* @param poly A vector containing the face loop (the first
* element of poly) and the hole loops (second and
* subsequent elements of poly).
*
* @return A vector of pairs of <loop_number, index> that
* reference poly and define the result polygon loop.
*/
std::vector<std::pair<size_t, size_t> > incorporateHolesIntoPolygon(const std::vector<std::vector<carve::geom2d::P2> > &poly);
std::vector<std::vector<std::pair<size_t, size_t> > > mergePolygonsAndHoles(const std::vector<std::vector<carve::geom2d::P2> > &poly);
struct tri_idx {
union {
unsigned v[3];
struct { unsigned a, b, c; };
};
tri_idx() : a(0), b(0), c(0) {
}
tri_idx(unsigned _a, unsigned _b, unsigned _c) : a(_a), b(_b), c(_c) {
}
};
/**
* \brief Triangulate a 2-dimensional polygon.
*
* Given a 2-dimensional polygon described as a vector of 2-d
* points, with no holes and no self-crossings, produce a
* triangulation using an ear-clipping algorithm.
*
* @param [in] poly A vector containing the input polygon.
* @param [out] result A vector of triangles, represented as
* indicies into poly.
*/
void triangulate(const std::vector<carve::geom2d::P2> &poly, std::vector<tri_idx> &result);
/**
* \brief Triangulate a polygon (templated).
*
* @tparam project_t A functor which converts vertices to a 2d
* projection.
* @tparam vert_t The vertex type.
* @param [in] project The projection functor.
* @param [in] poly A vector containing the input polygon,
* represented as vert_t pointers.
* @param [out] result A vector of triangles, represented as
* indicies into poly.
*/
template<typename project_t, typename vert_t>
void triangulate(const project_t &project,
const std::vector<vert_t> &poly,
std::vector<tri_idx> &result);
/**
* \brief Improve a candidate triangulation of poly by minimising
* the length of internal edges. (templated)
*
* @tparam project_t A functor which converts vertices to a 2d
* projection.
* @tparam vert_t The vertex type.
* @param [in] project The projection functor.
* @param [in] poly A vector containing the input polygon,
* represented as vert_t pointers.
* @param [inout] result A vector of triangles, represented as
* indicies into poly. On input, this vector
* must contain a candidate triangulation of
* poly. Calling improve() modifies the
* contents of the vector, returning an
* improved triangulation.
*/
template<typename project_t, typename vert_t>
void improve(const project_t &project,
const std::vector<vert_t> &poly,
std::vector<tri_idx> &result);
/**
* \brief Improve a candidate triangulation of poly by minimising
* the length of internal edges.
*
* @param [in] poly A vector containing the input polygon.
* @param [inout] result A vector of triangles, represented as
* indicies into poly. On input, this vector
* must contain a candidate triangulation of
* poly. Calling improve() modifies the
* contents of the vector, returning an
* improved triangulation.
*/
static inline void improve(const std::vector<carve::geom2d::P2> &poly, std::vector<tri_idx> &result) {
improve(carve::geom2d::p2_adapt_ident(), poly, result);
}
}
}
#include <carve/triangulator_impl.hpp>

View File

@@ -0,0 +1,851 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/geom2d.hpp>
#if defined(CARVE_DEBUG)
# include <iostream>
#endif
namespace carve {
namespace triangulate {
namespace detail {
static inline bool axisOrdering(const carve::geom2d::P2 &a,
const carve::geom2d::P2 &b,
int axis) {
return a.v[axis] < b.v[axis] || (a.v[axis] == b.v[axis] && a.v[1-axis] < b.v[1-axis]);
}
/**
* \class order_h_loops
* \brief Provides an ordering of hole loops based upon a single
* projected axis.
*
* @tparam project_t A functor which converts vertices to a 2d
* projection.
* @tparam hole_t A collection of vertices.
*/
template<typename project_t, typename vert_t>
class order_h_loops {
const project_t &project;
int axis;
public:
/**
*
* @param _project The projection functor.
* @param _axis The axis of the 2d projection upon which hole
* loops are ordered.
*/
order_h_loops(const project_t &_project, int _axis) : project(_project), axis(_axis) { }
bool operator()(const vert_t &a,
const vert_t &b) const {
return axisOrdering(project(a), project(b), axis);
}
bool operator()(
const std::pair<const typename std::vector<vert_t> *, typename std::vector<vert_t>::const_iterator> &a,
const std::pair<const typename std::vector<vert_t> *, typename std::vector<vert_t>::const_iterator> &b) {
return axisOrdering(project(*(a.second)), project(*(b.second)), axis);
}
};
/**
* \class heap_ordering
* \brief Provides an ordering of vertex indicies in a polygon
* loop according to proximity to a vertex.
*
* @tparam project_t A functor which converts vertices to a 2d
* projection.
* @tparam vert_t A vertex type.
*/
template<typename project_t, typename vert_t>
class heap_ordering {
const project_t &project;
const std::vector<vert_t> &loop;
const carve::geom2d::P2 p;
int axis;
public:
/**
*
* @param _project A functor which converts vertices to a 2d
* projection.
* @param _loop The polygon loop which indices address.
* @param _vert The vertex from which distance is measured.
*
*/
heap_ordering(const project_t &_project,
const std::vector<vert_t> &_loop,
vert_t _vert,
int _axis) :
project(_project),
loop(_loop),
p(_project(_vert)),
axis(_axis) {
}
bool operator()(size_t a, size_t b) const {
carve::geom2d::P2 pa = project(loop[a]);
carve::geom2d::P2 pb = project(loop[b]);
double da = carve::geom::distance2(p, pa);
double db = carve::geom::distance2(p, pb);
if (da > db) return true;
if (da < db) return false;
return axisOrdering(pa, pb, axis);
}
};
/**
* \brief Given a polygon loop and a hole loop, and attachment
* points, insert the hole loop vertices into the polygon loop.
*
* @param[in,out] f_loop The polygon loop to incorporate the
* hole into.
* @param f_loop_attach[in] The index of the vertex of the
* polygon loop that the hole is to be
* attached to.
* @param hole_attach[in] A pair consisting of a pointer to a
* hole container and an iterator into
* that container reflecting the point of
* attachment of the hole.
*/
template<typename vert_t>
void patchHoleIntoPolygon(std::vector<vert_t> &f_loop,
unsigned f_loop_attach,
const std::pair<const std::vector<vert_t> *,
typename std::vector<vert_t>::const_iterator> &hole_attach) {
// join the vertex curr of the polygon loop to the hole at
// h_loop_connect
f_loop.insert(f_loop.begin() + f_loop_attach + 1, hole_attach.first->size() + 2, NULL);
typename std::vector<vert_t>::iterator f = f_loop.begin() + f_loop_attach;
typename std::vector<vert_t>::const_iterator h = hole_attach.second;
while (h != hole_attach.first->end()) {
*++f = *h++;
}
h = hole_attach.first->begin();
typename std::vector<vert_t>::const_iterator he = hole_attach.second; ++he;
while (h != he) {
*++f = *h++;
}
*++f = f_loop[f_loop_attach];
}
struct vertex_info;
/**
* \brief Determine whether c is to the left of a->b.
*/
static inline bool isLeft(const vertex_info *a,
const vertex_info *b,
const vertex_info *c);
/**
* \brief Determine whether d is contained in the triangle abc.
*/
static inline bool pointInTriangle(const vertex_info *a,
const vertex_info *b,
const vertex_info *c,
const vertex_info *d);
/**
* \class vertex_info
* \brief Maintains a linked list of untriangulated vertices
* during a triangulation operation.
*/
struct vertex_info {
vertex_info *prev;
vertex_info *next;
carve::geom2d::P2 p;
size_t idx;
double score;
bool convex;
bool failed;
vertex_info(const carve::geom2d::P2 &_p, size_t _idx) :
prev(NULL), next(NULL),
p(_p), idx(_idx),
score(0.0), convex(false) {
}
static double triScore(const vertex_info *p, const vertex_info *v, const vertex_info *n);
double calcScore() const;
void recompute() {
score = calcScore();
convex = isLeft(prev, this, next);
failed = false;
}
bool isCandidate() const {
return convex && !failed;
}
void remove() {
next->prev = prev;
prev->next = next;
}
bool isClipable() const;
};
static inline bool isLeft(const vertex_info *a,
const vertex_info *b,
const vertex_info *c) {
if (a->idx < b->idx && b->idx < c->idx) {
return carve::geom2d::orient2d(a->p, b->p, c->p) > 0.0;
} else if (a->idx < c->idx && c->idx < b->idx) {
return carve::geom2d::orient2d(a->p, c->p, b->p) < 0.0;
} else if (b->idx < a->idx && a->idx < c->idx) {
return carve::geom2d::orient2d(b->p, a->p, c->p) < 0.0;
} else if (b->idx < c->idx && c->idx < a->idx) {
return carve::geom2d::orient2d(b->p, c->p, a->p) > 0.0;
} else if (c->idx < a->idx && a->idx < b->idx) {
return carve::geom2d::orient2d(c->p, a->p, b->p) > 0.0;
} else {
return carve::geom2d::orient2d(c->p, b->p, a->p) < 0.0;
}
}
static inline bool pointInTriangle(const vertex_info *a,
const vertex_info *b,
const vertex_info *c,
const vertex_info *d) {
return !isLeft(a, c, d) && !isLeft(b, a, d) && !isLeft(c, b, d);
}
size_t removeDegeneracies(vertex_info *&begin, std::vector<carve::triangulate::tri_idx> &result);
bool splitAndResume(vertex_info *begin, std::vector<carve::triangulate::tri_idx> &result);
bool doTriangulate(vertex_info *begin, std::vector<carve::triangulate::tri_idx> &result);
typedef std::pair<unsigned, unsigned> vert_edge_t;
struct hash_vert_edge_t {
size_t operator()(const vert_edge_t &e) const {
size_t r = (size_t)e.first;
size_t s = (size_t)e.second;
return r ^ ((s >> 16) | (s << 16));
}
};
static inline vert_edge_t ordered_vert_edge_t(unsigned a, unsigned b) {
return (a < b) ? vert_edge_t(a, b) : vert_edge_t(b, a);
}
struct tri_pair_t {
carve::triangulate::tri_idx *a, *b;
double score;
size_t idx;
tri_pair_t() : a(NULL), b(NULL), score(0.0) {
}
static inline unsigned N(unsigned i) { return (i+1)%3; }
static inline unsigned P(unsigned i) { return (i+2)%3; }
void findSharedEdge(unsigned &ai, unsigned &bi) const {
if (a->v[1] == b->v[0]) { if (a->v[0] == b->v[1]) { ai = 0; bi = 0; } else { ai = 1; bi = 2; } return; }
if (a->v[1] == b->v[1]) { if (a->v[0] == b->v[2]) { ai = 0; bi = 1; } else { ai = 1; bi = 0; } return; }
if (a->v[1] == b->v[2]) { if (a->v[0] == b->v[0]) { ai = 0; bi = 2; } else { ai = 1; bi = 1; } return; }
if (a->v[2] == b->v[0]) { ai = 2; bi = 2; return; }
if (a->v[2] == b->v[1]) { ai = 2; bi = 0; return; }
if (a->v[2] == b->v[2]) { ai = 2; bi = 1; return; }
CARVE_FAIL("should not be reached");
}
void flip(vert_edge_t &old_edge,
vert_edge_t &new_edge,
vert_edge_t perim[4]);
template<typename project_t, typename vert_t, typename distance_calc_t>
double calc(const project_t &project,
const std::vector<vert_t> &poly,
distance_calc_t dist) {
unsigned ai, bi;
unsigned cross_ai, cross_bi;
unsigned ea, eb;
findSharedEdge(ai, bi);
#if defined(CARVE_DEBUG)
if (carve::geom2d::signedArea(project(poly[a->v[0]]), project(poly[a->v[1]]), project(poly[a->v[2]])) > 0.0 ||
carve::geom2d::signedArea(project(poly[b->v[0]]), project(poly[b->v[1]]), project(poly[b->v[2]])) > 0.0) {
std::cerr << "warning: triangle pair " << this << " contains triangles with incorrect orientation" << std::endl;
}
#endif
cross_ai = P(ai);
cross_bi = P(bi);
ea = a->v[cross_ai];
eb = b->v[cross_bi];
double side_1 = carve::geom2d::orient2d(project(poly[ea]), project(poly[eb]), project(poly[a->v[ai]]));
double side_2 = carve::geom2d::orient2d(project(poly[ea]), project(poly[eb]), project(poly[a->v[N(ai)]]));
bool can_flip = (side_1 < 0.0 && side_2 > 0.0) || (side_1 > 0.0 && side_2 < 0.0);
if (!can_flip) {
score = -1;
} else {
score =
dist(poly[a->v[ai]], poly[b->v[bi]]) -
dist(poly[a->v[cross_ai]], poly[b->v[cross_bi]]);
}
return score;
}
template<typename project_t, typename vert_t, typename distance_calc_t>
double edgeLen(const project_t &project,
const std::vector<vert_t> &poly,
distance_calc_t dist) const {
unsigned ai, bi;
findSharedEdge(ai, bi);
return dist(poly[a->v[ai]], poly[b->v[bi]]);
}
};
struct max_score {
bool operator()(const tri_pair_t *a, const tri_pair_t *b) const { return a->score < b->score; }
};
struct tri_pairs_t {
typedef std::unordered_map<vert_edge_t, tri_pair_t *, hash_vert_edge_t> storage_t;
storage_t storage;
tri_pairs_t() : storage() {
};
~tri_pairs_t() {
for (storage_t::iterator i = storage.begin(); i != storage.end(); ++i) {
if ((*i).second) delete (*i).second;
}
}
void insert(unsigned a, unsigned b, carve::triangulate::tri_idx *t);
template<typename project_t, typename vert_t, typename distance_calc_t>
void updateEdge(tri_pair_t *tp,
const project_t &project,
const std::vector<vert_t> &poly,
distance_calc_t dist,
std::vector<tri_pair_t *> &edges,
size_t &n) {
double old_score = tp->score;
double new_score = tp->calc(project, poly, dist);
#if defined(CARVE_DEBUG)
std::cerr << "tp:" << tp << " old_score: " << old_score << " new_score: " << new_score << std::endl;
#endif
if (new_score > 0.0 && old_score <= 0.0) {
tp->idx = n;
edges[n++] = tp;
} else if (new_score <= 0.0 && old_score > 0.0) {
std::swap(edges[tp->idx], edges[--n]);
edges[tp->idx]->idx = tp->idx;
}
}
tri_pair_t *get(vert_edge_t &e) {
storage_t::iterator i;
i = storage.find(e);
if (i == storage.end()) return NULL;
return (*i).second;
}
template<typename project_t, typename vert_t, typename distance_calc_t>
void flip(const project_t &project,
const std::vector<vert_t> &poly,
distance_calc_t dist,
std::vector<tri_pair_t *> &edges,
size_t &n) {
vert_edge_t old_e, new_e;
vert_edge_t perim[4];
#if defined(CARVE_DEBUG)
std::cerr << "improvable edges: " << n << std::endl;
#endif
tri_pair_t *tp = *std::max_element(edges.begin(), edges.begin() + n, max_score());
#if defined(CARVE_DEBUG)
std::cerr << "improving tri-pair: " << tp << " with score: " << tp->score << std::endl;
#endif
tp->flip(old_e, new_e, perim);
#if defined(CARVE_DEBUG)
std::cerr << "old_e: " << old_e.first << "," << old_e.second << " -> new_e: " << new_e.first << "," << new_e.second << std::endl;
#endif
CARVE_ASSERT(storage.find(old_e) != storage.end());
storage.erase(old_e);
storage[new_e] = tp;
std::swap(edges[tp->idx], edges[--n]);
edges[tp->idx]->idx = tp->idx;
tri_pair_t *tp2;
tp2 = get(perim[0]);
if (tp2 != NULL) {
updateEdge(tp2, project, poly, dist, edges, n);
}
tp2 = get(perim[1]);
if (tp2 != NULL) {
CARVE_ASSERT(tp2->a == tp->b || tp2->b == tp->b);
if (tp2->a == tp->b) { tp2->a = tp->a; } else { tp2->b = tp->a; }
updateEdge(tp2, project, poly, dist, edges, n);
}
tp2 = get(perim[2]);
if (tp2 != NULL) {
updateEdge(tp2, project, poly, dist, edges, n);
}
tp2 = get(perim[3]);
if (tp2 != NULL) {
CARVE_ASSERT(tp2->a == tp->a || tp2->b == tp->a);
if (tp2->a == tp->a) { tp2->a = tp->b; } else { tp2->b = tp->b; }
updateEdge(tp2, project, poly, dist, edges, n);
}
}
template<typename project_t, typename vert_t, typename distance_calc_t>
size_t getInternalEdges(const project_t &project,
const std::vector<vert_t> &poly,
distance_calc_t dist,
std::vector<tri_pair_t *> &edges) {
size_t count = 0;
for (storage_t::iterator i = storage.begin(); i != storage.end();) {
tri_pair_t *tp = (*i).second;
if (tp->a && tp->b) {
tp->calc(project, poly, dist);
count++;
#if defined(CARVE_DEBUG)
std::cerr << "internal edge: " << (*i).first.first << "," << (*i).first.second << " -> " << tp << " " << tp->score << std::endl;
#endif
++i;
} else {
delete (*i).second;
storage.erase(i++);
}
}
edges.resize(count);
size_t fwd = 0;
size_t rev = count;
for (storage_t::iterator i = storage.begin(); i != storage.end(); ++i) {
tri_pair_t *tp = (*i).second;
if (tp && tp->a && tp->b) {
if (tp->score > 0.0) {
edges[fwd++] = tp;
} else {
edges[--rev] = tp;
}
}
}
CARVE_ASSERT(fwd == rev);
return fwd;
}
};
template<typename project_t, typename vert_t>
static bool
testCandidateAttachment(const project_t &project,
std::vector<vert_t> &current_f_loop,
size_t curr,
carve::geom2d::P2 hole_min) {
const size_t SZ = current_f_loop.size();
size_t prev, next;
if (curr == 0) {
prev = SZ - 1; next = 1;
} else if (curr == SZ - 1) {
prev = curr - 1; next = 0;
} else {
prev = curr - 1; next = curr + 1;
}
if (!carve::geom2d::internalToAngle(project(current_f_loop[next]),
project(current_f_loop[curr]),
project(current_f_loop[prev]),
hole_min)) {
return false;
}
if (hole_min == project(current_f_loop[curr])) {
return true;
}
carve::geom2d::LineSegment2 test(hole_min, project(current_f_loop[curr]));
size_t v1 = current_f_loop.size() - 1;
size_t v2 = 0;
double v1_side = carve::geom2d::orient2d(test.v1, test.v2, project(current_f_loop[v1]));
double v2_side = 0;
while (v2 != current_f_loop.size()) {
v2_side = carve::geom2d::orient2d(test.v1, test.v2, project(current_f_loop[v2]));
if (v1_side != v2_side) {
// XXX: need to test vertices, not indices, because they may
// be duplicated.
if (project(current_f_loop[v1]) != project(current_f_loop[curr]) &&
project(current_f_loop[v2]) != project(current_f_loop[curr])) {
carve::geom2d::LineSegment2 test2(project(current_f_loop[v1]), project(current_f_loop[v2]));
if (carve::geom2d::lineSegmentIntersection_simple(test, test2)) {
// intersection; failed.
return false;
}
}
}
v1 = v2;
v1_side = v2_side;
++v2;
}
return true;
}
}
template<typename project_t, typename vert_t>
static std::vector<vert_t>
incorporateHolesIntoPolygon(const project_t &project,
const std::vector<vert_t> &f_loop,
const std::vector<std::vector<vert_t> > &h_loops) {
typedef std::vector<vert_t> hole_t;
typedef typename std::vector<vert_t>::const_iterator vert_iter;
typedef typename std::vector<std::vector<vert_t> >::const_iterator hole_iter;
size_t N = f_loop.size();
// work out how much space to reserve for the patched in holes.
for (hole_iter i = h_loops.begin(); i != h_loops.end(); ++i) {
N += 2 + (*i).size();
}
// this is the vector that we will build the result in.
std::vector<vert_t> current_f_loop;
current_f_loop.reserve(N);
std::vector<size_t> f_loop_heap;
f_loop_heap.reserve(N);
for (unsigned i = 0; i < f_loop.size(); ++i) {
current_f_loop.push_back(f_loop[i]);
}
std::vector<std::pair<const std::vector<vert_t> *, vert_iter> > h_loop_min_vertex;
h_loop_min_vertex.reserve(h_loops.size());
// find the major axis for the holes - this is the axis that we
// will sort on for finding vertices on the polygon to join
// holes up to.
//
// it might also be nice to also look for whether it is better
// to sort ascending or descending.
//
// another trick that could be used is to modify the projection
// by 90 degree rotations or flipping about an axis. just as
// long as we keep the carve::geom3d::Vector pointers for the
// real data in sync, everything should be ok. then we wouldn't
// need to accomodate axes or sort order in the main loop.
// find the bounding box of all the holes.
bool first = true;
double min_x, min_y, max_x, max_y;
for (hole_iter i = h_loops.begin(); i != h_loops.end(); ++i) {
const hole_t &hole(*i);
for (vert_iter j = hole.begin(); j != hole.end(); ++j) {
carve::geom2d::P2 curr = project(*j);
if (first) {
min_x = max_x = curr.x;
min_y = max_y = curr.y;
first = false;
} else {
min_x = std::min(min_x, curr.x);
min_y = std::min(min_y, curr.y);
max_x = std::max(max_x, curr.x);
max_y = std::max(max_y, curr.y);
}
}
}
// choose the axis for which the bbox is largest.
int axis = (max_x - min_x) > (max_y - min_y) ? 0 : 1;
// for each hole, find the minimum vertex in the chosen axis.
for (hole_iter i = h_loops.begin(); i != h_loops.end(); ++i) {
const hole_t &hole = *i;
vert_iter best_i = std::min_element(hole.begin(), hole.end(), detail::order_h_loops<project_t, vert_t>(project, axis));
h_loop_min_vertex.push_back(std::make_pair(&hole, best_i));
}
// sort the holes by the minimum vertex.
std::sort(h_loop_min_vertex.begin(), h_loop_min_vertex.end(), detail::order_h_loops<project_t, vert_t>(project, axis));
// now, for each hole, find a vertex in the current polygon loop that it can be joined to.
for (unsigned i = 0; i < h_loop_min_vertex.size(); ++i) {
const size_t N_f_loop = current_f_loop.size();
// the index of the vertex in the hole to connect.
vert_iter h_loop_connect = h_loop_min_vertex[i].second;
carve::geom2d::P2 hole_min = project(*h_loop_connect);
f_loop_heap.clear();
// we order polygon loop vertices that may be able to be connected
// to the hole vertex by their distance to the hole vertex
detail::heap_ordering<project_t, vert_t> _heap_ordering(project, current_f_loop, *h_loop_connect, axis);
for (size_t j = 0; j < N_f_loop; ++j) {
// it is guaranteed that there exists a polygon vertex with
// coord < the min hole coord chosen, which can be joined to
// the min hole coord without crossing the polygon
// boundary. also, because we merge holes in ascending
// order, it is also true that this join can never cross
// another hole (and that doesn't need to be tested for).
if (project(current_f_loop[j]).v[axis] <= hole_min.v[axis]) {
f_loop_heap.push_back(j);
std::push_heap(f_loop_heap.begin(), f_loop_heap.end(), _heap_ordering);
}
}
// we are going to test each potential (according to the
// previous test) polygon vertex as a candidate join. we order
// by closeness to the hole vertex, so that the join we make
// is as small as possible. to test, we need to check the
// joining line segment does not cross any other line segment
// in the current polygon loop (excluding those that have the
// vertex that we are attempting to join with as an endpoint).
size_t attachment_point = current_f_loop.size();
while (f_loop_heap.size()) {
std::pop_heap(f_loop_heap.begin(), f_loop_heap.end(), _heap_ordering);
size_t curr = f_loop_heap.back();
f_loop_heap.pop_back();
// test the candidate join from current_f_loop[curr] to hole_min
if (!detail::testCandidateAttachment(project, current_f_loop, curr, hole_min)) {
continue;
}
attachment_point = curr;
break;
}
if (attachment_point == current_f_loop.size()) {
CARVE_FAIL("didn't manage to link up hole!");
}
detail::patchHoleIntoPolygon(current_f_loop, attachment_point, h_loop_min_vertex[i]);
}
return current_f_loop;
}
template<typename project_t, typename vert_t>
void triangulate(const project_t &project,
const std::vector<vert_t> &poly,
std::vector<tri_idx> &result) {
std::vector<detail::vertex_info *> vinfo;
const size_t N = poly.size();
result.clear();
if (N < 3) {
return;
}
result.reserve(poly.size() - 2);
if (N == 3) {
result.push_back(tri_idx(0, 1, 2));
return;
}
vinfo.resize(N);
vinfo[0] = new detail::vertex_info(project(poly[0]), 0);
for (size_t i = 1; i < N-1; ++i) {
vinfo[i] = new detail::vertex_info(project(poly[i]), i);
vinfo[i]->prev = vinfo[i-1];
vinfo[i-1]->next = vinfo[i];
}
vinfo[N-1] = new detail::vertex_info(project(poly[N-1]), N-1);
vinfo[N-1]->prev = vinfo[N-2];
vinfo[N-1]->next = vinfo[0];
vinfo[0]->prev = vinfo[N-1];
vinfo[N-2]->next = vinfo[N-1];
for (size_t i = 0; i < N; ++i) {
vinfo[i]->recompute();
}
detail::vertex_info *begin = vinfo[0];
removeDegeneracies(begin, result);
doTriangulate(begin, result);
}
template<typename project_t, typename vert_t, typename distance_calc_t>
void improve(const project_t &project,
const std::vector<vert_t> &poly,
distance_calc_t dist,
std::vector<tri_idx> &result) {
detail::tri_pairs_t tri_pairs;
#if defined(CARVE_DEBUG)
bool warn = false;
for (size_t i = 0; i < result.size(); ++i) {
tri_idx &t = result[i];
if (carve::geom2d::signedArea(project(poly[t.a]), project(poly[t.b]), project(poly[t.c])) > 0) {
warn = true;
}
}
if (warn) {
std::cerr << "carve::triangulate::improve(): Some triangles are incorrectly oriented. Results may be incorrect." << std::endl;
}
#endif
for (size_t i = 0; i < result.size(); ++i) {
tri_idx &t = result[i];
tri_pairs.insert(t.a, t.b, &t);
tri_pairs.insert(t.b, t.c, &t);
tri_pairs.insert(t.c, t.a, &t);
}
std::vector<detail::tri_pair_t *> edges;
size_t n = tri_pairs.getInternalEdges(project, poly, dist, edges);
for (size_t i = 0; i < n; ++i) {
edges[i]->idx = i;
}
// procedure:
// while a tri pair with a positive score exists:
// p = pair with highest positive score
// flip p, rewriting its two referenced triangles.
// negate p's score
// for each q in the up-to-four adjoining tri pairs:
// update q's tri ptr, if changed, and its score.
#if defined(CARVE_DEBUG)
double initial_score = 0;
for (size_t i = 0; i < edges.size(); ++i) {
initial_score += edges[i]->edgeLen(project, poly, dist);
}
std::cerr << "initial score: " << initial_score << std::endl;
#endif
while (n) {
tri_pairs.flip(project, poly, dist, edges, n);
}
#if defined(CARVE_DEBUG)
double final_score = 0;
for (size_t i = 0; i < edges.size(); ++i) {
final_score += edges[i]->edgeLen(project, poly, dist);
}
std::cerr << "final score: " << final_score << std::endl;
#endif
#if defined(CARVE_DEBUG)
if (!warn) {
for (size_t i = 0; i < result.size(); ++i) {
tri_idx &t = result[i];
CARVE_ASSERT (carve::geom2d::signedArea(project(poly[t.a]), project(poly[t.b]), project(poly[t.c])) <= 0.0);
}
}
#endif
}
template<typename project_t, typename vert_t>
void improve(const project_t &project,
const std::vector<vert_t> &poly,
std::vector<tri_idx> &result) {
improve(project, poly, carve::geom::distance_functor(), result);
}
}
}

31
extern/carve/include/carve/util.hpp vendored Normal file
View File

@@ -0,0 +1,31 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
namespace carve {
namespace util {
struct min_functor {
template<typename T>
const T &operator()(const T &a, const T &b) const { return std::min(a, b); }
};
struct max_functor {
template<typename T>
const T &operator()(const T &a, const T &b) const { return std::max(a, b); }
};
}
}

View File

@@ -0,0 +1,17 @@
/* include/carve/config.h. Generated from config.h.in by configure. */
#pragma once
#include <math.h>
/* Define if using boost collections. Preferred, because the visual C++ unordered collections are slow and memory hungry. */
#define HAVE_BOOST_UNORDERED_COLLECTIONS
#if defined(_MSC_VER)
# pragma warning(disable:4201)
#endif
#include <math.h>
static inline double round(double value) {
return (value >= 0) ? floor(value + 0.5) : ceil(value - 0.5);
}

163
extern/carve/include/carve/vector.hpp vendored Normal file
View File

@@ -0,0 +1,163 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/math_constants.hpp>
#include <carve/geom.hpp>
#include <carve/geom3d.hpp>
#include <sstream>
#include <algorithm>
#include <math.h>
namespace carve {
namespace geom3d {
struct hash_vector_ptr {
size_t operator()(const Vector * const &v) const {
return (size_t)v;
}
size_t operator()(const std::pair<const Vector *, const Vector *> &v) const {
size_t r = (size_t)v.first;
size_t s = (size_t)v.second;
return r ^ ((s >> 16) | (s << 16));
}
};
struct vec_adapt_ident {
const Vector &operator()(const Vector &v) const { return v; }
Vector &operator()(Vector &v) const { return v; }
};
struct vec_adapt_ptr {
const Vector &operator()(const Vector * const &v) const { return *v; }
Vector &operator()(Vector *&v) const { return *v; }
};
struct vec_adapt_pair_first {
template<typename pair_t> const Vector &operator()(const pair_t &v) const { return v.first; }
template<typename pair_t> Vector &operator()(pair_t &v) const { return v.first; }
};
struct vec_adapt_pair_second {
template<typename pair_t> const Vector &operator()(const pair_t &v) const { return v.second; }
template<typename pair_t> Vector &operator()(pair_t &v) const { return v.second; }
};
template<typename adapt_t>
struct vec_cmp_lt_x {
adapt_t adapt;
vec_cmp_lt_x(adapt_t _adapt = adapt_t()) : adapt(_adapt) {}
template<typename input_t> bool operator()(const input_t &a, const input_t &b) const { return adapt(a).x < adapt(b).x; }
};
template<typename adapt_t> vec_cmp_lt_x<adapt_t> vec_lt_x(adapt_t &adapt) { return vec_cmp_lt_x<adapt_t>(adapt); }
template<typename adapt_t>
struct vec_cmp_lt_y {
adapt_t adapt;
vec_cmp_lt_y(adapt_t _adapt = adapt_t()) : adapt(_adapt) {}
template<typename input_t> bool operator()(const input_t &a, const input_t &b) const { return adapt(a).y < adapt(b).y; }
};
template<typename adapt_t> vec_cmp_lt_y<adapt_t> vec_lt_y(adapt_t &adapt) { return vec_cmp_lt_y<adapt_t>(adapt); }
template<typename adapt_t>
struct vec_cmp_lt_z {
adapt_t adapt;
vec_cmp_lt_z(adapt_t _adapt = adapt_t()) : adapt(_adapt) {}
template<typename input_t> bool operator()(const input_t &a, const input_t &b) const { return adapt(a).z < adapt(b).z; }
};
template<typename adapt_t> vec_cmp_lt_z<adapt_t> vec_lt_z(adapt_t &adapt) { return vec_cmp_lt_z<adapt_t>(adapt); }
template<typename adapt_t>
struct vec_cmp_gt_x {
adapt_t adapt;
vec_cmp_gt_x(adapt_t _adapt = adapt_t()) : adapt(_adapt) {}
template<typename input_t> bool operator()(const input_t &a, const input_t &b) const { return adapt(a).x > adapt(b).x; }
};
template<typename adapt_t> vec_cmp_gt_x<adapt_t> vec_gt_x(adapt_t &adapt) { return vec_cmp_gt_x<adapt_t>(adapt); }
template<typename adapt_t>
struct vec_cmp_gt_y {
adapt_t adapt;
vec_cmp_gt_y(adapt_t _adapt = adapt_t()) : adapt(_adapt) {}
template<typename input_t> bool operator()(const input_t &a, const input_t &b) const { return adapt(a).y > adapt(b).y; }
};
template<typename adapt_t> vec_cmp_gt_y<adapt_t> vec_gt_y(adapt_t &adapt) { return vec_cmp_gt_y<adapt_t>(adapt); }
template<typename adapt_t>
struct vec_cmp_gt_z {
adapt_t adapt;
vec_cmp_gt_z(adapt_t _adapt = adapt_t()) : adapt(_adapt) {}
template<typename input_t> bool operator()(const input_t &a, const input_t &b) const { return adapt(a).z > adapt(b).z; }
};
template<typename adapt_t> vec_cmp_gt_z<adapt_t> vec_gt_z(adapt_t &adapt) { return vec_cmp_gt_z<adapt_t>(adapt); }
template<typename iter_t, typename adapt_t>
void sortInDirectionOfRay(const Vector &ray_dir, iter_t begin, iter_t end, adapt_t adapt) {
switch (carve::geom::largestAxis(ray_dir)) {
case 0:
if (ray_dir.x > 0) {
std::sort(begin, end, vec_lt_x(adapt));
} else {
std::sort(begin, end, vec_gt_x(adapt));
}
break;
case 1:
if (ray_dir.y > 0) {
std::sort(begin, end, vec_lt_y(adapt));
} else {
std::sort(begin, end, vec_gt_y(adapt));
}
break;
case 2:
if (ray_dir.z > 0) {
std::sort(begin, end, vec_lt_z(adapt));
} else {
std::sort(begin, end, vec_gt_z(adapt));
}
break;
}
}
}
}

View File

@@ -0,0 +1,111 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/geom2d.hpp>
#include <carve/vector.hpp>
#include <carve/matrix.hpp>
#include <carve/geom3d.hpp>
#include <carve/aabb.hpp>
#include <carve/tag.hpp>
#include <vector>
#include <list>
#include <map>
namespace carve {
namespace poly {
struct Object;
template<unsigned ndim>
class Vertex : public tagable {
public:
typedef carve::geom::vector<ndim> vector_t;
typedef Object obj_t;
vector_t v;
obj_t *owner;
Vertex() : tagable(), v() {
}
~Vertex() {
}
Vertex(const vector_t &_v) : tagable(), v(_v) {
}
};
struct hash_vertex_ptr {
template<unsigned ndim>
size_t operator()(const Vertex<ndim> * const &v) const {
return (size_t)v;
}
template<unsigned ndim>
size_t operator()(const std::pair<const Vertex<ndim> *, const Vertex<ndim> *> &v) const {
size_t r = (size_t)v.first;
size_t s = (size_t)v.second;
return r ^ ((s >> 16) | (s << 16));
}
};
template<unsigned ndim>
double distance(const Vertex<ndim> *v1, const Vertex<ndim> *v2) {
return distance(v1->v, v2->v);
}
template<unsigned ndim>
double distance(const Vertex<ndim> &v1, const Vertex<ndim> &v2) {
return distance(v1.v, v2.v);
}
struct vec_adapt_vertex_ref {
template<unsigned ndim>
const typename Vertex<ndim>::vector_t &operator()(const Vertex<ndim> &v) const { return v.v; }
template<unsigned ndim>
typename Vertex<ndim>::vector_t &operator()(Vertex<ndim> &v) const { return v.v; }
};
struct vec_adapt_vertex_ptr {
template<unsigned ndim>
const typename Vertex<ndim>::vector_t &operator()(const Vertex<ndim> *v) const { return v->v; }
template<unsigned ndim>
typename Vertex<ndim>::vector_t &operator()(Vertex<ndim> *v) const { return v->v; }
};
}
}

View File

@@ -0,0 +1,24 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
namespace carve {
namespace poly {
}
}

58
extern/carve/include/carve/win32.h vendored Executable file
View File

@@ -0,0 +1,58 @@
// Copyright 2006 Tobias Sargeant (toby@permuted.net)
// All rights reserved.
#pragma once
#pragma warning (disable : 4996)
#pragma warning (disable : 4786)
#include <string.h>
#include <stdlib.h>
inline int strcasecmp(const char *a, const char *b) {
return _stricmp(a,b);
}
inline void srandom(unsigned long input) {
srand(input);
}
inline long random() {
return rand();
}
#if defined(_MSC_VER)
# include <carve/cbrt.h>
#if _MSC_VER < 1300
// intptr_t is an integer type that is big enough to hold a pointer
// It is not defined in VC6 so include a definition here for the older compiler
typedef long intptr_t;
typedef unsigned long uintptr_t;
#endif
# if _MSC_VER < 1600
// stdint.h is not available before VS2010
#if defined(_WIN32)
/* The __intXX are built-in types of the visual complier! So we don't
need to include anything else here.
This typedefs should be in sync with types from MEM_sys_types.h */
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
# else
# include <stdint.h>
# endif
#endif
#if defined(_MSC_VER)
# include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif

29
extern/carve/lib/carve.cpp vendored Normal file
View File

@@ -0,0 +1,29 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#if defined(HAVE_CONFIG_H)
# include <carve_config.h>
#endif
#include <carve/carve.hpp>
#define DEF_EPSILON 1.4901161193847656e-08
namespace carve {
double EPSILON = DEF_EPSILON;
double EPSILON2 = DEF_EPSILON * DEF_EPSILON;
}

100
extern/carve/lib/convex_hull.cpp vendored Normal file
View File

@@ -0,0 +1,100 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#if defined(HAVE_CONFIG_H)
# include <carve_config.h>
#endif
#include <carve/csg.hpp>
#include <carve/convex_hull.hpp>
#include <algorithm>
namespace {
bool grahamScan(const std::vector<carve::geom2d::P2> &points,
int vpp, int vp,
const std::vector<int> &ordered,
int start,
std::vector<int> &result, int _i = 0) {
carve::geom2d::P2 v1 = points[vp] - points[vpp];
if (start == (int)ordered.size()) return true;
for (int i = start; i < (int)ordered.size(); ++i) {
int v = ordered[i];
carve::geom2d::P2 v2 = points[v] - points[vp];
double cp = v1.x * v2.y - v2.x * v1.y;
if (cp < 0) return false;
int j = i + 1;
while (j < (int)ordered.size() && points[ordered[j]] == points[v]) j++;
result.push_back(v);
if (grahamScan(points, vp, v, ordered, j, result, _i + 1)) return true;
result.pop_back();
}
return false;
}
}
namespace carve {
namespace geom {
std::vector<int> convexHull(const std::vector<carve::geom2d::P2> &points) {
double max_x = points[0].x;
unsigned max_v = 0;
for (unsigned i = 1; i < points.size(); ++i) {
if (points[i].x > max_x) {
max_x = points[i].x;
max_v = i;
}
}
std::vector<std::pair<double, double> > angle_dist;
std::vector<int> ordered;
angle_dist.reserve(points.size());
ordered.reserve(points.size() - 1);
for (unsigned i = 0; i < points.size(); ++i) {
if (i == max_v) continue;
angle_dist[i] = std::make_pair(carve::math::ANG(carve::geom2d::atan2(points[i] - points[max_v])), distance2(points[i], points[max_v]));
ordered.push_back(i);
}
std::sort(ordered.begin(),
ordered.end(),
make_index_sort(angle_dist.begin()));
std::vector<int> result;
result.push_back(max_v);
result.push_back(ordered[0]);
if (!grahamScan(points, max_v, ordered[0], ordered, 1, result)) {
result.clear();
throw carve::exception("convex hull failed!");
}
return result;
}
}
}

93
extern/carve/lib/csg.cpp vendored Normal file
View File

@@ -0,0 +1,93 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#if defined(HAVE_CONFIG_H)
# include <carve_config.h>
#endif
#include <carve/csg.hpp>
#include "csg_detail.hpp"
const char *carve::csg::ENUM(carve::csg::FaceClass f) {
if (f == FACE_ON_ORIENT_OUT) return "FACE_ON_ORIENT_OUT";
if (f == FACE_OUT) return "FACE_OUT";
if (f == FACE_IN) return "FACE_IN";
if (f == FACE_ON_ORIENT_IN) return "FACE_ON_ORIENT_IN";
return "???";
}
const char *carve::csg::ENUM(carve::PointClass p) {
if (p == POINT_UNK) return "POINT_UNK";
if (p == POINT_OUT) return "POINT_OUT";
if (p == POINT_ON) return "POINT_ON";
if (p == POINT_IN) return "POINT_IN";
if (p == POINT_VERTEX) return "POINT_VERTEX";
if (p == POINT_EDGE) return "POINT_EDGE";
return "???";
}
void carve::csg::detail::LoopEdges::addFaceLoop(FaceLoop *fl) {
carve::mesh::MeshSet<3>::vertex_t *v1, *v2;
v1 = fl->vertices[fl->vertices.size() - 1];
for (unsigned j = 0; j < fl->vertices.size(); ++j) {
v2 = fl->vertices[j];
(*this)[std::make_pair(v1, v2)].push_back(fl);
v1 = v2;
}
}
void carve::csg::detail::LoopEdges::sortFaceLoopLists() {
for (super::iterator i = begin(), e = end(); i != e; ++i) {
(*i).second.sort();
}
}
void carve::csg::detail::LoopEdges::removeFaceLoop(FaceLoop *fl) {
carve::mesh::MeshSet<3>::vertex_t *v1, *v2;
v1 = fl->vertices[fl->vertices.size() - 1];
for (unsigned j = 0; j < fl->vertices.size(); ++j) {
v2 = fl->vertices[j];
iterator l(find(std::make_pair(v1, v2)));
if (l != end()) {
(*l).second.remove(fl);
if (!(*l).second.size()) {
erase(l);
}
}
v1 = v2;
}
}
carve::csg::FaceClass carve::csg::FaceLoopGroup::classificationAgainst(const carve::mesh::MeshSet<3>::mesh_t *mesh) const {
for (std::list<ClassificationInfo>::const_iterator i = classification.begin(); i != classification.end(); ++i) {
if ((*i).intersected_mesh == mesh) {
return (*i).classification;
}
}
return FACE_UNCLASSIFIED;
}

372
extern/carve/lib/csg_collector.cpp vendored Normal file
View File

@@ -0,0 +1,372 @@
// Begin License:
// Copyright (C) 2006-2014 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 included in the packaging of this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#if defined(HAVE_CONFIG_H)
# include <carve_config.h>
#endif
#include <carve/csg.hpp>
#include <iostream>
#include "csg_collector.hpp"
#include "intersect_debug.hpp"
#if defined(CARVE_DEBUG_WRITE_PLY_DATA)
void writePLY(const std::string &out_file, const carve::mesh::MeshSet<3> *poly, bool ascii);
#endif
namespace carve {
namespace csg {
namespace {
class BaseCollector : public CSG::Collector {
BaseCollector();
BaseCollector(const BaseCollector &);
BaseCollector &operator=(const BaseCollector &);
protected:
struct face_data_t {
carve::mesh::MeshSet<3>::face_t *face;
const carve::mesh::MeshSet<3>::face_t *orig_face;
bool flipped;
face_data_t(carve::mesh::MeshSet<3>::face_t *_face,
const carve::mesh::MeshSet<3>::face_t *_orig_face,
bool _flipped) : face(_face), orig_face(_orig_face), flipped(_flipped) {
};
};
std::list<face_data_t> faces;
const carve::mesh::MeshSet<3> *src_a;
const carve::mesh::MeshSet<3> *src_b;
BaseCollector(const carve::mesh::MeshSet<3> *_src_a,
const carve::mesh::MeshSet<3> *_src_b) : CSG::Collector(), src_a(_src_a), src_b(_src_b) {
}
virtual ~BaseCollector() {
}
void FWD(const carve::mesh::MeshSet<3>::face_t *orig_face,
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &vertices,
carve::geom3d::Vector /* normal */,
bool /* poly_a */,
FaceClass face_class,
CSG::Hooks &hooks) {
std::vector<carve::mesh::MeshSet<3>::face_t *> new_faces;
new_faces.reserve(1);
new_faces.push_back(orig_face->create(vertices.begin(), vertices.end(), false));
hooks.processOutputFace(new_faces, orig_face, false);
for (size_t i = 0; i < new_faces.size(); ++i) {
faces.push_back(face_data_t(new_faces[i], orig_face, false));
}
#if defined(CARVE_DEBUG) && defined(DEBUG_PRINT_RESULT_FACES)
std::cerr << "+" << ENUM(face_class) << " ";
for (unsigned i = 0; i < vertices.size(); ++i) std::cerr << " " << vertices[i] << ":" << *vertices[i];
std::cerr << std::endl;
#endif
}
void REV(const carve::mesh::MeshSet<3>::face_t *orig_face,
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &vertices,
carve::geom3d::Vector /* normal */,
bool /* poly_a */,
FaceClass face_class,
CSG::Hooks &hooks) {
// normal = -normal;
std::vector<carve::mesh::MeshSet<3>::face_t *> new_faces;
new_faces.reserve(1);
new_faces.push_back(orig_face->create(vertices.begin(), vertices.end(), true));
hooks.processOutputFace(new_faces, orig_face, true);
for (size_t i = 0; i < new_faces.size(); ++i) {
faces.push_back(face_data_t(new_faces[i], orig_face, true));
}
#if defined(CARVE_DEBUG) && defined(DEBUG_PRINT_RESULT_FACES)
std::cerr << "-" << ENUM(face_class) << " ";
for (unsigned i = 0; i < vertices.size(); ++i) std::cerr << " " << vertices[i] << ":" << *vertices[i];
std::cerr << std::endl;
#endif
}
virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face,
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &vertices,
carve::geom3d::Vector normal,
bool poly_a,
FaceClass face_class,
CSG::Hooks &hooks) =0;
virtual void collect(FaceLoopGroup *grp, CSG::Hooks &hooks) {
std::list<ClassificationInfo> &cinfo = (grp->classification);
if (cinfo.size() == 0) {
std::cerr << "WARNING! group " << grp << " has no classification info!" << std::endl;
return;
}
FaceClass fc = FACE_UNCLASSIFIED;
unsigned fc_closed_bits = 0;
unsigned fc_open_bits = 0;
unsigned fc_bits = 0;
for (std::list<ClassificationInfo>::const_iterator i = grp->classification.begin(), e = grp->classification.end(); i != e; ++i) {
if ((*i).intersected_mesh == NULL) {
// classifier only returns global info
fc_closed_bits = class_to_class_bit((*i).classification);
break;
}
if ((*i).classification == FACE_UNCLASSIFIED) continue;
if ((*i).intersectedMeshIsClosed()) {
fc_closed_bits |= class_to_class_bit((*i).classification);
} else {
fc_open_bits |= class_to_class_bit((*i).classification);
}
}
if (fc_closed_bits) {
fc_bits = fc_closed_bits;
} else {
fc_bits = fc_open_bits;
}
fc = class_bit_to_class(fc_bits);
// handle the complex cases where a group is classified differently with respect to two or more closed manifolds.
if (fc == FACE_UNCLASSIFIED) {
unsigned inout_bits = fc_bits & FACE_NOT_ON_BIT;
unsigned on_bits = fc_bits & FACE_ON_BIT;
// both in and out. indicates an invalid manifold embedding.
if (inout_bits == (FACE_IN_BIT | FACE_OUT_BIT)) goto out;
// on, both orientations. could be caused by two manifolds touching at a face.
if (on_bits == (FACE_ON_ORIENT_IN_BIT | FACE_ON_ORIENT_OUT_BIT)) goto out;
// in or out, but also on (with orientation). the on classification takes precedence.
fc = class_bit_to_class(on_bits);
}
out:
if (fc == FACE_UNCLASSIFIED) {
std::cerr << "group " << grp << " is unclassified!" << std::endl;
#if defined(CARVE_DEBUG_WRITE_PLY_DATA)
static int uc_count = 0;
std::vector<carve::mesh::MeshSet<3>::face_t *> faces;
for (FaceLoop *f = grp->face_loops.head; f; f = f->next) {
carve::mesh::MeshSet<3>::face_t *temp = f->orig_face->create(f->vertices.begin(), f->vertices.end(), false);
faces.push_back(temp);
}
carve::mesh::MeshSet<3> *p = new carve::mesh::MeshSet<3>(faces);
std::ostringstream filename;
filename << "classifier_fail_" << ++uc_count << ".ply";
std::string out(filename.str().c_str());
::writePLY(out, p, false);
delete p;
#endif
return;
}
bool is_poly_a = grp->src == src_a;
for (FaceLoop *f = grp->face_loops.head; f; f = f->next) {
collect(f->orig_face, f->vertices, f->orig_face->plane.N, is_poly_a, fc, hooks);
}
}
virtual carve::mesh::MeshSet<3> *done(CSG::Hooks &hooks) {
std::vector<carve::mesh::MeshSet<3>::face_t *> f;
f.reserve(faces.size());
for (std::list<face_data_t>::iterator i = faces.begin(); i != faces.end(); ++i) {
f.push_back((*i).face);
}
carve::mesh::MeshSet<3> *p = new carve::mesh::MeshSet<3>(f);
if (hooks.hasHook(carve::csg::CSG::Hooks::RESULT_FACE_HOOK)) {
for (std::list<face_data_t>::iterator i = faces.begin(); i != faces.end(); ++i) {
hooks.resultFace((*i).face, (*i).orig_face, (*i).flipped);
}
}
return p;
}
};
class AllCollector : public BaseCollector {
public:
AllCollector(const carve::mesh::MeshSet<3> *_src_a,
const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) {
}
virtual ~AllCollector() {
}
virtual void collect(FaceLoopGroup *grp, CSG::Hooks &hooks) {
for (FaceLoop *f = grp->face_loops.head; f; f = f->next) {
FWD(f->orig_face, f->vertices, f->orig_face->plane.N, f->orig_face->mesh->meshset == src_a, FACE_OUT, hooks);
}
}
virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face,
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &vertices,
carve::geom3d::Vector normal,
bool poly_a,
FaceClass face_class,
CSG::Hooks &hooks) {
FWD(orig_face, vertices, normal, poly_a, face_class, hooks);
}
};
class UnionCollector : public BaseCollector {
public:
UnionCollector(const carve::mesh::MeshSet<3> *_src_a,
const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) {
}
virtual ~UnionCollector() {
}
virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face,
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &vertices,
carve::geom3d::Vector normal,
bool poly_a,
FaceClass face_class,
CSG::Hooks &hooks) {
if (face_class == FACE_OUT || (poly_a && face_class == FACE_ON_ORIENT_OUT)) {
FWD(orig_face, vertices, normal, poly_a, face_class, hooks);
}
}
};
class IntersectionCollector : public BaseCollector {
public:
IntersectionCollector(const carve::mesh::MeshSet<3> *_src_a,
const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) {
}
virtual ~IntersectionCollector() {
}
virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face,
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &vertices,
carve::geom3d::Vector normal,
bool poly_a,
FaceClass face_class,
CSG::Hooks &hooks) {
if (face_class == FACE_IN || (poly_a && face_class == FACE_ON_ORIENT_OUT)) {
FWD(orig_face, vertices, normal, poly_a, face_class, hooks);
}
}
};
class SymmetricDifferenceCollector : public BaseCollector {
public:
SymmetricDifferenceCollector(const carve::mesh::MeshSet<3> *_src_a,
const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) {
}
virtual ~SymmetricDifferenceCollector() {
}
virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face,
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &vertices,
carve::geom3d::Vector normal,
bool poly_a,
FaceClass face_class,
CSG::Hooks &hooks) {
if (face_class == FACE_OUT) {
FWD(orig_face, vertices, normal, poly_a, face_class, hooks);
} else if (face_class == FACE_IN) {
REV(orig_face, vertices, normal, poly_a, face_class, hooks);
}
}
};
class AMinusBCollector : public BaseCollector {
public:
AMinusBCollector(const carve::mesh::MeshSet<3> *_src_a,
const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) {
}
virtual ~AMinusBCollector() {
}
virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face,
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &vertices,
carve::geom3d::Vector normal,
bool poly_a,
FaceClass face_class,
CSG::Hooks &hooks) {
if ((face_class == FACE_OUT || face_class == FACE_ON_ORIENT_IN) && poly_a) {
FWD(orig_face, vertices, normal, poly_a, face_class, hooks);
} else if (face_class == FACE_IN && !poly_a) {
REV(orig_face, vertices, normal, poly_a, face_class, hooks);
}
}
};
class BMinusACollector : public BaseCollector {
public:
BMinusACollector(const carve::mesh::MeshSet<3> *_src_a,
const carve::mesh::MeshSet<3> *_src_b) : BaseCollector(_src_a, _src_b) {
}
virtual ~BMinusACollector() {
}
virtual void collect(const carve::mesh::MeshSet<3>::face_t *orig_face,
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &vertices,
carve::geom3d::Vector normal,
bool poly_a,
FaceClass face_class,
CSG::Hooks &hooks) {
if ((face_class == FACE_OUT || face_class == FACE_ON_ORIENT_IN) && !poly_a) {
FWD(orig_face, vertices, normal, poly_a, face_class, hooks);
} else if (face_class == FACE_IN && poly_a) {
REV(orig_face, vertices, normal, poly_a, face_class, hooks);
}
}
};
}
CSG::Collector *makeCollector(CSG::OP op,
const carve::mesh::MeshSet<3> *poly_a,
const carve::mesh::MeshSet<3> *poly_b) {
switch (op) {
case CSG::UNION: return new UnionCollector(poly_a, poly_b);
case CSG::INTERSECTION: return new IntersectionCollector(poly_a, poly_b);
case CSG::A_MINUS_B: return new AMinusBCollector(poly_a, poly_b);
case CSG::B_MINUS_A: return new BMinusACollector(poly_a, poly_b);
case CSG::SYMMETRIC_DIFFERENCE: return new SymmetricDifferenceCollector(poly_a, poly_b);
case CSG::ALL: return new AllCollector(poly_a, poly_b);
}
return NULL;
}
}
}

Some files were not shown because too many files have changed in this diff Show More