Merging r43721 through r43847 from trunk into soc-2011-tomato
This commit is contained in:
@@ -249,6 +249,12 @@ if(APPLE)
|
||||
"Choose the minimum OSX version required: 10.4 or 10.5"
|
||||
FORCE)
|
||||
endif()
|
||||
if(${CMAKE_GENERATOR} MATCHES "Xcode" AND (${XCODE_VERSION} VERSION_EQUAL 4 OR ${XCODE_VERSION} VERSION_GREATER 4))
|
||||
# Xcode 4 defaults to the Apple LLVM Compiler.
|
||||
# Override the default compiler selection because Blender only compiles with gcc
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
|
||||
message(STATUS "Setting compiler to: " ${CMAKE_XCODE_ATTRIBUTE_GCC_VERSION})
|
||||
endif()
|
||||
option(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" ON)
|
||||
option(USE_QTKIT "Use QtKit instead of Carbon quicktime (needed for having partial quicktime for 64bit)" OFF)
|
||||
option(WITH_LIBS10.5 "Use 10.5 libs (needed for 64bit builds)" OFF)
|
||||
|
||||
@@ -69,11 +69,9 @@ See the actuator's reference for available methods
|
||||
:columns: 3
|
||||
|
||||
* :class:`~bge.types.BL_ActionActuator`
|
||||
* :class:`~bge.types.BL_ShapeActionActuator`
|
||||
* :class:`~bge.types.KX_CameraActuator`
|
||||
* :class:`~bge.types.KX_ConstraintActuator`
|
||||
* :class:`~bge.types.KX_GameActuator`
|
||||
* :class:`~bge.types.KX_IpoActuator`
|
||||
* :class:`~bge.types.KX_NetworkMessageActuator`
|
||||
* :class:`~bge.types.KX_ObjectActuator`
|
||||
* :class:`~bge.types.KX_ParentActuator`
|
||||
@@ -477,6 +475,7 @@ Action Actuator
|
||||
See :class:`bge.types.BL_ActionActuator`
|
||||
|
||||
.. data:: KX_ACTIONACT_PLAY
|
||||
.. data:: KX_ACTIONACT_PINGPONG
|
||||
.. data:: KX_ACTIONACT_FLIPPER
|
||||
.. data:: KX_ACTIONACT_LOOPSTOP
|
||||
.. data:: KX_ACTIONACT_LOOPEND
|
||||
@@ -635,21 +634,6 @@ See :class:`bge.types.KX_GameActuator`
|
||||
.. data:: KX_GAME_SAVECFG
|
||||
.. data:: KX_GAME_LOADCFG
|
||||
|
||||
.. _ipo-actuator:
|
||||
|
||||
------------
|
||||
IPO Actuator
|
||||
------------
|
||||
|
||||
See :class:`bge.types.KX_IpoActuator`
|
||||
|
||||
.. data:: KX_IPOACT_PLAY
|
||||
.. data:: KX_IPOACT_PINGPONG
|
||||
.. data:: KX_IPOACT_FLIPPER
|
||||
.. data:: KX_IPOACT_LOOPSTOP
|
||||
.. data:: KX_IPOACT_LOOPEND
|
||||
.. data:: KX_IPOACT_FROM_PROP
|
||||
|
||||
---------------
|
||||
Parent Actuator
|
||||
---------------
|
||||
@@ -691,20 +675,6 @@ See :class:`bge.types.KX_SceneActuator`
|
||||
.. data:: KX_SCENE_SUSPEND
|
||||
.. data:: KX_SCENE_RESUME
|
||||
|
||||
.. _shape-action-actuator:
|
||||
|
||||
---------------------
|
||||
Shape Action Actuator
|
||||
---------------------
|
||||
|
||||
See :class:`bge.types.BL_ActionActuator`
|
||||
|
||||
.. data:: KX_ACTIONACT_PLAY
|
||||
.. data:: KX_ACTIONACT_FLIPPER
|
||||
.. data:: KX_ACTIONACT_LOOPSTOP
|
||||
.. data:: KX_ACTIONACT_LOOPEND
|
||||
.. data:: KX_ACTIONACT_PROPERTY
|
||||
|
||||
.. _logic-sound-actuator:
|
||||
|
||||
--------------
|
||||
|
||||
@@ -123,6 +123,29 @@ Example of a data path that can be quickly found via the console:
|
||||
1.0
|
||||
|
||||
|
||||
Data Creation/Removal
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Those of you familiar with other python api's may be surprised that new datablocks in the bpy api can't be created by calling the class:
|
||||
|
||||
>>> bpy.types.Mesh()
|
||||
Traceback (most recent call last):
|
||||
File "<blender_console>", line 1, in <module>
|
||||
TypeError: bpy_struct.__new__(type): expected a single argument
|
||||
|
||||
|
||||
This is an intentional part of the API design.
|
||||
The blender/python api can't create blender data that exists outside the main blender database (accessed through bpy.data), because this data is managed by blender (save/load/undo/append... etc).
|
||||
|
||||
Data is added and removed via methods on the collections in bpy.data, eg:
|
||||
|
||||
>>> mesh = bpy.data.meshes.new(name="MyMesh")
|
||||
>>> print(mesh)
|
||||
<bpy_struct, Mesh("MyMesh.001")>
|
||||
|
||||
>>> bpy.data.meshes.remove(mesh)
|
||||
|
||||
|
||||
Custom Properties
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -17,7 +17,7 @@ done
|
||||
rm -rf include
|
||||
rm -rf lib
|
||||
|
||||
cat "files.txt" | while f=`line`; do
|
||||
cat "files.txt" | while read f; do
|
||||
mkdir -p `dirname $f`
|
||||
cp $tmp/carve/$f $f
|
||||
done
|
||||
|
||||
+160
-125
@@ -48,6 +48,63 @@ namespace {
|
||||
|
||||
|
||||
|
||||
#if defined(CARVE_DEBUG_WRITE_PLY_DATA)
|
||||
template<typename iter_t>
|
||||
void dumpFacesAndHoles(iter_t f_begin, iter_t f_end,
|
||||
iter_t h_begin, iter_t h_end,
|
||||
const std::string &fname) {
|
||||
std::cerr << "dumping " << std::distance(f_begin, f_end) << " faces, " << std::distance(h_begin, h_end) << " holes." << std::endl;
|
||||
std::map<carve::mesh::MeshSet<3>::vertex_t *, size_t> v_included;
|
||||
|
||||
for (iter_t i = f_begin; i != f_end; ++i) {
|
||||
for (size_t j = 0; j < (*i).size(); ++j) {
|
||||
if (v_included.find((*i)[j]) == v_included.end()) {
|
||||
size_t &p = v_included[(*i)[j]];
|
||||
p = v_included.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (iter_t i = h_begin; i != h_end; ++i) {
|
||||
for (size_t j = 0; j < (*i).size(); ++j) {
|
||||
if (v_included.find((*i)[j]) == v_included.end()) {
|
||||
size_t &p = v_included[(*i)[j]];
|
||||
p = v_included.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
carve::line::PolylineSet fh;
|
||||
fh.vertices.resize(v_included.size());
|
||||
for (std::map<carve::mesh::MeshSet<3>::vertex_t *, size_t>::const_iterator
|
||||
i = v_included.begin(); i != v_included.end(); ++i) {
|
||||
fh.vertices[(*i).second].v = (*i).first->v;
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<size_t> connected;
|
||||
for (iter_t i = f_begin; i != f_end; ++i) {
|
||||
connected.clear();
|
||||
for (size_t j = 0; j < (*i).size(); ++j) {
|
||||
connected.push_back(v_included[(*i)[j]]);
|
||||
}
|
||||
fh.addPolyline(true, connected.begin(), connected.end());
|
||||
}
|
||||
for (iter_t i = h_begin; i != h_end; ++i) {
|
||||
connected.clear();
|
||||
for (size_t j = 0; j < (*i).size(); ++j) {
|
||||
connected.push_back(v_included[(*i)[j]]);
|
||||
}
|
||||
fh.addPolyline(true, connected.begin(), connected.end());
|
||||
}
|
||||
}
|
||||
|
||||
::writePLY(fname, &fh, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
void populateVectorFromList(std::list<T> &l, std::vector<T> &v) {
|
||||
v.clear();
|
||||
@@ -433,6 +490,7 @@ namespace {
|
||||
face_loops_sorted[m].push_back(n);
|
||||
}
|
||||
face_loop_areas.push_back(carve::geom2d::signedArea(face_loops_projected[m]));
|
||||
|
||||
std::sort(face_loops_sorted[m].begin(), face_loops_sorted[m].end(),
|
||||
carve::make_index_sort(face_loops[m].begin()));
|
||||
face_loop_aabb[m].fit(face_loops_projected[m].begin(), face_loops_projected[m].end());
|
||||
@@ -449,6 +507,7 @@ namespace {
|
||||
hole_loops_sorted[m].push_back(n);
|
||||
}
|
||||
hole_loop_areas.push_back(carve::geom2d::signedArea(hole_loops_projected[m]));
|
||||
|
||||
std::sort(hole_loops_sorted[m].begin(), hole_loops_sorted[m].end(),
|
||||
carve::make_index_sort(hole_loops[m].begin()));
|
||||
hole_loop_aabb[m].fit(hole_loops_projected[m].begin(), hole_loops_projected[m].end());
|
||||
@@ -572,6 +631,10 @@ namespace {
|
||||
std::vector<std::vector<int> > containing_faces;
|
||||
std::map<int, std::map<int, std::pair<unsigned, unsigned> > > hole_shared_vertices;
|
||||
|
||||
#if defined(CARVE_DEBUG_WRITE_PLY_DATA)
|
||||
dumpFacesAndHoles(f_loops.begin(), f_loops.end(), h_loops.begin(), h_loops.end(), "/tmp/pre_merge.ply");
|
||||
#endif
|
||||
|
||||
{
|
||||
// move input face and hole loops to temp vectors.
|
||||
size_t m;
|
||||
@@ -720,6 +783,10 @@ namespace {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(CARVE_DEBUG_WRITE_PLY_DATA)
|
||||
dumpFacesAndHoles(f_loops.begin(), f_loops.end(), h_loops.begin(), h_loops.end(), "/tmp/post_merge.ply");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -738,7 +805,7 @@ namespace {
|
||||
* on that edge.
|
||||
* @param[out] base_loop A vector of the vertices of the base loop.
|
||||
*/
|
||||
static void assembleBaseLoop(carve::mesh::MeshSet<3>::face_t *face,
|
||||
static bool assembleBaseLoop(carve::mesh::MeshSet<3>::face_t *face,
|
||||
const carve::csg::detail::Data &data,
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> &base_loop) {
|
||||
base_loop.clear();
|
||||
@@ -746,6 +813,7 @@ namespace {
|
||||
// XXX: assumes that face->edges is in the same order as
|
||||
// face->vertices. (Which it is)
|
||||
carve::mesh::MeshSet<3>::edge_t *e = face->edge;
|
||||
bool face_edge_intersected = false;
|
||||
do {
|
||||
base_loop.push_back(carve::csg::map_vertex(data.vmap, e->vert));
|
||||
|
||||
@@ -757,9 +825,13 @@ namespace {
|
||||
for (size_t k = 0, ke = ev_vec.size(); k < ke;) {
|
||||
base_loop.push_back(ev_vec[k++]);
|
||||
}
|
||||
|
||||
face_edge_intersected = true;
|
||||
}
|
||||
e = e->next;
|
||||
} while (e != face->edge);
|
||||
|
||||
return face_edge_intersected;
|
||||
}
|
||||
|
||||
|
||||
@@ -789,7 +861,6 @@ namespace {
|
||||
carve::csg::CSG::Hooks &hooks,
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> &base_loop,
|
||||
std::vector<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > &paths,
|
||||
std::vector<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > &loops,
|
||||
std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > &face_loops_out) {
|
||||
const size_t N = base_loop.size();
|
||||
std::vector<crossing_data> endpoint_indices;
|
||||
@@ -800,6 +871,7 @@ namespace {
|
||||
endpoint_indices.push_back(crossing_data(&paths[i], N, N));
|
||||
}
|
||||
|
||||
// Step 1:
|
||||
// locate endpoints of paths on the base loop.
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
for (size_t j = 0; j < paths.size(); ++j) {
|
||||
@@ -872,6 +944,7 @@ namespace {
|
||||
#endif
|
||||
|
||||
|
||||
// Step 2:
|
||||
// divide paths up into those that connect to the base loop in two
|
||||
// places (cross), and those that do not (noncross).
|
||||
std::vector<crossing_data> cross, noncross;
|
||||
@@ -895,7 +968,6 @@ namespace {
|
||||
double area = carve::geom2d::signedArea(endpoint_indices[i].path->begin() + 1,
|
||||
endpoint_indices[i].path->end(),
|
||||
carve::mesh::MeshSet<3>::face_t::projection_mapping(face->project));
|
||||
std::cerr << "HITS THIS CODE - area=" << area << std::endl;
|
||||
if (area < 0) {
|
||||
// XXX: Create test case to check that this is the correct sign for the area.
|
||||
std::reverse(endpoint_indices[i].path->begin(), endpoint_indices[i].path->end());
|
||||
@@ -917,6 +989,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3:
|
||||
// add a temporary crossing path that connects the beginning and the
|
||||
// end of the base loop. this stops us from needing special case
|
||||
// code to handle the left over loop after all the other crossing
|
||||
@@ -931,10 +1004,12 @@ namespace {
|
||||
std::cerr << "### crossing edge count (with sentinel): " << cross.size() << std::endl;
|
||||
#endif
|
||||
|
||||
// Step 4:
|
||||
// sort paths by increasing beginning point and decreasing ending point.
|
||||
std::sort(cross.begin(), cross.end());
|
||||
std::sort(noncross.begin(), noncross.end());
|
||||
|
||||
// Step 5:
|
||||
// divide up the base loop based upon crossing paths.
|
||||
std::vector<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > divided_base_loop;
|
||||
divided_base_loop.reserve(cross.size());
|
||||
@@ -979,6 +1054,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
// Step 6:
|
||||
for (size_t i = 0; i < cross.size(); ++i) {
|
||||
#if defined(CARVE_DEBUG)
|
||||
std::cerr << "### i=" << i << " working on edge: " << cross[i].edge_idx[0] << " - " << cross[i].edge_idx[1] << std::endl;
|
||||
@@ -1060,7 +1136,8 @@ namespace {
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!noncross.size() && !loops.size()) {
|
||||
if (!noncross.size()) {
|
||||
// If there are no non-crossing paths then we're done.
|
||||
populateListFromVector(divided_base_loop, face_loops_out);
|
||||
return true;
|
||||
}
|
||||
@@ -1113,16 +1190,6 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
// for each loop, just test with any point.
|
||||
for (size_t j = 0; j < loops.size(); ++j) {
|
||||
test = face->project(loops[j].front()->v);
|
||||
|
||||
if (proj_aabb[i].intersects(test) &&
|
||||
carve::geom2d::pointInPoly(proj[i], test).iclass != carve::POINT_OUT) {
|
||||
inc.push_back(&loops[j]);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CARVE_DEBUG)
|
||||
std::cerr << "### divided base loop:" << i << " inc.size()=" << inc.size() << std::endl;
|
||||
std::cerr << "### inc = [";
|
||||
@@ -1172,15 +1239,18 @@ namespace {
|
||||
void composeEdgesIntoPaths(const carve::csg::V2Set &edges,
|
||||
const std::vector<carve::mesh::MeshSet<3>::vertex_t *> &extra_endpoints,
|
||||
std::vector<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > &paths,
|
||||
std::vector<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > &cuts,
|
||||
std::vector<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > &loops) {
|
||||
using namespace carve::csg;
|
||||
|
||||
detail::VVSMap vertex_graph;
|
||||
detail::VSet endpoints;
|
||||
detail::VSet cut_endpoints;
|
||||
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> path;
|
||||
typedef std::vector<carve::mesh::MeshSet<3>::vertex_t *> vvec_t;
|
||||
vvec_t path;
|
||||
|
||||
std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > temp;
|
||||
std::list<vvec_t> path_list, cut_list, loop_list;
|
||||
|
||||
// build graph from edges.
|
||||
for (V2Set::const_iterator i = edges.begin(); i != edges.end(); ++i) {
|
||||
@@ -1199,6 +1269,9 @@ namespace {
|
||||
std::cerr << "### endpoint: " << (*i).first << std::endl;
|
||||
#endif
|
||||
endpoints.insert((*i).first);
|
||||
if ((*i).second.size() == 1) {
|
||||
cut_endpoints.insert((*i).first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1209,6 +1282,7 @@ namespace {
|
||||
std::cerr << "### extra endpoint: " << extra_endpoints[i] << std::endl;
|
||||
#endif
|
||||
endpoints.insert(extra_endpoints[i]);
|
||||
cut_endpoints.erase(extra_endpoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1252,11 +1326,19 @@ namespace {
|
||||
}
|
||||
CARVE_ASSERT(endpoints.find(path.back()) != endpoints.end());
|
||||
|
||||
temp.push_back(path);
|
||||
bool is_cut =
|
||||
cut_endpoints.find(path.front()) != cut_endpoints.end() &&
|
||||
cut_endpoints.find(path.back()) != cut_endpoints.end();
|
||||
|
||||
if (is_cut) {
|
||||
cut_list.push_back(vvec_t()); path.swap(cut_list.back());
|
||||
} else {
|
||||
path_list.push_back(vvec_t()); path.swap(path_list.back());
|
||||
}
|
||||
}
|
||||
|
||||
populateVectorFromList(temp, paths);
|
||||
temp.clear();
|
||||
populateVectorFromList(path_list, paths);
|
||||
populateVectorFromList(cut_list, cuts);
|
||||
|
||||
// now only loops should remain in the graph.
|
||||
while (vertex_graph.size()) {
|
||||
@@ -1291,72 +1373,14 @@ namespace {
|
||||
if (v == path[0]) break;
|
||||
}
|
||||
|
||||
temp.push_back(path);
|
||||
loop_list.push_back(vvec_t()); path.swap(loop_list.back());
|
||||
}
|
||||
populateVectorFromList(temp, loops);
|
||||
|
||||
populateVectorFromList(loop_list, loops);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(CARVE_DEBUG_WRITE_PLY_DATA)
|
||||
void dumpFacesAndHoles(const std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > &face_loops,
|
||||
const std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > &hole_loops) {
|
||||
std::map<carve::mesh::MeshSet<3>::vertex_t *, size_t> v_included;
|
||||
|
||||
for (std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> >::const_iterator
|
||||
i = face_loops.begin(); i != face_loops.end(); ++i) {
|
||||
for (size_t j = 0; j < (*i).size(); ++j) {
|
||||
if (v_included.find((*i)[j]) == v_included.end()) {
|
||||
size_t &p = v_included[(*i)[j]];
|
||||
p = v_included.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> >::const_iterator
|
||||
i = hole_loops.begin(); i != hole_loops.end(); ++i) {
|
||||
for (size_t j = 0; j < (*i).size(); ++j) {
|
||||
if (v_included.find((*i)[j]) == v_included.end()) {
|
||||
size_t &p = v_included[(*i)[j]];
|
||||
p = v_included.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
carve::line::PolylineSet fh;
|
||||
fh.vertices.resize(v_included.size());
|
||||
for (std::map<carve::mesh::MeshSet<3>::vertex_t *, size_t>::const_iterator
|
||||
i = v_included.begin(); i != v_included.end(); ++i) {
|
||||
fh.vertices[(*i).second].v = (*i).first->v;
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<size_t> connected;
|
||||
for (std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> >::const_iterator
|
||||
i = face_loops.begin(); i != face_loops.end(); ++i) {
|
||||
connected.clear();
|
||||
for (size_t j = 0; j < (*i).size(); ++j) {
|
||||
connected.push_back(v_included[(*i)[j]]);
|
||||
}
|
||||
fh.addPolyline(true, connected.begin(), connected.end());
|
||||
}
|
||||
for (std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> >::const_iterator
|
||||
i = hole_loops.begin(); i != hole_loops.end(); ++i) {
|
||||
connected.clear();
|
||||
for (size_t j = 0; j < (*i).size(); ++j) {
|
||||
connected.push_back(v_included[(*i)[j]]);
|
||||
}
|
||||
fh.addPolyline(true, connected.begin(), connected.end());
|
||||
}
|
||||
}
|
||||
|
||||
std::string out("/tmp/hole_merge.ply");
|
||||
::writePLY(out, &fh, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
std::string ptrstr(const T *ptr) {
|
||||
std::ostringstream s;
|
||||
@@ -1416,7 +1440,7 @@ namespace {
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> base_loop;
|
||||
std::list<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > hole_loops;
|
||||
|
||||
assembleBaseLoop(face, data, base_loop);
|
||||
bool face_edge_intersected = assembleBaseLoop(face, data, base_loop);
|
||||
|
||||
detail::FV2SMap::const_iterator fse_iter = data.face_split_edges.find(face);
|
||||
|
||||
@@ -1452,7 +1476,8 @@ namespace {
|
||||
|
||||
if (face_edges.find(std::make_pair(v1, v2)) == face_edges.end() &&
|
||||
face_edges.find(std::make_pair(v2, v1)) == face_edges.end()) {
|
||||
|
||||
// If the edge isn't part of the face perimeter, add it to
|
||||
// split_edges.
|
||||
split_edges.insert(ordered_edge(v1, v2));
|
||||
}
|
||||
}
|
||||
@@ -1517,9 +1542,13 @@ namespace {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Consider handling cases where one end of the edge touches the
|
||||
// perimeter, and where neither end does.
|
||||
}
|
||||
|
||||
std::vector<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > paths;
|
||||
std::vector<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > cuts;
|
||||
std::vector<std::vector<carve::mesh::MeshSet<3>::vertex_t *> > loops;
|
||||
|
||||
// Take the split edges and compose them into a set of paths and
|
||||
@@ -1528,67 +1557,73 @@ namespace {
|
||||
// of the face. Paths are made up of all the other edge segments,
|
||||
// and start and end at the face perimeter, or where they meet
|
||||
// another path (sometimes both cases will be true).
|
||||
composeEdgesIntoPaths(split_edges, base_loop, paths, loops);
|
||||
composeEdgesIntoPaths(split_edges, base_loop, paths, cuts, loops);
|
||||
|
||||
#if defined(CARVE_DEBUG)
|
||||
std::cerr << "### paths.size(): " << paths.size() << std::endl;
|
||||
std::cerr << "### cuts.size(): " << cuts.size() << std::endl;
|
||||
std::cerr << "### loops.size(): " << loops.size() << std::endl;
|
||||
#endif
|
||||
|
||||
if (!paths.size()) {
|
||||
// Loops found by composeEdgesIntoPaths() can't touch the
|
||||
// boundary, or each other, so we can deal with the no paths
|
||||
// case simply. The hole loops are the loops produced by
|
||||
// composeEdgesIntoPaths() oriented so that their signed area
|
||||
// wrt. the face is negative. The face loops are the base loop
|
||||
// plus the hole loops, reversed.
|
||||
// No complex paths.
|
||||
face_loops.push_back(base_loop);
|
||||
|
||||
for (size_t i = 0; i < loops.size(); ++i) {
|
||||
hole_loops.push_back(std::vector<carve::mesh::MeshSet<3>::vertex_t *>());
|
||||
hole_loops.back().reserve(loops[i].size()-1);
|
||||
std::copy(loops[i].begin(), loops[i].end()-1, std::back_inserter(hole_loops.back()));
|
||||
|
||||
face_loops.push_back(std::vector<carve::mesh::MeshSet<3>::vertex_t *>());
|
||||
face_loops.back().reserve(loops[i].size()-1);
|
||||
std::copy(loops[i].rbegin()+1, loops[i].rend(), std::back_inserter(face_loops.back()));
|
||||
|
||||
std::vector<carve::geom2d::P2> projected;
|
||||
projected.reserve(face_loops.back().size());
|
||||
for (size_t i = 0; i < face_loops.back().size(); ++i) {
|
||||
projected.push_back(face->project(face_loops.back()[i]->v));
|
||||
}
|
||||
|
||||
if (carve::geom2d::signedArea(projected) > 0.0) {
|
||||
std::swap(face_loops.back(), hole_loops.back());
|
||||
}
|
||||
}
|
||||
|
||||
// if there are holes, then they need to be merged with faces.
|
||||
if (hole_loops.size()) {
|
||||
mergeFacesAndHoles(face, face_loops, hole_loops, hooks);
|
||||
}
|
||||
} else {
|
||||
if (!processCrossingEdges(face, vertex_intersections, hooks, base_loop, paths, loops, face_loops)) {
|
||||
if (processCrossingEdges(face, vertex_intersections, hooks, base_loop, paths, face_loops)) {
|
||||
// Worked.
|
||||
} else {
|
||||
// complex case - fall back to old edge tracing code.
|
||||
#if defined(CARVE_DEBUG)
|
||||
std::cerr << "### processCrossingEdges failed. Falling back to edge tracing code" << std::endl;
|
||||
#endif
|
||||
for (V2Set::const_iterator i = split_edges.begin(); i != split_edges.end(); ++i) {
|
||||
face_edges.insert(std::make_pair((*i).first, (*i).second));
|
||||
face_edges.insert(std::make_pair((*i).second, (*i).first));
|
||||
for (size_t i = 0; i < paths.size(); ++i) {
|
||||
for (size_t j = 0; j < paths[i].size() - 1; ++j) {
|
||||
face_edges.insert(std::make_pair(paths[i][j], paths[i][j+1]));
|
||||
face_edges.insert(std::make_pair(paths[i][j+1], paths[i][j]));
|
||||
}
|
||||
}
|
||||
splitFace(face, face_edges, face_loops, hole_loops, vertex_intersections);
|
||||
|
||||
if (hole_loops.size()) {
|
||||
mergeFacesAndHoles(face, face_loops, hole_loops, hooks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now merge cuts and loops into face loops.
|
||||
|
||||
// every cut creates a hole.
|
||||
for (size_t i = 0; i < cuts.size(); ++i) {
|
||||
hole_loops.push_back(std::vector<carve::mesh::MeshSet<3>::vertex_t *>());
|
||||
hole_loops.back().reserve(2 * cuts[i].size() - 2);
|
||||
std::copy(cuts[i].begin(), cuts[i].end(), std::back_inserter(hole_loops.back()));
|
||||
if (cuts[i].size() > 2) {
|
||||
std::copy(cuts[i].rbegin() + 1, cuts[i].rend() - 1, std::back_inserter(hole_loops.back()));
|
||||
}
|
||||
}
|
||||
|
||||
// every loop creates a hole and a corresponding face.
|
||||
for (size_t i = 0; i < loops.size(); ++i) {
|
||||
hole_loops.push_back(std::vector<carve::mesh::MeshSet<3>::vertex_t *>());
|
||||
hole_loops.back().reserve(loops[i].size()-1);
|
||||
std::copy(loops[i].begin(), loops[i].end()-1, std::back_inserter(hole_loops.back()));
|
||||
|
||||
face_loops.push_back(std::vector<carve::mesh::MeshSet<3>::vertex_t *>());
|
||||
face_loops.back().reserve(loops[i].size()-1);
|
||||
std::copy(loops[i].rbegin()+1, loops[i].rend(), std::back_inserter(face_loops.back()));
|
||||
|
||||
std::vector<carve::geom2d::P2> projected;
|
||||
projected.reserve(face_loops.back().size());
|
||||
for (size_t i = 0; i < face_loops.back().size(); ++i) {
|
||||
projected.push_back(face->project(face_loops.back()[i]->v));
|
||||
}
|
||||
|
||||
if (carve::geom2d::signedArea(projected) > 0.0) {
|
||||
std::swap(face_loops.back(), hole_loops.back());
|
||||
}
|
||||
}
|
||||
|
||||
// if there are holes, then they need to be merged with faces.
|
||||
if (hole_loops.size()) {
|
||||
mergeFacesAndHoles(face, face_loops, hole_loops, hooks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+24
-34
@@ -501,10 +501,21 @@ bool carve::triangulate::detail::vertex_info::isClipable() const {
|
||||
|
||||
|
||||
size_t carve::triangulate::detail::removeDegeneracies(vertex_info *&begin, std::vector<carve::triangulate::tri_idx> &result) {
|
||||
vertex_info *v = begin;
|
||||
vertex_info *v;
|
||||
vertex_info *n;
|
||||
size_t count = 0;
|
||||
size_t remain = 0;
|
||||
|
||||
v = begin;
|
||||
do {
|
||||
v = v->next;
|
||||
++remain;
|
||||
} while (v != begin);
|
||||
|
||||
v = begin;
|
||||
do {
|
||||
if (remain < 4) break;
|
||||
|
||||
bool remove = false;
|
||||
if (v->p == v->next->p) {
|
||||
remove = true;
|
||||
@@ -533,11 +544,11 @@ size_t carve::triangulate::detail::removeDegeneracies(vertex_info *&begin, std::
|
||||
if (n == begin) begin = n->next;
|
||||
n->remove();
|
||||
count++;
|
||||
remain--;
|
||||
delete n;
|
||||
continue;
|
||||
} else {
|
||||
v = v->next;
|
||||
}
|
||||
|
||||
v = v->next;
|
||||
} while (v != begin);
|
||||
return count;
|
||||
}
|
||||
@@ -615,7 +626,7 @@ bool carve::triangulate::detail::doTriangulate(vertex_info *begin, std::vector<c
|
||||
std::cerr << "remain = " << remain << std::endl;
|
||||
#endif
|
||||
|
||||
while (vq.size()) {
|
||||
while (remain > 3 && vq.size()) {
|
||||
vertex_info *v = vq.pop();
|
||||
if (!v->isClipable()) {
|
||||
v->failed = true;
|
||||
@@ -639,10 +650,11 @@ bool carve::triangulate::detail::doTriangulate(vertex_info *begin, std::vector<c
|
||||
#endif
|
||||
|
||||
v->remove();
|
||||
remain--;
|
||||
if (v == begin) begin = v->next;
|
||||
delete v;
|
||||
|
||||
if (--remain == 3) break;
|
||||
|
||||
vq.updateVertex(n);
|
||||
vq.updateVertex(p);
|
||||
|
||||
@@ -676,27 +688,7 @@ bool carve::triangulate::detail::doTriangulate(vertex_info *begin, std::vector<c
|
||||
std::cerr << "doTriangulate complete; remain=" << remain << std::endl;
|
||||
#endif
|
||||
|
||||
bool ret = true;
|
||||
|
||||
if (remain > 3) {
|
||||
std::vector<carve::geom2d::P2> temp;
|
||||
temp.reserve(remain);
|
||||
vertex_info *v = begin;
|
||||
|
||||
do {
|
||||
temp.push_back(v->p);
|
||||
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.
|
||||
#if defined(CARVE_DEBUG)
|
||||
std::cerr << "skeleton remains. complete." << std::endl;
|
||||
#endif
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if defined(CARVE_DEBUG)
|
||||
std::cerr << "before removeDegeneracies: remain=" << remain << std::endl;
|
||||
#endif
|
||||
@@ -704,18 +696,16 @@ bool carve::triangulate::detail::doTriangulate(vertex_info *begin, std::vector<c
|
||||
#if defined(CARVE_DEBUG)
|
||||
std::cerr << "after removeDegeneracies: remain=" << remain << std::endl;
|
||||
#endif
|
||||
|
||||
if (remain > 3) {
|
||||
return splitAndResume(begin, result);
|
||||
}
|
||||
}
|
||||
|
||||
if (remain > 3) {
|
||||
return splitAndResume(begin, result);
|
||||
} else if (remain == 3) {
|
||||
if (remain == 3) {
|
||||
result.push_back(carve::triangulate::tri_idx(begin->idx, begin->next->idx, begin->next->next->idx));
|
||||
ret = true;
|
||||
} else {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
done:
|
||||
vertex_info *d = begin;
|
||||
do {
|
||||
vertex_info *n = d->next;
|
||||
@@ -723,7 +713,7 @@ bool carve::triangulate::detail::doTriangulate(vertex_info *begin, std::vector<c
|
||||
d = n;
|
||||
} while (d != begin);
|
||||
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace carve::mesh;
|
||||
using namespace carve::geom;
|
||||
typedef unsigned int uint;
|
||||
|
||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||
@@ -65,71 +66,183 @@ static int isFacePlanar(CSG_IFace &face, std::vector<carve::geom3d::Vector> &ver
|
||||
return 1;
|
||||
}
|
||||
|
||||
static MeshSet<3> *Carve_meshSetFromMeshes(std::vector<MeshSet<3>::mesh_t*> &meshes)
|
||||
static void Carve_copyMeshes(std::vector<MeshSet<3>::mesh_t*> &meshes, std::vector<MeshSet<3>::mesh_t*> &new_meshes)
|
||||
{
|
||||
std::vector<MeshSet<3>::mesh_t*> new_meshes;
|
||||
|
||||
std::vector<MeshSet<3>::mesh_t*>::iterator it = meshes.begin();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static MeshSet<3> *Carve_meshSetFromMeshes(std::vector<MeshSet<3>::mesh_t*> &meshes)
|
||||
{
|
||||
std::vector<MeshSet<3>::mesh_t*> new_meshes;
|
||||
|
||||
Carve_copyMeshes(meshes, new_meshes);
|
||||
|
||||
return new MeshSet<3>(new_meshes);
|
||||
}
|
||||
|
||||
static void Carve_getIntersectedOperandMeshes(std::vector<MeshSet<3>::mesh_t*> &meshes,
|
||||
std::vector<MeshSet<3>::aabb_t> &precomputedAABB,
|
||||
MeshSet<3>::aabb_t &otherAABB,
|
||||
static MeshSet<3> *Carve_meshSetFromTwoMeshes(std::vector<MeshSet<3>::mesh_t*> &left_meshes,
|
||||
std::vector<MeshSet<3>::mesh_t*> &right_meshes)
|
||||
{
|
||||
std::vector<MeshSet<3>::mesh_t*> new_meshes;
|
||||
|
||||
Carve_copyMeshes(left_meshes, new_meshes);
|
||||
Carve_copyMeshes(right_meshes, new_meshes);
|
||||
|
||||
return new MeshSet<3>(new_meshes);
|
||||
}
|
||||
|
||||
static bool Carve_checkEdgeFaceIntersections_do(carve::csg::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;
|
||||
}
|
||||
|
||||
static bool Carve_checkEdgeFaceIntersections(carve::csg::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(Carve_checkEdgeFaceIntersections_do(intersections, face_a, edge_b))
|
||||
return true;
|
||||
edge_b = edge_b->next;
|
||||
} while (edge_b != face_b->edge);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool Carve_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);
|
||||
}
|
||||
|
||||
static bool Carve_checkMeshSetInterseciton_do(carve::csg::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(Carve_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(Carve_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(!Carve_facesAreCoplanar(fa, fb)) {
|
||||
if(Carve_checkEdgeFaceIntersections(intersections, fa, fb)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool Carve_checkMeshSetInterseciton(RTreeNode<3, Face<3> *> *rtree_a, RTreeNode<3, Face<3> *> *rtree_b)
|
||||
{
|
||||
carve::csg::Intersections intersections;
|
||||
|
||||
return Carve_checkMeshSetInterseciton_do(intersections, rtree_a, rtree_b);
|
||||
}
|
||||
|
||||
static void Carve_getIntersectedOperandMeshes(std::vector<MeshSet<3>::mesh_t*> &meshes, MeshSet<3>::aabb_t &otherAABB,
|
||||
std::vector<MeshSet<3>::mesh_t*> &operandMeshes)
|
||||
{
|
||||
std::vector<MeshSet<3>::mesh_t*>::iterator it = meshes.begin();
|
||||
std::vector<MeshSet<3>::aabb_t>::iterator aabb_it = precomputedAABB.begin();
|
||||
std::vector<MeshSet<3>::aabb_t> usedAABB;
|
||||
std::vector< RTreeNode<3, Face<3> *> *> meshRTree;
|
||||
|
||||
while(it != meshes.end()) {
|
||||
MeshSet<3>::mesh_t *mesh = *it;
|
||||
MeshSet<3>::aabb_t aabb = mesh->getAABB();
|
||||
bool isIntersect = false;
|
||||
|
||||
std::vector<MeshSet<3>::aabb_t>::iterator used_it = usedAABB.begin();
|
||||
for(; used_it!=usedAABB.end(); used_it++) {
|
||||
MeshSet<3>::aabb_t usedAABB = *used_it;
|
||||
RTreeNode<3, Face<3> *> *rtree = RTreeNode<3, Face<3> *>::construct_STR(mesh->faces.begin(), mesh->faces.end(), 4, 4);
|
||||
|
||||
if(usedAABB.intersects(aabb) && usedAABB.intersects(otherAABB)) {
|
||||
isIntersect = true;
|
||||
break;
|
||||
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(operandRTree->bbox.intersects(otherAABB)) {
|
||||
if(Carve_checkMeshSetInterseciton(rtree, operandRTree)) {
|
||||
isIntersect = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!isIntersect) {
|
||||
operandMeshes.push_back(mesh);
|
||||
usedAABB.push_back(aabb);
|
||||
meshRTree.push_back(rtree);
|
||||
|
||||
it = meshes.erase(it);
|
||||
aabb_it = precomputedAABB.erase(aabb_it);
|
||||
}
|
||||
else {
|
||||
it++;
|
||||
aabb_it++;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<RTreeNode<3, Face<3> *> *>::iterator tree_it = meshRTree.begin();
|
||||
for(; tree_it != meshRTree.end(); tree_it++) {
|
||||
delete *tree_it;
|
||||
}
|
||||
}
|
||||
|
||||
static MeshSet<3> *Carve_getIntersectedOperand(std::vector<MeshSet<3>::mesh_t*> &meshes,
|
||||
std::vector<MeshSet<3>::aabb_t> &precomputedAABB,
|
||||
MeshSet<3>::aabb_t &otherAABB)
|
||||
static MeshSet<3> *Carve_getIntersectedOperand(std::vector<MeshSet<3>::mesh_t*> &meshes, MeshSet<3>::aabb_t &otherAABB)
|
||||
{
|
||||
std::vector<MeshSet<3>::mesh_t*> operandMeshes;
|
||||
Carve_getIntersectedOperandMeshes(meshes, precomputedAABB, otherAABB, operandMeshes);
|
||||
Carve_getIntersectedOperandMeshes(meshes, otherAABB, operandMeshes);
|
||||
|
||||
return Carve_meshSetFromMeshes(operandMeshes);
|
||||
}
|
||||
|
||||
static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly,
|
||||
std::vector<MeshSet<3>::aabb_t> &precomputedAABB,
|
||||
MeshSet<3>::aabb_t &otherAABB,
|
||||
carve::interpolate::FaceAttr<uint> &oface_num)
|
||||
{
|
||||
@@ -144,24 +257,36 @@ static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly,
|
||||
std::vector<MeshSet<3>::mesh_t*> orig_meshes =
|
||||
std::vector<MeshSet<3>::mesh_t*>(poly->meshes.begin(), poly->meshes.end());
|
||||
|
||||
MeshSet<3> *left = Carve_getIntersectedOperand(orig_meshes, precomputedAABB, otherAABB);
|
||||
MeshSet<3> *left = Carve_getIntersectedOperand(orig_meshes, otherAABB);
|
||||
|
||||
while(orig_meshes.size()) {
|
||||
MeshSet<3> *right = Carve_getIntersectedOperand(orig_meshes, precomputedAABB, otherAABB);
|
||||
MeshSet<3> *right = Carve_getIntersectedOperand(orig_meshes, otherAABB);
|
||||
|
||||
try {
|
||||
MeshSet<3> *result = csg.compute(left, right, carve::csg::CSG::UNION, NULL, carve::csg::CSG::CLASSIFY_EDGE);
|
||||
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);
|
||||
|
||||
delete left;
|
||||
delete right;
|
||||
|
||||
left = result;
|
||||
}
|
||||
}
|
||||
catch(carve::exception e) {
|
||||
std::cerr << "CSG failed, exception " << e.str() << std::endl;
|
||||
|
||||
MeshSet<3> *result = Carve_meshSetFromTwoMeshes(left->meshes, right->meshes);
|
||||
|
||||
delete left;
|
||||
delete right;
|
||||
|
||||
left = result;
|
||||
}
|
||||
catch(carve::exception e) {
|
||||
std::cerr << "CSG failed, exception " << e.str() << std::endl;
|
||||
|
||||
delete right;
|
||||
}
|
||||
catch(...) {
|
||||
delete left;
|
||||
delete right;
|
||||
@@ -173,38 +298,16 @@ static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly,
|
||||
return left;
|
||||
}
|
||||
|
||||
static MeshSet<3>::aabb_t Carve_computeAABB(MeshSet<3> *poly,
|
||||
std::vector<MeshSet<3>::aabb_t> &precomputedAABB)
|
||||
{
|
||||
MeshSet<3>::aabb_t overallAABB;
|
||||
std::vector<MeshSet<3>::mesh_t*>::iterator it = poly->meshes.begin();
|
||||
|
||||
for(; it!=poly->meshes.end(); it++) {
|
||||
MeshSet<3>::aabb_t aabb;
|
||||
MeshSet<3>::mesh_t *mesh = *it;
|
||||
|
||||
aabb = mesh->getAABB();
|
||||
precomputedAABB.push_back(aabb);
|
||||
|
||||
overallAABB.unionAABB(aabb);
|
||||
}
|
||||
|
||||
return overallAABB;
|
||||
}
|
||||
|
||||
static void Carve_prepareOperands(MeshSet<3> **left_r, MeshSet<3> **right_r,
|
||||
carve::interpolate::FaceAttr<uint> &oface_num)
|
||||
static void Carve_unionIntersections(MeshSet<3> **left_r, MeshSet<3> **right_r,
|
||||
carve::interpolate::FaceAttr<uint> &oface_num)
|
||||
{
|
||||
MeshSet<3> *left, *right;
|
||||
|
||||
std::vector<MeshSet<3>::aabb_t> left_precomputedAABB;
|
||||
std::vector<MeshSet<3>::aabb_t> right_precomputedAABB;
|
||||
MeshSet<3>::aabb_t leftAABB = (*left_r)->getAABB();
|
||||
MeshSet<3>::aabb_t rightAABB = (*right_r)->getAABB();
|
||||
|
||||
MeshSet<3>::aabb_t leftAABB = Carve_computeAABB(*left_r, left_precomputedAABB);
|
||||
MeshSet<3>::aabb_t rightAABB = Carve_computeAABB(*right_r, right_precomputedAABB);
|
||||
|
||||
left = Carve_unionIntersectingMeshes(*left_r, left_precomputedAABB, rightAABB, oface_num);
|
||||
right = Carve_unionIntersectingMeshes(*right_r, right_precomputedAABB, leftAABB, oface_num);
|
||||
left = Carve_unionIntersectingMeshes(*left_r, rightAABB, oface_num);
|
||||
right = Carve_unionIntersectingMeshes(*right_r, leftAABB, oface_num);
|
||||
|
||||
if(left != *left_r)
|
||||
delete *left_r;
|
||||
@@ -226,9 +329,9 @@ static MeshSet<3> *Carve_addMesh(CSG_FaceIteratorDescriptor &face_it,
|
||||
|
||||
while (!vertex_it.Done(vertex_it.it)) {
|
||||
vertex_it.Fill(vertex_it.it,&vertex);
|
||||
vertices.push_back(carve::geom::VECTOR(vertex.position[0],
|
||||
vertex.position[1],
|
||||
vertex.position[2]));
|
||||
vertices.push_back(VECTOR(vertex.position[0],
|
||||
vertex.position[1],
|
||||
vertex.position[2]));
|
||||
vertex_it.Step(vertex_it.it);
|
||||
}
|
||||
|
||||
@@ -492,7 +595,7 @@ BoolOpState BOP_performBooleanOperation(BoolOpType opType,
|
||||
CSG_VertexIteratorDescriptor obBVertices)
|
||||
{
|
||||
carve::csg::CSG::OP op;
|
||||
MeshSet<3> *left, *right, *output;
|
||||
MeshSet<3> *left, *right, *output = NULL;
|
||||
carve::csg::CSG csg;
|
||||
carve::geom3d::Vector min, max;
|
||||
carve::interpolate::FaceAttr<uint> oface_num;
|
||||
@@ -515,8 +618,6 @@ BoolOpState BOP_performBooleanOperation(BoolOpType opType,
|
||||
left = Carve_addMesh(obAFaces, obAVertices, oface_num, num_origfaces );
|
||||
right = Carve_addMesh(obBFaces, obBVertices, oface_num, num_origfaces );
|
||||
|
||||
Carve_prepareOperands(&left, &right, oface_num);
|
||||
|
||||
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;
|
||||
@@ -544,6 +645,23 @@ BoolOpState BOP_performBooleanOperation(BoolOpType opType,
|
||||
left->transform(fwd_r);
|
||||
right->transform(fwd_r);
|
||||
|
||||
// prepare operands for actual boolean operation. it's needed because operands might consist of
|
||||
// several intersecting meshes and in case if another operands intersect an edge loop of intersecting that
|
||||
// meshes tesselation 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(&left, &right, oface_num);
|
||||
|
||||
if(left->meshes.size() == 0 || right->meshes.size()==0) {
|
||||
// normally sohuldn'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
|
||||
|
||||
delete left;
|
||||
delete right;
|
||||
|
||||
return BOP_ERROR;
|
||||
}
|
||||
|
||||
csg.hooks.registerHook(new carve::csg::CarveTriangulator, carve::csg::CSG::Hooks::PROCESS_OUTPUT_FACE_BIT);
|
||||
|
||||
oface_num.installHooks(csg);
|
||||
|
||||
@@ -606,6 +606,7 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
|
||||
|
||||
col = split.column()
|
||||
col.prop(cmat, "sample_as_light")
|
||||
col.prop(mat, "pass_index")
|
||||
|
||||
|
||||
class CyclesTexture_PT_context(CyclesButtonsPanel, Panel):
|
||||
|
||||
@@ -203,7 +203,10 @@ void BlenderSession::render()
|
||||
b_rlay = *b_iter;
|
||||
|
||||
/* add passes */
|
||||
if(session_params.device.type == DEVICE_CPU) { /* todo */
|
||||
vector<Pass> passes;
|
||||
Pass::add(PASS_COMBINED, passes);
|
||||
|
||||
if(session_params.device.advanced_shading) {
|
||||
BL::RenderLayer::passes_iterator b_pass_iter;
|
||||
|
||||
for(b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
|
||||
@@ -211,12 +214,13 @@ void BlenderSession::render()
|
||||
PassType pass_type = get_pass_type(b_pass);
|
||||
|
||||
if(pass_type != PASS_NONE)
|
||||
Pass::add(pass_type, buffer_params.passes);
|
||||
Pass::add(pass_type, passes);
|
||||
}
|
||||
}
|
||||
|
||||
scene->film->passes = buffer_params.passes;
|
||||
scene->film->need_update = true;
|
||||
buffer_params.passes = passes;
|
||||
scene->film->passes = passes;
|
||||
scene->film->tag_update(scene);
|
||||
|
||||
/* update session */
|
||||
session->reset(buffer_params, session_params.samples);
|
||||
|
||||
@@ -183,6 +183,9 @@ Device *Device::create(DeviceInfo& info, bool background, int threads)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(device)
|
||||
device->info = info;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
string id;
|
||||
int num;
|
||||
bool display_device;
|
||||
bool advanced_shading;
|
||||
vector<DeviceInfo> multi_devices;
|
||||
|
||||
DeviceInfo()
|
||||
@@ -59,6 +60,7 @@ public:
|
||||
id = "CPU";
|
||||
num = 0;
|
||||
display_device = false;
|
||||
advanced_shading = true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -101,10 +103,8 @@ protected:
|
||||
public:
|
||||
virtual ~Device() {}
|
||||
|
||||
virtual bool support_full_kernel() = 0;
|
||||
|
||||
/* info */
|
||||
virtual string description() = 0;
|
||||
DeviceInfo info;
|
||||
virtual const string& error_message() { return error_msg; }
|
||||
|
||||
/* regular memory */
|
||||
|
||||
@@ -72,16 +72,11 @@ public:
|
||||
kernel_globals_free(kg);
|
||||
}
|
||||
|
||||
bool support_full_kernel()
|
||||
bool support_advanced_shading()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
string description()
|
||||
{
|
||||
return system_cpu_brand_string();
|
||||
}
|
||||
|
||||
void mem_alloc(device_memory& mem, MemoryType type)
|
||||
{
|
||||
mem.device_pointer = mem.data_pointer;
|
||||
@@ -271,6 +266,7 @@ void device_cpu_info(vector<DeviceInfo>& devices)
|
||||
info.description = system_cpu_brand_string();
|
||||
info.id = "CPU";
|
||||
info.num = 0;
|
||||
info.advanced_shading = true;
|
||||
|
||||
devices.insert(devices.begin(), info);
|
||||
}
|
||||
|
||||
@@ -106,11 +106,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static int cuda_align_up(int& offset, int alignment)
|
||||
{
|
||||
return (offset + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define cuda_abort()
|
||||
#else
|
||||
@@ -194,26 +189,6 @@ public:
|
||||
cuda_assert(cuCtxDetach(cuContext))
|
||||
}
|
||||
|
||||
bool support_full_kernel()
|
||||
{
|
||||
int major, minor;
|
||||
cuDeviceComputeCapability(&major, &minor, cuDevId);
|
||||
|
||||
return (major >= 2);
|
||||
}
|
||||
|
||||
string description()
|
||||
{
|
||||
/* print device information */
|
||||
char deviceName[256];
|
||||
|
||||
cuda_push_context();
|
||||
cuDeviceGetName(deviceName, 256, cuDevId);
|
||||
cuda_pop_context();
|
||||
|
||||
return string("CUDA ") + deviceName;
|
||||
}
|
||||
|
||||
bool support_device(bool experimental)
|
||||
{
|
||||
if(!experimental) {
|
||||
@@ -505,7 +480,7 @@ public:
|
||||
offset += sizeof(d_rng_state);
|
||||
|
||||
int sample = task.sample;
|
||||
offset = cuda_align_up(offset, __alignof(sample));
|
||||
offset = align_up(offset, __alignof(sample));
|
||||
|
||||
cuda_assert(cuParamSeti(cuPathTrace, offset, task.sample))
|
||||
offset += sizeof(task.sample);
|
||||
@@ -569,7 +544,7 @@ public:
|
||||
offset += sizeof(d_buffer);
|
||||
|
||||
int sample = task.sample;
|
||||
offset = cuda_align_up(offset, __alignof(sample));
|
||||
offset = align_up(offset, __alignof(sample));
|
||||
|
||||
cuda_assert(cuParamSeti(cuFilmConvert, offset, task.sample))
|
||||
offset += sizeof(task.sample);
|
||||
@@ -638,7 +613,7 @@ public:
|
||||
offset += sizeof(d_offset);
|
||||
|
||||
int shader_eval_type = task.shader_eval_type;
|
||||
offset = cuda_align_up(offset, __alignof(shader_eval_type));
|
||||
offset = align_up(offset, __alignof(shader_eval_type));
|
||||
|
||||
cuda_assert(cuParamSeti(cuDisplace, offset, task.shader_eval_type))
|
||||
offset += sizeof(task.shader_eval_type);
|
||||
@@ -881,6 +856,10 @@ void device_cuda_info(vector<DeviceInfo>& devices)
|
||||
info.id = string_printf("CUDA_%d", num);
|
||||
info.num = num;
|
||||
|
||||
int major, minor;
|
||||
cuDeviceComputeCapability(&major, &minor, num);
|
||||
info.advanced_shading = (major >= 2);
|
||||
|
||||
/* if device has a kernel timeout, assume it is used for display */
|
||||
if(cuDeviceGetAttribute(&attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num) == CUDA_SUCCESS && attr == 1) {
|
||||
info.display_device = true;
|
||||
|
||||
@@ -76,16 +76,6 @@ public:
|
||||
delete sub.device;
|
||||
}
|
||||
|
||||
bool support_full_kernel()
|
||||
{
|
||||
foreach(SubDevice& sub, devices) {
|
||||
if(!sub.device->support_full_kernel())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const string& error_message()
|
||||
{
|
||||
foreach(SubDevice& sub, devices) {
|
||||
@@ -99,38 +89,6 @@ public:
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
string description()
|
||||
{
|
||||
/* create map to find duplicate descriptions */
|
||||
map<string, int> dupli_map;
|
||||
map<string, int>::iterator dt;
|
||||
|
||||
foreach(SubDevice& sub, devices) {
|
||||
string key = sub.device->description();
|
||||
|
||||
if(dupli_map.find(key) == dupli_map.end())
|
||||
dupli_map[key] = 1;
|
||||
else
|
||||
dupli_map[key]++;
|
||||
}
|
||||
|
||||
/* generate string */
|
||||
stringstream desc;
|
||||
bool first = true;
|
||||
|
||||
for(dt = dupli_map.begin(); dt != dupli_map.end(); dt++) {
|
||||
if(!first) desc << ", ";
|
||||
first = false;
|
||||
|
||||
if(dt->second > 1)
|
||||
desc << dt->second << "x " << dt->first;
|
||||
else
|
||||
desc << dt->first;
|
||||
}
|
||||
|
||||
return desc.str();
|
||||
}
|
||||
|
||||
bool load_kernels(bool experimental)
|
||||
{
|
||||
foreach(SubDevice& sub, devices)
|
||||
@@ -344,6 +302,8 @@ static void device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool
|
||||
map<string, int>::iterator dt;
|
||||
int num_added = 0, num_display = 0;
|
||||
|
||||
info.advanced_shading = true;
|
||||
|
||||
foreach(DeviceInfo& subinfo, devices) {
|
||||
if(subinfo.type == type) {
|
||||
if(subinfo.display_device) {
|
||||
@@ -363,6 +323,8 @@ static void device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool
|
||||
info.multi_devices.push_back(subinfo);
|
||||
if(subinfo.display_device)
|
||||
info.display_device = true;
|
||||
if(!subinfo.advanced_shading)
|
||||
info.advanced_shading = false;
|
||||
num_added++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,24 +57,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
bool support_full_kernel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string description()
|
||||
{
|
||||
RPCSend snd(socket, "description");
|
||||
snd.write();
|
||||
|
||||
RPCReceive rcv(socket);
|
||||
string desc_string;
|
||||
|
||||
*rcv.archive & desc_string;
|
||||
|
||||
return desc_string + " (remote)";
|
||||
}
|
||||
|
||||
void mem_alloc(device_memory& mem, MemoryType type)
|
||||
{
|
||||
#if 0
|
||||
|
||||
@@ -453,20 +453,6 @@ public:
|
||||
clReleaseContext(cxContext);
|
||||
}
|
||||
|
||||
bool support_full_kernel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string description()
|
||||
{
|
||||
char name[1024];
|
||||
|
||||
clGetDeviceInfo(cdDevice, CL_DEVICE_NAME, sizeof(name), &name, NULL);
|
||||
|
||||
return string("OpenCL ") + name;
|
||||
}
|
||||
|
||||
void mem_alloc(device_memory& mem, MemoryType type)
|
||||
{
|
||||
size_t size = mem.memory_size();
|
||||
@@ -750,6 +736,7 @@ void device_opencl_info(vector<DeviceInfo>& devices)
|
||||
info.num = num;
|
||||
/* we don't know if it's used for display, but assume it is */
|
||||
info.display_device = true;
|
||||
info.advanced_shading = false;
|
||||
|
||||
devices.push_back(info);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
|
||||
ShaderData sd;
|
||||
float3 eval;
|
||||
|
||||
#ifdef __BACKGROUND_MIS__
|
||||
if(ls->type == LIGHT_BACKGROUND) {
|
||||
Ray ray;
|
||||
ray.D = ls->D;
|
||||
@@ -36,7 +37,9 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
|
||||
shader_setup_from_background(kg, &sd, &ray);
|
||||
eval = shader_eval_background(kg, &sd, 0);
|
||||
}
|
||||
else {
|
||||
else
|
||||
#endif
|
||||
{
|
||||
shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v);
|
||||
ls->Ng = sd.Ng;
|
||||
|
||||
@@ -113,7 +116,8 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
|
||||
|
||||
if(ls.shader & SHADER_CAST_SHADOW) {
|
||||
/* setup ray */
|
||||
ray->P = ray_offset(sd->P, sd->Ng);
|
||||
bool transmit = (dot(sd->Ng, ls.D) < 0.0f);
|
||||
ray->P = ray_offset(sd->P, (transmit)? -sd->Ng: sd->Ng);
|
||||
|
||||
if(ls.t == FLT_MAX) {
|
||||
/* distant light */
|
||||
@@ -164,6 +168,7 @@ __device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag,
|
||||
float3 L = shader_eval_background(kg, &sd, path_flag);
|
||||
shader_release(kg, &sd);
|
||||
|
||||
#ifdef __BACKGROUND_MIS__
|
||||
/* check if background light exists or if we should skip pdf */
|
||||
int res = kernel_data.integrator.pdf_background_res;
|
||||
|
||||
@@ -175,6 +180,7 @@ __device float3 indirect_background(KernelGlobals *kg, Ray *ray, int path_flag,
|
||||
|
||||
return L*mis_weight;
|
||||
}
|
||||
#endif
|
||||
|
||||
return L;
|
||||
#else
|
||||
|
||||
@@ -59,7 +59,7 @@ __device void kernel_film_tonemap(KernelGlobals *kg,
|
||||
buffer += index*kernel_data.film.pass_stride;
|
||||
|
||||
/* map colors */
|
||||
float4 irradiance = *(float4*)buffer;
|
||||
float4 irradiance = *((__global float4*)buffer);
|
||||
float4 float_result = film_map(kg, irradiance, sample);
|
||||
uchar4 byte_result = film_float_to_byte(float_result);
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
|
||||
ls->D = -D;
|
||||
ls->t = FLT_MAX;
|
||||
}
|
||||
#ifdef __BACKGROUND_MIS__
|
||||
else if(type == LIGHT_BACKGROUND) {
|
||||
/* infinite area light (e.g. light dome or env light) */
|
||||
float3 D = background_light_sample(kg, randu, randv, pdf);
|
||||
@@ -201,6 +202,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
|
||||
ls->D = -D;
|
||||
ls->t = FLT_MAX;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
ls->P = make_float3(data0.y, data0.z, data0.w);
|
||||
|
||||
|
||||
@@ -20,32 +20,23 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
__device_inline void kernel_write_pass_float(__global float *buffer, int sample, float value)
|
||||
{
|
||||
float *buf = buffer;
|
||||
__global float *buf = buffer;
|
||||
*buf = (sample == 0)? value: *buf + value;
|
||||
}
|
||||
|
||||
__device_inline void kernel_write_pass_float3(__global float *buffer, int sample, float3 value)
|
||||
{
|
||||
float3 *buf = (float3*)buffer;
|
||||
__global float3 *buf = (__global float3*)buffer;
|
||||
*buf = (sample == 0)? value: *buf + value;
|
||||
}
|
||||
|
||||
__device_inline void kernel_write_pass_float4(__global float *buffer, int sample, float4 value)
|
||||
{
|
||||
float4 *buf = (float4*)buffer;
|
||||
__global float4 *buf = (__global float4*)buffer;
|
||||
*buf = (sample == 0)? value: *buf + value;
|
||||
}
|
||||
|
||||
__device_inline void kernel_clear_passes(__global float *buffer, int sample, int pass_stride)
|
||||
{
|
||||
#ifdef __PASSES__
|
||||
if(sample == 0 && pass_stride != 4)
|
||||
for(int i = 4; i < pass_stride; i++)
|
||||
buffer[i] = 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
__device void kernel_write_data_passes(KernelGlobals *kg, __global float *buffer, PathRadiance *L,
|
||||
__device_inline void kernel_write_data_passes(KernelGlobals *kg, __global float *buffer, PathRadiance *L,
|
||||
ShaderData *sd, int sample, int path_flag, float3 throughput)
|
||||
{
|
||||
#ifdef __PASSES__
|
||||
@@ -95,7 +86,7 @@ __device void kernel_write_data_passes(KernelGlobals *kg, __global float *buffer
|
||||
#endif
|
||||
}
|
||||
|
||||
__device void kernel_write_light_passes(KernelGlobals *kg, __global float *buffer, PathRadiance *L, int sample)
|
||||
__device_inline void kernel_write_light_passes(KernelGlobals *kg, __global float *buffer, PathRadiance *L, int sample)
|
||||
{
|
||||
#ifdef __PASSES__
|
||||
int flag = kernel_data.film.pass_flag;
|
||||
|
||||
@@ -220,9 +220,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
|
||||
|
||||
path_radiance_init(&L, kernel_data.film.use_light_pass);
|
||||
|
||||
#ifdef __EMISSION__
|
||||
float ray_pdf = 0.0f;
|
||||
#endif
|
||||
PathState state;
|
||||
int rng_offset = PRNG_BASE_NUM;
|
||||
|
||||
@@ -239,11 +237,13 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
|
||||
if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) {
|
||||
L_transparent += average(throughput);
|
||||
}
|
||||
#ifdef __BACKGROUND__
|
||||
else {
|
||||
/* sample background shader */
|
||||
float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf);
|
||||
path_radiance_accum_background(&L, throughput, L_background, state.bounce);
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -342,9 +342,8 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
|
||||
path_radiance_bsdf_bounce(&L, &throughput, &bsdf_eval, bsdf_pdf, state.bounce, label);
|
||||
|
||||
/* set labels */
|
||||
#if defined(__EMISSION__) || defined(__BACKGROUND__)
|
||||
ray_pdf = bsdf_pdf;
|
||||
#endif
|
||||
if(!(label & LABEL_TRANSPARENT))
|
||||
ray_pdf = bsdf_pdf;
|
||||
|
||||
/* update path state */
|
||||
path_state_next(kg, &state, label);
|
||||
@@ -377,8 +376,6 @@ __device void kernel_path_trace(KernelGlobals *kg,
|
||||
rng_state += index;
|
||||
buffer += index*pass_stride;
|
||||
|
||||
kernel_clear_passes(buffer, sample, pass_stride);
|
||||
|
||||
/* initialize random numbers */
|
||||
RNG rng;
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __OSL__
|
||||
|
||||
#include "osl_shader.h"
|
||||
@@ -301,7 +300,7 @@ __device_inline void _shader_bsdf_multi_eval(const ShaderData *sd, const float3
|
||||
}
|
||||
}
|
||||
|
||||
*pdf = sum_pdf/sum_sample_weight;
|
||||
*pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -70,9 +70,8 @@ CCL_NAMESPACE_BEGIN
|
||||
#ifdef __KERNEL_ADV_SHADING__
|
||||
#define __MULTI_CLOSURE__
|
||||
#define __TRANSPARENT_SHADOWS__
|
||||
#ifdef __KERNEL_CPU__
|
||||
#define __PASSES__
|
||||
#endif
|
||||
#define __BACKGROUND_MIS__
|
||||
#endif
|
||||
|
||||
//#define __MULTI_LIGHT__
|
||||
@@ -185,6 +184,9 @@ typedef float3 PathThroughput;
|
||||
struct PathRadiance {
|
||||
int use_light_pass;
|
||||
|
||||
float3 emission;
|
||||
float3 background;
|
||||
|
||||
float3 indirect;
|
||||
float3 direct_throughput;
|
||||
float3 direct_emission;
|
||||
@@ -200,9 +202,6 @@ struct PathRadiance {
|
||||
float3 indirect_diffuse;
|
||||
float3 indirect_glossy;
|
||||
float3 indirect_transmission;
|
||||
|
||||
float3 emission;
|
||||
float3 background;
|
||||
};
|
||||
|
||||
struct BsdfEval {
|
||||
|
||||
@@ -71,7 +71,7 @@ int BufferParams::get_passes_size()
|
||||
foreach(Pass& pass, passes)
|
||||
size += pass.components;
|
||||
|
||||
return size;
|
||||
return align_up(size, 4);
|
||||
}
|
||||
|
||||
/* Render Buffers */
|
||||
@@ -130,7 +130,7 @@ bool RenderBuffers::copy_from_device()
|
||||
if(!buffer.device_pointer)
|
||||
return false;
|
||||
|
||||
device->mem_copy_from(buffer, 0, params.width, params.height, sizeof(float4));
|
||||
device->mem_copy_from(buffer, 0, params.width, params.height, params.get_passes_size()*sizeof(float));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -157,10 +157,17 @@ bool RenderBuffers::get_pass(PassType type, float exposure, int sample, int comp
|
||||
assert(pass.components == components);
|
||||
|
||||
/* scalar */
|
||||
for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
|
||||
float f = *in;
|
||||
|
||||
pixels[0] = f*scale_exposure;
|
||||
if(type == PASS_DEPTH) {
|
||||
for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
|
||||
float f = *in;
|
||||
pixels[0] = (f == 0.0f)? 1e10f: f*scale_exposure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
|
||||
float f = *in;
|
||||
pixels[0] = f*scale_exposure;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(components == 3) {
|
||||
|
||||
@@ -21,12 +21,20 @@
|
||||
#include "film.h"
|
||||
#include "scene.h"
|
||||
|
||||
#include "util_algorithm.h"
|
||||
#include "util_foreach.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Pass */
|
||||
|
||||
static bool compare_pass_order(const Pass& a, const Pass& b)
|
||||
{
|
||||
if(a.components == b.components)
|
||||
return (a.type < b.type);
|
||||
return (a.components > b.components);
|
||||
}
|
||||
|
||||
void Pass::add(PassType type, vector<Pass>& passes)
|
||||
{
|
||||
Pass pass;
|
||||
@@ -106,6 +114,10 @@ void Pass::add(PassType type, vector<Pass>& passes)
|
||||
}
|
||||
|
||||
passes.push_back(pass);
|
||||
|
||||
/* order from by components, to ensure alignment so passes with size 4
|
||||
come first and then passes with size 1 */
|
||||
sort(passes.begin(), passes.end(), compare_pass_order);
|
||||
}
|
||||
|
||||
bool Pass::equals(const vector<Pass>& A, const vector<Pass>& B)
|
||||
@@ -219,6 +231,8 @@ void Film::device_update(Device *device, DeviceScene *dscene)
|
||||
kfilm->pass_stride += pass.components;
|
||||
}
|
||||
|
||||
kfilm->pass_stride = align_up(kfilm->pass_stride, 4);
|
||||
|
||||
need_update = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -402,6 +402,16 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
|
||||
|
||||
float4 *light_data = dscene->light_data.resize(scene->lights.size()*LIGHT_SIZE);
|
||||
|
||||
if(!device->info.advanced_shading) {
|
||||
/* remove unsupported light */
|
||||
foreach(Light *light, scene->lights) {
|
||||
if(light->type == LIGHT_BACKGROUND) {
|
||||
scene->lights.erase(std::remove(scene->lights.begin(), scene->lights.end(), light), scene->lights.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < scene->lights.size(); i++) {
|
||||
Light *light = scene->lights[i];
|
||||
float3 co = light->co;
|
||||
|
||||
@@ -58,7 +58,7 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
|
||||
}
|
||||
|
||||
bool sunsky_done = false;
|
||||
bool use_multi_closure = device->support_full_kernel();
|
||||
bool use_multi_closure = device->info.advanced_shading;
|
||||
|
||||
for(i = 0; i < scene->shaders.size(); i++) {
|
||||
Shader *shader = scene->shaders[i];
|
||||
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
{
|
||||
thread_scoped_lock lock(progress_mutex);
|
||||
|
||||
start_time = start_time;
|
||||
start_time = start_time_;
|
||||
}
|
||||
|
||||
void set_sample(int sample_, double sample_time_)
|
||||
|
||||
@@ -277,6 +277,11 @@ __device float4 make_float4(float x, float y, float z, float w)
|
||||
return a;
|
||||
}
|
||||
|
||||
__device int align_up(int offset, int alignment)
|
||||
{
|
||||
return (offset + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -65,8 +65,8 @@ class MEM_CacheLimiter;
|
||||
|
||||
#ifndef __MEM_cache_limiter_c_api_h_included__
|
||||
extern "C" {
|
||||
extern void MEM_CacheLimiter_set_maximum(intptr_t m);
|
||||
extern intptr_t MEM_CacheLimiter_get_maximum();
|
||||
extern void MEM_CacheLimiter_set_maximum(size_t m);
|
||||
extern size_t MEM_CacheLimiter_get_maximum();
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -125,7 +125,7 @@ class MEM_CacheLimiter {
|
||||
public:
|
||||
typedef typename std::list<MEM_CacheLimiterHandle<T> *,
|
||||
MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator iterator;
|
||||
typedef intptr_t (*MEM_CacheLimiter_DataSize_Func) (void *data);
|
||||
typedef size_t (*MEM_CacheLimiter_DataSize_Func) (void *data);
|
||||
MEM_CacheLimiter(MEM_CacheLimiter_DataSize_Func getDataSize_)
|
||||
: getDataSize(getDataSize_) {
|
||||
}
|
||||
@@ -146,8 +146,8 @@ public:
|
||||
delete handle;
|
||||
}
|
||||
void enforce_limits() {
|
||||
intptr_t max = MEM_CacheLimiter_get_maximum();
|
||||
intptr_t mem_in_use, cur_size;
|
||||
size_t max = MEM_CacheLimiter_get_maximum();
|
||||
size_t mem_in_use, cur_size;
|
||||
|
||||
if (max == 0) {
|
||||
return;
|
||||
@@ -188,8 +188,8 @@ public:
|
||||
handle->me = it;
|
||||
}
|
||||
private:
|
||||
intptr_t total_size() {
|
||||
intptr_t size = 0;
|
||||
size_t total_size() {
|
||||
size_t size = 0;
|
||||
for (iterator it = queue.begin(); it != queue.end(); it++) {
|
||||
size+= getDataSize((*it)->get()->get_data());
|
||||
}
|
||||
|
||||
@@ -42,10 +42,10 @@ typedef struct MEM_CacheLimiterHandle_s MEM_CacheLimiterHandleC;
|
||||
typedef void(*MEM_CacheLimiter_Destruct_Func)(void*);
|
||||
|
||||
/* function used to measure stored data element size */
|
||||
typedef intptr_t(*MEM_CacheLimiter_DataSize_Func) (void*);
|
||||
typedef size_t(*MEM_CacheLimiter_DataSize_Func) (void*);
|
||||
|
||||
#ifndef MEM_CACHELIMITER_H
|
||||
extern void MEM_CacheLimiter_set_maximum(int m);
|
||||
extern void MEM_CacheLimiter_set_maximum(size_t m);
|
||||
extern int MEM_CacheLimiter_get_maximum(void);
|
||||
#endif // MEM_CACHELIMITER_H
|
||||
/**
|
||||
|
||||
@@ -29,18 +29,18 @@
|
||||
#include "MEM_CacheLimiter.h"
|
||||
#include "MEM_CacheLimiterC-Api.h"
|
||||
|
||||
static intptr_t & get_max()
|
||||
static size_t & get_max()
|
||||
{
|
||||
static intptr_t m = 32*1024*1024;
|
||||
static size_t m = 32*1024*1024;
|
||||
return m;
|
||||
}
|
||||
|
||||
void MEM_CacheLimiter_set_maximum(intptr_t m)
|
||||
void MEM_CacheLimiter_set_maximum(size_t m)
|
||||
{
|
||||
get_max() = m;
|
||||
}
|
||||
|
||||
intptr_t MEM_CacheLimiter_get_maximum()
|
||||
size_t MEM_CacheLimiter_get_maximum()
|
||||
{
|
||||
return get_max();
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ def add_object_align_init(context, operator):
|
||||
properties = operator.properties if operator is not None else None
|
||||
|
||||
space_data = context.space_data
|
||||
if space_data.type != 'VIEW_3D':
|
||||
if space_data and space_data.type != 'VIEW_3D':
|
||||
space_data = None
|
||||
|
||||
# location
|
||||
|
||||
@@ -9,3 +9,6 @@ settings.default_search_size = 100
|
||||
settings.default_frames_limit = 0
|
||||
settings.default_pattern_match = 'PREV_FRAME'
|
||||
settings.default_margin = 0
|
||||
settings.use_default_red_channel = True
|
||||
settings.use_default_green_channel = True
|
||||
settings.use_default_blue_channel = True
|
||||
|
||||
@@ -9,3 +9,6 @@ settings.default_search_size = 61
|
||||
settings.default_frames_limit = 0
|
||||
settings.default_pattern_match = 'KEYFRAME'
|
||||
settings.default_margin = 0
|
||||
settings.use_default_red_channel = True
|
||||
settings.use_default_green_channel = True
|
||||
settings.use_default_blue_channel = True
|
||||
|
||||
@@ -9,3 +9,6 @@ settings.default_search_size = 300
|
||||
settings.default_frames_limit = 0
|
||||
settings.default_pattern_match = 'PREV_FRAME'
|
||||
settings.default_margin = 5
|
||||
settings.use_default_red_channel = True
|
||||
settings.use_default_green_channel = True
|
||||
settings.use_default_blue_channel = True
|
||||
|
||||
@@ -90,6 +90,34 @@ def CLIP_track_view_selected(sc, track):
|
||||
return False
|
||||
|
||||
|
||||
def CLIP_default_settings_from_track(clip, track):
|
||||
settings = clip.tracking.settings
|
||||
|
||||
width = clip.size[0]
|
||||
height = clip.size[1]
|
||||
|
||||
pattern = track.pattern_max - track.pattern_min
|
||||
search = track.search_max - track.search_min
|
||||
|
||||
pattern[0] = pattern[0] * clip.size[0]
|
||||
pattern[1] = pattern[1] * clip.size[1]
|
||||
|
||||
search[0] = search[0] * clip.size[0]
|
||||
search[1] = search[1] * clip.size[1]
|
||||
|
||||
settings.default_tracker = track.tracker
|
||||
settings.default_pyramid_levels = track.pyramid_levels
|
||||
settings.default_correlation_min = track.correlation_min
|
||||
settings.default_pattern_size = max(pattern[0], pattern[1])
|
||||
settings.default_search_size = max(search[0], search[1])
|
||||
settings.default_frames_limit = track.frames_limit
|
||||
settings.default_pattern_match = track.pattern_match
|
||||
settings.default_margin = track.margin
|
||||
settings.use_default_red_channel = track.use_red_channel
|
||||
settings.use_default_green_channel = track.use_green_channel
|
||||
settings.use_default_blue_channel = track.use_blue_channel
|
||||
|
||||
|
||||
class CLIP_OT_track_to_empty(Operator):
|
||||
"""Create an Empty object which will be copying movement of active track"""
|
||||
|
||||
@@ -805,3 +833,29 @@ class CLIP_OT_setup_tracking_scene(Operator):
|
||||
self._setupObjects(context)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
class CLIP_OT_track_settings_as_default(Operator):
|
||||
"""Copy tracking settings from active track to default settings"""
|
||||
|
||||
bl_idname = "clip.track_settings_as_default"
|
||||
bl_label = "Track Settings As Default"
|
||||
bl_options = {'UNDO', 'REGISTER'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
sc = context.space_data
|
||||
|
||||
if sc.type != 'CLIP_EDITOR':
|
||||
return False
|
||||
|
||||
clip = sc.clip
|
||||
|
||||
return clip and clip.tracking.tracks.active
|
||||
|
||||
def execute(self, context):
|
||||
sc = context.space_data
|
||||
clip = sc.clip
|
||||
|
||||
CLIP_default_settings_from_track(clip, clip.tracking.tracks.active)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -20,7 +20,10 @@
|
||||
|
||||
import bpy
|
||||
from bpy.types import Operator
|
||||
from bpy.props import StringProperty, BoolProperty, EnumProperty, IntProperty
|
||||
from bpy.props import (StringProperty,
|
||||
BoolProperty,
|
||||
EnumProperty,
|
||||
IntProperty)
|
||||
|
||||
|
||||
class SelectPattern(Operator):
|
||||
@@ -54,7 +57,7 @@ class SelectPattern(Operator):
|
||||
pattern_match = fnmatch.fnmatchcase
|
||||
else:
|
||||
pattern_match = (lambda a, b:
|
||||
fnmatch.fnmatchcase(a.upper(), b.upper()))
|
||||
fnmatch.fnmatchcase(a.upper(), b.upper()))
|
||||
is_ebone = False
|
||||
obj = context.object
|
||||
if obj and obj.mode == 'POSE':
|
||||
@@ -489,9 +492,8 @@ class ShapeTransfer(Operator):
|
||||
return (obj and obj.mode != 'EDIT')
|
||||
|
||||
def execute(self, context):
|
||||
C = bpy.context
|
||||
ob_act = C.active_object
|
||||
objects = [ob for ob in C.selected_editable_objects if ob != ob_act]
|
||||
ob_act = context.active_object
|
||||
objects = [ob for ob in context.selected_editable_objects if ob != ob_act]
|
||||
|
||||
if 1: # swap from/to, means we cant copy to many at once.
|
||||
if len(objects) != 1:
|
||||
@@ -585,11 +587,6 @@ class MakeDupliFace(Operator):
|
||||
bl_idname = "object.make_dupli_face"
|
||||
bl_label = "Make Dupli-Face"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
obj = context.active_object
|
||||
return (obj and obj.type == 'MESH')
|
||||
|
||||
def _main(self, context):
|
||||
from mathutils import Vector
|
||||
|
||||
@@ -601,22 +598,22 @@ class MakeDupliFace(Operator):
|
||||
Vector((-offset, +offset, 0.0)),
|
||||
)
|
||||
|
||||
def matrix_to_quat(matrix):
|
||||
def matrix_to_quad(matrix):
|
||||
# scale = matrix.median_scale
|
||||
trans = matrix.to_translation()
|
||||
rot = matrix.to_3x3() # also contains scale
|
||||
|
||||
return [(rot * b) + trans for b in base_tri]
|
||||
scene = bpy.context.scene
|
||||
scene = context.scene
|
||||
linked = {}
|
||||
for obj in bpy.context.selected_objects:
|
||||
for obj in context.selected_objects:
|
||||
data = obj.data
|
||||
if data:
|
||||
linked.setdefault(data, []).append(obj)
|
||||
|
||||
for data, objects in linked.items():
|
||||
face_verts = [axis for obj in objects
|
||||
for v in matrix_to_quat(obj.matrix_world)
|
||||
for v in matrix_to_quad(obj.matrix_world)
|
||||
for axis in v]
|
||||
|
||||
faces = list(range(len(face_verts) // 3))
|
||||
|
||||
@@ -409,7 +409,10 @@ class AddPresetTrackingSettings(AddPresetBase, Operator):
|
||||
"settings.default_search_size",
|
||||
"settings.default_frames_limit",
|
||||
"settings.default_pattern_match",
|
||||
"settings.default_margin"
|
||||
"settings.default_margin",
|
||||
"settings.use_default_red_channel",
|
||||
"settings.use_default_green_channel",
|
||||
"settings.use_default_blue_channel"
|
||||
]
|
||||
|
||||
preset_subdir = "tracking_settings"
|
||||
|
||||
@@ -226,10 +226,10 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
|
||||
row.alignment = 'RIGHT'
|
||||
|
||||
sub = row.row(align=True)
|
||||
sub.label() # XXX, for alignment only
|
||||
subsub = sub.row(align=True)
|
||||
subsub.active = enable_edit_value
|
||||
subsub.prop(ob, "show_only_shape_key", text="")
|
||||
subsub.prop(kb, "mute", text="")
|
||||
sub.prop(ob, "use_shape_key_edit_mode", text="")
|
||||
|
||||
sub = row.row()
|
||||
|
||||
@@ -434,25 +434,28 @@ class ConstraintButtonsPanel():
|
||||
def ACTION(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
layout.prop(con, "action")
|
||||
|
||||
layout.prop(con, "transform_channel")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.label(text="Action Length:")
|
||||
col.prop(con, "frame_start", text="Start")
|
||||
col.prop(con, "frame_end", text="End")
|
||||
|
||||
|
||||
col = split.column()
|
||||
col.label(text="From Target:")
|
||||
col.prop(con, "transform_channel", text="")
|
||||
col.prop(con, "target_space", text="")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="To Action:")
|
||||
col.prop(con, "action", text="")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column(align=True)
|
||||
col.label(text="Target Range:")
|
||||
col.prop(con, "min", text="Min")
|
||||
col.prop(con, "max", text="Max")
|
||||
|
||||
row = layout.row()
|
||||
row.label(text="Convert:")
|
||||
row.prop(con, "target_space", text="")
|
||||
|
||||
col = split.column(align=True)
|
||||
col.label(text="Action Range:")
|
||||
col.prop(con, "frame_start", text="Start")
|
||||
col.prop(con, "frame_end", text="End")
|
||||
|
||||
def LOCKED_TRACK(self, context, layout, con):
|
||||
self.target_template(layout, con)
|
||||
|
||||
@@ -85,6 +85,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):
|
||||
col.label()
|
||||
col.prop(fluid, "use_speed_vectors")
|
||||
col.prop(fluid, "use_reverse_frames")
|
||||
col.prop(fluid, "frame_offset", text="Offset")
|
||||
|
||||
layout.prop(fluid, "filepath", text="")
|
||||
|
||||
|
||||
@@ -127,6 +127,13 @@ class CLIP_PT_tools_marker(Panel):
|
||||
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(settings, "use_default_red_channel", text="R", toggle=True)
|
||||
row.prop(settings, "use_default_green_channel", text="G", toggle=True)
|
||||
row.prop(settings, "use_default_blue_channel", text="B", toggle=True)
|
||||
|
||||
col.separator()
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.prop(settings, "default_pattern_size")
|
||||
sub.prop(settings, "default_search_size")
|
||||
@@ -147,6 +154,9 @@ class CLIP_PT_tools_marker(Panel):
|
||||
col.label(text="Match:")
|
||||
col.prop(settings, "default_pattern_match", text="")
|
||||
|
||||
col.separator()
|
||||
col.operator('clip.track_settings_as_default', text="Copy From Active Track")
|
||||
|
||||
|
||||
class CLIP_PT_tools_tracking(Panel):
|
||||
bl_space_type = 'CLIP_EDITOR'
|
||||
@@ -710,17 +720,21 @@ class CLIP_PT_proxy(Panel):
|
||||
|
||||
layout.active = clip.use_proxy
|
||||
|
||||
layout.label(text="Build Sizes:")
|
||||
layout.label(text="Build Original:")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(clip.proxy, "build_25")
|
||||
row.prop(clip.proxy, "build_50")
|
||||
row = layout.row(align=True)
|
||||
row.prop(clip.proxy, "build_25", toggle=True)
|
||||
row.prop(clip.proxy, "build_50", toggle=True)
|
||||
row.prop(clip.proxy, "build_75", toggle=True)
|
||||
row.prop(clip.proxy, "build_100", toggle=True)
|
||||
|
||||
row = layout.row()
|
||||
row.prop(clip.proxy, "build_75")
|
||||
row.prop(clip.proxy, "build_100")
|
||||
layout.label(text="Build Undistorted:")
|
||||
|
||||
layout.prop(clip.proxy, "build_undistorted")
|
||||
row = layout.row(align=True)
|
||||
row.prop(clip.proxy, "build_undistorted_25", toggle=True)
|
||||
row.prop(clip.proxy, "build_undistorted_50", toggle=True)
|
||||
row.prop(clip.proxy, "build_undistorted_75", toggle=True)
|
||||
row.prop(clip.proxy, "build_undistorted_100", toggle=True)
|
||||
|
||||
layout.prop(clip.proxy, "quality")
|
||||
|
||||
@@ -728,7 +742,7 @@ class CLIP_PT_proxy(Panel):
|
||||
if clip.use_proxy_custom_directory:
|
||||
layout.prop(clip.proxy, "directory")
|
||||
|
||||
layout.operator("clip.rebuild_proxy", text="Rebuild Proxy")
|
||||
layout.operator("clip.rebuild_proxy", text="Build Proxy")
|
||||
|
||||
if clip.source == 'MOVIE':
|
||||
col = layout.column()
|
||||
|
||||
@@ -92,7 +92,7 @@ class IMAGE_MT_select(Menu):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("uv.select_border").pinned = False
|
||||
layout.operator("uv.select_border").pinned = True
|
||||
layout.operator("uv.select_border", text="Border Select Pinned").pinned = True
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ void animviz_calc_motionpaths(struct Scene *scene, ListBase *targets);
|
||||
void free_path(struct Path *path);
|
||||
void calc_curvepath(struct Object *ob);
|
||||
int interval_test(int min, int max, int p1, int cycl);
|
||||
int where_on_path(struct Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius, float *weight);
|
||||
int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius, float *weight);
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
/* Dupli-Geometry */
|
||||
|
||||
@@ -109,6 +109,8 @@ void armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[][4], flo
|
||||
void armature_loc_pose_to_bone(struct bPoseChannel *pchan, float *inloc, float *outloc);
|
||||
void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]);
|
||||
|
||||
void armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]);
|
||||
|
||||
void pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[][3], short use_compat);
|
||||
void pchan_apply_mat4(struct bPoseChannel *pchan, float mat[][4], short use_comat);
|
||||
void pchan_to_mat4(struct bPoseChannel *pchan, float chan_mat[4][4]);
|
||||
|
||||
@@ -51,7 +51,7 @@ extern "C" {
|
||||
/* can be left blank, otherwise a,b,c... etc with no quotes */
|
||||
#define BLENDER_VERSION_CHAR
|
||||
/* alpha/beta/rc/release, docs use this */
|
||||
#define BLENDER_VERSION_CYCLE alpha
|
||||
#define BLENDER_VERSION_CYCLE beta
|
||||
|
||||
extern char versionstr[]; /* from blender.c */
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ void clmdSetInterruptCallBack ( int ( *f ) ( void ) );
|
||||
void cloth_free_modifier_extern ( struct ClothModifierData *clmd );
|
||||
void cloth_free_modifier ( struct ClothModifierData *clmd );
|
||||
void cloth_init ( struct ClothModifierData *clmd );
|
||||
struct DerivedMesh *clothModifier_do ( struct ClothModifierData *clmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm);
|
||||
void clothModifier_do ( struct ClothModifierData *clmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3]);
|
||||
|
||||
void cloth_update_normals ( ClothVertex *verts, int nVerts, struct MFace *face, int totface );
|
||||
int cloth_uses_vgroup(struct ClothModifierData *clmd);
|
||||
|
||||
@@ -67,7 +67,7 @@ extern const CustomDataMask CD_MASK_FACECORNERS;
|
||||
#define CD_DUPLICATE 4 /* do a full copy of all layers, only allowed if source
|
||||
has same number of elements */
|
||||
|
||||
#define CD_TYPE_AS_MASK(_type) (CustomDataMask)(1 << (CustomDataMask)(_type))
|
||||
#define CD_TYPE_AS_MASK(_type) (CustomDataMask)((CustomDataMask)1 << (CustomDataMask)(_type))
|
||||
|
||||
/* initialises a CustomData object with the same layer setup as source.
|
||||
* mask is a bitfield where (mask & (1 << (layer type))) indicates
|
||||
|
||||
@@ -59,7 +59,7 @@ void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object
|
||||
struct DerivedMesh *dm, float (*vertexCos)[3],
|
||||
int numVerts, const char *vgroup, short defaxis);
|
||||
void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target,
|
||||
float *orco, float *vec, float mat[][3], int no_rot_axis);
|
||||
float orco[3], float vec[3], float mat[][3], int no_rot_axis);
|
||||
|
||||
void lattice_deform_verts(struct Object *laOb, struct Object *target,
|
||||
struct DerivedMesh *dm, float (*vertexCos)[3],
|
||||
|
||||
@@ -49,7 +49,7 @@ void BKE_movieclip_reload(struct MovieClip *clip);
|
||||
struct ImBuf *BKE_movieclip_get_ibuf(struct MovieClip *clip, struct MovieClipUser *user);
|
||||
struct ImBuf *BKE_movieclip_get_postprocessed_ibuf(struct MovieClip *clip, struct MovieClipUser *user, int postprocess_flag);
|
||||
struct ImBuf *BKE_movieclip_get_stable_ibuf(struct MovieClip *clip, struct MovieClipUser *user, float loc[2], float *scale, float *angle, int postprocess_flag);
|
||||
struct ImBuf *BKE_movieclip_get_ibuf_flag(struct MovieClip *clip, struct MovieClipUser *user, int flag);
|
||||
struct ImBuf *BKE_movieclip_get_ibuf_flag(struct MovieClip *clip, struct MovieClipUser *user, int flag, int cache_flag);
|
||||
void BKE_movieclip_get_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height);
|
||||
void BKE_movieclip_aspect(struct MovieClip *clip, float *aspx, float *aspy);
|
||||
int BKE_movieclip_has_frame(struct MovieClip *clip, struct MovieClipUser *user);
|
||||
@@ -64,6 +64,9 @@ void BKE_movieclip_get_cache_segments(struct MovieClip *clip, struct MovieClipUs
|
||||
void BKE_movieclip_build_proxy_frame(struct MovieClip *clip, int clip_flag, struct MovieDistortion *distortion,
|
||||
int cfra, int *build_sizes, int build_count, int undistorted);
|
||||
|
||||
/* cacheing flags */
|
||||
#define MOVIECLIP_CACHE_SKIP (1<<0)
|
||||
|
||||
/* postprocessing flags */
|
||||
#define MOVIECLIP_DISABLE_RED (1<<0)
|
||||
#define MOVIECLIP_DISABLE_GREEN (1<<1)
|
||||
|
||||
@@ -585,11 +585,14 @@ int interval_test(int min, int max, int p1, int cycl)
|
||||
}
|
||||
|
||||
|
||||
/* calculate the deformation implied by the curve path at a given parametric position, and returns whether this operation succeeded
|
||||
* - *vec needs FOUR items!
|
||||
* - ctime is normalized range <0-1>
|
||||
/* calculate the deformation implied by the curve path at a given parametric position,
|
||||
* and returns whether this operation succeeded.
|
||||
*
|
||||
* note: ctime is normalized range <0-1>
|
||||
*
|
||||
* returns OK: 1/0
|
||||
*/
|
||||
int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius, float *weight) /* returns OK */
|
||||
int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius, float *weight)
|
||||
{
|
||||
Curve *cu;
|
||||
Nurb *nu;
|
||||
|
||||
@@ -1319,6 +1319,23 @@ void armature_loc_pose_to_bone(bPoseChannel *pchan, float *inloc, float *outloc)
|
||||
copy_v3_v3(outloc, nLocMat[3]);
|
||||
}
|
||||
|
||||
void armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[][4], float outmat[][4])
|
||||
{
|
||||
bPoseChannel work_pchan = *pchan;
|
||||
|
||||
/* recalculate pose matrix with only parent transformations,
|
||||
* bone loc/sca/rot is ignored, scene and frame are not used. */
|
||||
where_is_pose_bone(NULL, ob, &work_pchan, 0.0f, FALSE);
|
||||
|
||||
/* find the matrix, need to remove the bone transforms first so this is
|
||||
* calculated as a matrix to set rather then a difference ontop of whats
|
||||
* already there. */
|
||||
unit_m4(outmat);
|
||||
pchan_apply_mat4(&work_pchan, outmat, FALSE);
|
||||
|
||||
armature_mat_pose_to_bone(&work_pchan, inmat, outmat);
|
||||
}
|
||||
|
||||
/* same as object_mat3_to_rot() */
|
||||
void pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat)
|
||||
{
|
||||
|
||||
@@ -90,7 +90,7 @@ static CM_SOLVER_DEF solvers [] =
|
||||
/* ********** cloth engine ******* */
|
||||
/* Prototypes for internal functions.
|
||||
*/
|
||||
static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm);
|
||||
static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]);
|
||||
static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm );
|
||||
static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first);
|
||||
static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
|
||||
@@ -429,9 +429,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
|
||||
/************************************************
|
||||
* clothModifier_do - main simulation function
|
||||
************************************************/
|
||||
DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm)
|
||||
void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3])
|
||||
{
|
||||
DerivedMesh *result;
|
||||
PointCache *cache;
|
||||
PTCacheID pid;
|
||||
float timescale;
|
||||
@@ -441,20 +440,14 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
|
||||
clmd->scene= scene; /* nice to pass on later :) */
|
||||
framenr= (int)scene->r.cfra;
|
||||
cache= clmd->point_cache;
|
||||
result = CDDM_copy(dm);
|
||||
|
||||
BKE_ptcache_id_from_cloth(&pid, ob, clmd);
|
||||
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale);
|
||||
clmd->sim_parms->timescale= timescale;
|
||||
|
||||
if(!result) {
|
||||
BKE_ptcache_invalidate(cache);
|
||||
return dm;
|
||||
}
|
||||
|
||||
if(clmd->sim_parms->reset
|
||||
|| (framenr == (startframe - clmd->sim_parms->preroll) && clmd->sim_parms->preroll != 0)
|
||||
|| (clmd->clothObject && result->getNumVerts(result) != clmd->clothObject->numverts))
|
||||
|| (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->numverts))
|
||||
{
|
||||
clmd->sim_parms->reset = 0;
|
||||
cache->flag |= PTCACHE_OUTDATED;
|
||||
@@ -462,7 +455,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
|
||||
BKE_ptcache_validate(cache, 0);
|
||||
cache->last_exact= 0;
|
||||
cache->flag &= ~PTCACHE_REDO_NEEDED;
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
|
||||
// unused in the moment, calculated separately in implicit.c
|
||||
@@ -474,20 +467,20 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
|
||||
|
||||
/* do simulation */
|
||||
if(!do_init_cloth(ob, clmd, dm, framenr))
|
||||
return result;
|
||||
return;
|
||||
|
||||
do_step_cloth(ob, clmd, dm, framenr);
|
||||
cloth_to_object(ob, clmd, result);
|
||||
cloth_to_object(ob, clmd, vertexCos);
|
||||
|
||||
clmd->clothObject->last_frame= framenr;
|
||||
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
|
||||
/* simulation is only active during a specific period */
|
||||
if(framenr < startframe) {
|
||||
BKE_ptcache_invalidate(cache);
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
else if(framenr > endframe) {
|
||||
framenr= endframe;
|
||||
@@ -495,7 +488,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
|
||||
|
||||
/* initialize simulation data if it didn't exist already */
|
||||
if(!do_init_cloth(ob, clmd, dm, framenr))
|
||||
return result;
|
||||
return;
|
||||
|
||||
if((framenr == startframe) && (clmd->sim_parms->preroll == 0)) {
|
||||
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
|
||||
@@ -503,7 +496,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
|
||||
BKE_ptcache_validate(cache, framenr);
|
||||
cache->flag &= ~PTCACHE_REDO_NEEDED;
|
||||
clmd->clothObject->last_frame= framenr;
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to read from cache */
|
||||
@@ -511,7 +504,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
|
||||
|
||||
if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
|
||||
implicit_set_positions(clmd);
|
||||
cloth_to_object (ob, clmd, result);
|
||||
cloth_to_object (ob, clmd, vertexCos);
|
||||
|
||||
BKE_ptcache_validate(cache, framenr);
|
||||
|
||||
@@ -520,7 +513,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
|
||||
|
||||
clmd->clothObject->last_frame= framenr;
|
||||
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
else if(cache_result==PTCACHE_READ_OLD) {
|
||||
implicit_set_positions(clmd);
|
||||
@@ -528,11 +521,11 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
|
||||
else if( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
|
||||
/* if baked and nothing in cache, do nothing */
|
||||
BKE_ptcache_invalidate(cache);
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
|
||||
if(framenr!=clmd->clothObject->last_frame+1)
|
||||
return result;
|
||||
return;
|
||||
|
||||
/* if on second frame, write cache for first frame */
|
||||
if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
|
||||
@@ -549,10 +542,8 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
|
||||
else
|
||||
BKE_ptcache_write(&pid, framenr);
|
||||
|
||||
cloth_to_object (ob, clmd, result);
|
||||
cloth_to_object (ob, clmd, vertexCos);
|
||||
clmd->clothObject->last_frame= framenr;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* frees all */
|
||||
@@ -707,24 +698,19 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd )
|
||||
* cloth_to_object - copies the deformed vertices to the object.
|
||||
*
|
||||
**/
|
||||
static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm)
|
||||
static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3])
|
||||
{
|
||||
unsigned int i = 0;
|
||||
MVert *mvert = NULL;
|
||||
unsigned int numverts;
|
||||
Cloth *cloth = clmd->clothObject;
|
||||
|
||||
if (clmd->clothObject) {
|
||||
/* inverse matrix is not uptodate... */
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
|
||||
mvert = CDDM_get_verts(dm);
|
||||
numverts = dm->getNumVerts(dm);
|
||||
|
||||
for (i = 0; i < numverts; i++)
|
||||
for (i = 0; i < cloth->numverts; i++)
|
||||
{
|
||||
copy_v3_v3 (mvert[i].co, cloth->verts[i].x);
|
||||
mul_m4_v3(ob->imat, mvert[i].co); /* cloth is in global coords */
|
||||
copy_v3_v3 (vertexCos[i], cloth->verts[i].x);
|
||||
mul_m4_v3(ob->imat, vertexCos[i]); /* cloth is in global coords */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +220,50 @@ void constraints_clear_evalob (bConstraintOb *cob)
|
||||
|
||||
/* -------------- Space-Conversion API -------------- */
|
||||
|
||||
static void constraint_pchan_diff_mat(bPoseChannel *pchan, float diff_mat[4][4])
|
||||
{
|
||||
if (pchan->parent) {
|
||||
float offs_bone[4][4];
|
||||
|
||||
/* construct offs_bone the same way it is done in armature.c */
|
||||
copy_m4_m3(offs_bone, pchan->bone->bone_mat);
|
||||
copy_v3_v3(offs_bone[3], pchan->bone->head);
|
||||
offs_bone[3][1] += pchan->bone->parent->length;
|
||||
|
||||
if (pchan->bone->flag & BONE_HINGE) {
|
||||
/* pose_mat = par_pose-space_location * chan_mat */
|
||||
float tmat[4][4];
|
||||
|
||||
/* the rotation of the parent restposition */
|
||||
copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
|
||||
|
||||
/* the location of actual parent transform */
|
||||
copy_v3_v3(tmat[3], offs_bone[3]);
|
||||
zero_v3(offs_bone[3]);
|
||||
mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
|
||||
|
||||
mult_m4_m4m4(diff_mat, tmat, offs_bone);
|
||||
}
|
||||
else {
|
||||
/* pose_mat = par_pose_mat * bone_mat * chan_mat */
|
||||
if (pchan->bone->flag & BONE_NO_SCALE) {
|
||||
float tmat[4][4];
|
||||
copy_m4_m4(tmat, pchan->parent->pose_mat);
|
||||
normalize_m4(tmat);
|
||||
mult_m4_m4m4(diff_mat, tmat, offs_bone);
|
||||
}
|
||||
else {
|
||||
mult_m4_m4m4(diff_mat, pchan->parent->pose_mat, offs_bone);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* pose_mat = chan_mat * arm_mat */
|
||||
copy_m4_m4(diff_mat, pchan->bone->arm_mat);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This function is responsible for the correct transformations/conversions
|
||||
* of a matrix from one space to another for constraint evaluation.
|
||||
* For now, this is only implemented for Objects and PoseChannels.
|
||||
@@ -263,42 +307,18 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4
|
||||
/* pose to local */
|
||||
else if (to == CONSTRAINT_SPACE_LOCAL) {
|
||||
if (pchan->bone) {
|
||||
if (pchan->parent) {
|
||||
float offs_bone[4][4];
|
||||
|
||||
/* construct offs_bone the same way it is done in armature.c */
|
||||
copy_m4_m3(offs_bone, pchan->bone->bone_mat);
|
||||
copy_v3_v3(offs_bone[3], pchan->bone->head);
|
||||
offs_bone[3][1]+= pchan->bone->parent->length;
|
||||
|
||||
if (pchan->bone->flag & BONE_HINGE) {
|
||||
/* pose_mat = par_pose-space_location * chan_mat */
|
||||
float tmat[4][4];
|
||||
|
||||
/* the rotation of the parent restposition */
|
||||
copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
|
||||
|
||||
/* the location of actual parent transform */
|
||||
copy_v3_v3(tmat[3], offs_bone[3]);
|
||||
offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
|
||||
mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
|
||||
|
||||
mult_m4_m4m4(diff_mat, tmat, offs_bone);
|
||||
invert_m4_m4(imat, diff_mat);
|
||||
}
|
||||
else {
|
||||
/* pose_mat = par_pose_mat * bone_mat * chan_mat */
|
||||
mult_m4_m4m4(diff_mat, pchan->parent->pose_mat, offs_bone);
|
||||
invert_m4_m4(imat, diff_mat);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* pose_mat = chan_mat * arm_mat */
|
||||
invert_m4_m4(imat, pchan->bone->arm_mat);
|
||||
}
|
||||
|
||||
constraint_pchan_diff_mat(pchan, diff_mat);
|
||||
|
||||
invert_m4_m4(imat, diff_mat);
|
||||
|
||||
copy_m4_m4(tempmat, mat);
|
||||
mult_m4_m4m4(mat, imat, tempmat);
|
||||
|
||||
/* override with local location */
|
||||
if ((pchan->parent) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) {
|
||||
armature_mat_pose_to_bone_ex(ob, pchan, pchan->pose_mat, tempmat);
|
||||
copy_v3_v3(mat[3], tempmat[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* pose to local with parent */
|
||||
@@ -315,44 +335,11 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4
|
||||
{
|
||||
/* local to pose - do inverse procedure that was done for pose to local */
|
||||
if (pchan->bone) {
|
||||
/* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
|
||||
if (pchan->parent) {
|
||||
float offs_bone[4][4];
|
||||
|
||||
/* construct offs_bone the same way it is done in armature.c */
|
||||
copy_m4_m3(offs_bone, pchan->bone->bone_mat);
|
||||
copy_v3_v3(offs_bone[3], pchan->bone->head);
|
||||
offs_bone[3][1]+= pchan->bone->parent->length;
|
||||
|
||||
if (pchan->bone->flag & BONE_HINGE) {
|
||||
/* pose_mat = par_pose-space_location * chan_mat */
|
||||
float tmat[4][4];
|
||||
|
||||
/* the rotation of the parent restposition */
|
||||
copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
|
||||
|
||||
/* the location of actual parent transform */
|
||||
copy_v3_v3(tmat[3], offs_bone[3]);
|
||||
zero_v3(offs_bone[3]);
|
||||
mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
|
||||
|
||||
mult_m4_m4m4(diff_mat, tmat, offs_bone);
|
||||
copy_m4_m4(tempmat, mat);
|
||||
mult_m4_m4m4(mat, diff_mat, tempmat);
|
||||
}
|
||||
else {
|
||||
/* pose_mat = par_pose_mat * bone_mat * chan_mat */
|
||||
mult_m4_m4m4(diff_mat, pchan->parent->pose_mat, offs_bone);
|
||||
copy_m4_m4(tempmat, mat);
|
||||
mult_m4_m4m4(mat, diff_mat, tempmat);
|
||||
}
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(diff_mat, pchan->bone->arm_mat);
|
||||
|
||||
copy_m4_m4(tempmat, mat);
|
||||
mult_m4_m4m4(mat, diff_mat, tempmat);
|
||||
}
|
||||
/* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
|
||||
constraint_pchan_diff_mat(pchan, diff_mat);
|
||||
|
||||
copy_m4_m4(tempmat, mat);
|
||||
mult_m4_m4m4(mat, diff_mat, tempmat);
|
||||
}
|
||||
|
||||
/* use pose-space as stepping stone for other spaces */
|
||||
@@ -504,13 +491,17 @@ static void contarget_get_mesh_mat (Object *ob, const char *substring, float mat
|
||||
normalize_v3(normal);
|
||||
copy_v3_v3(plane, tmat[1]);
|
||||
|
||||
copy_v3_v3(tmat[2], normal);
|
||||
cross_v3_v3v3(tmat[0], normal, plane);
|
||||
cross_v3_v3v3(tmat[1], tmat[2], tmat[0]);
|
||||
|
||||
copy_m4_m3(mat, tmat);
|
||||
cross_v3_v3v3(mat[0], normal, plane);
|
||||
if(len_v3(mat[0]) < 1e-3) {
|
||||
copy_v3_v3(plane, tmat[0]);
|
||||
cross_v3_v3v3(mat[0], normal, plane);
|
||||
}
|
||||
|
||||
copy_v3_v3(mat[2], normal);
|
||||
cross_v3_v3v3(mat[1], mat[2], mat[0]);
|
||||
|
||||
normalize_m4(mat);
|
||||
|
||||
|
||||
|
||||
/* apply the average coordinate as the new location */
|
||||
mul_v3_m4v3(mat[3], ob->obmat, vec);
|
||||
|
||||
@@ -381,7 +381,8 @@ void CTX_wm_window_set(bContext *C, wmWindow *win)
|
||||
{
|
||||
C->wm.window= win;
|
||||
C->wm.screen= (win)? win->screen: NULL;
|
||||
C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
|
||||
if(C->wm.screen)
|
||||
C->data.scene= C->wm.screen->scene;
|
||||
C->wm.area= NULL;
|
||||
C->wm.region= NULL;
|
||||
}
|
||||
@@ -389,7 +390,8 @@ void CTX_wm_window_set(bContext *C, wmWindow *win)
|
||||
void CTX_wm_screen_set(bContext *C, bScreen *screen)
|
||||
{
|
||||
C->wm.screen= screen;
|
||||
C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
|
||||
if(C->wm.screen)
|
||||
C->data.scene= C->wm.screen->scene;
|
||||
C->wm.area= NULL;
|
||||
C->wm.region= NULL;
|
||||
}
|
||||
|
||||
@@ -539,6 +539,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
|
||||
}
|
||||
break;
|
||||
case OB_CURVE:
|
||||
case OB_FONT:
|
||||
{
|
||||
Curve *cu= ob->data;
|
||||
|
||||
@@ -550,15 +551,11 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
|
||||
node2 = dag_get_node(dag, cu->taperobj);
|
||||
dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Curve Taper");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OB_FONT:
|
||||
{
|
||||
Curve *cu= ob->data;
|
||||
|
||||
if(cu->textoncurve) {
|
||||
node2 = dag_get_node(dag, cu->textoncurve);
|
||||
dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Texture On Curve");
|
||||
if(ob->type == OB_FONT) {
|
||||
if(cu->textoncurve) {
|
||||
node2 = dag_get_node(dag, cu->textoncurve);
|
||||
dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Texture On Curve");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -833,6 +833,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
|
||||
int editmode = (!forRender && cu->editnurb);
|
||||
DerivedMesh *dm= NULL, *ndm;
|
||||
float (*vertCos)[3] = NULL;
|
||||
int useCache = !forRender;
|
||||
|
||||
if(forRender) required_mode = eModifierMode_Render;
|
||||
else required_mode = eModifierMode_Realtime;
|
||||
@@ -911,7 +912,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
|
||||
vertCos= NULL;
|
||||
}
|
||||
|
||||
ndm = mti->applyModifier(md, ob, dm, forRender, editmode);
|
||||
ndm = mti->applyModifier(md, ob, dm, forRender, useCache);
|
||||
|
||||
if (ndm) {
|
||||
/* Modifier returned a new derived mesh */
|
||||
|
||||
@@ -3552,7 +3552,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
|
||||
/* Proceed only if particle is active */
|
||||
if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;
|
||||
else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;
|
||||
else if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue;
|
||||
else if(pa->flag & PARS_UNEXIST) continue;
|
||||
|
||||
/* for debug purposes check if any NAN particle proceeds
|
||||
* For some reason they get past activity check, this should rule most of them out */
|
||||
|
||||
@@ -462,32 +462,25 @@ void end_latt_deform(Object *ob)
|
||||
so we store in latmat transform from path coord inside object
|
||||
*/
|
||||
typedef struct {
|
||||
float dmin[3], dmax[3], dscale, dloc[3];
|
||||
float dmin[3], dmax[3];
|
||||
float curvespace[4][4], objectspace[4][4], objectspace3[3][3];
|
||||
int no_rot_axis;
|
||||
} CurveDeform;
|
||||
|
||||
static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd, int dloc)
|
||||
static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd)
|
||||
{
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
mult_m4_m4m4(cd->objectspace, ob->imat, par->obmat);
|
||||
invert_m4_m4(cd->curvespace, cd->objectspace);
|
||||
copy_m3_m4(cd->objectspace3, cd->objectspace);
|
||||
|
||||
// offset vector for 'no smear'
|
||||
if(dloc) {
|
||||
invert_m4_m4(par->imat, par->obmat);
|
||||
mul_v3_m4v3(cd->dloc, par->imat, ob->obmat[3]);
|
||||
}
|
||||
else {
|
||||
cd->dloc[0]=cd->dloc[1]=cd->dloc[2]= 0.0f;
|
||||
}
|
||||
|
||||
cd->no_rot_axis= 0;
|
||||
}
|
||||
|
||||
/* this makes sure we can extend for non-cyclic. *vec needs 4 items! */
|
||||
static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */
|
||||
/* this makes sure we can extend for non-cyclic.
|
||||
*
|
||||
* returns OK: 1/0
|
||||
*/
|
||||
static int where_on_path_deform(Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius)
|
||||
{
|
||||
Curve *cu= ob->data;
|
||||
BevList *bl;
|
||||
@@ -532,20 +525,18 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* for each point, rotate & translate to curve */
|
||||
/* use path, since it has constant distances */
|
||||
/* co: local coord, result local too */
|
||||
/* returns quaternion for rotation, using cd->no_rot_axis */
|
||||
/* axis is using another define!!! */
|
||||
static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp)
|
||||
/* for each point, rotate & translate to curve */
|
||||
/* use path, since it has constant distances */
|
||||
/* co: local coord, result local too */
|
||||
/* returns quaternion for rotation, using cd->no_rot_axis */
|
||||
/* axis is using another define!!! */
|
||||
static int calc_curve_deform(Scene *scene, Object *par, float co[3],
|
||||
const short axis, CurveDeform *cd, float quat_r[4])
|
||||
{
|
||||
Curve *cu= par->data;
|
||||
float fac, loc[4], dir[3], new_quat[4], radius;
|
||||
short /*upflag, */ index;
|
||||
|
||||
index= axis-1;
|
||||
if(index>2)
|
||||
index -= 3; /* negative */
|
||||
short index;
|
||||
const int is_neg_axis = (axis > 2);
|
||||
|
||||
/* to be sure, mostly after file load */
|
||||
if(cu->path==NULL) {
|
||||
@@ -554,52 +545,24 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
|
||||
}
|
||||
|
||||
/* options */
|
||||
if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */
|
||||
if (is_neg_axis) {
|
||||
index = axis - 3;
|
||||
if(cu->flag & CU_STRETCH)
|
||||
fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]);
|
||||
else
|
||||
fac= (cd->dloc[index])/(cu->path->totdist) - (co[index]-cd->dmax[index])/(cu->path->totdist);
|
||||
fac= - (co[index]-cd->dmax[index])/(cu->path->totdist);
|
||||
}
|
||||
else {
|
||||
index = axis;
|
||||
if(cu->flag & CU_STRETCH)
|
||||
fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]);
|
||||
else
|
||||
fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist);
|
||||
fac= + (co[index]-cd->dmin[index])/(cu->path->totdist);
|
||||
}
|
||||
|
||||
#if 0 // XXX old animation system
|
||||
/* we want the ipo to work on the default 100 frame range, because there's no
|
||||
actual time involved in path position */
|
||||
// huh? by WHY!!!!???? - Aligorith
|
||||
if(cu->ipo) {
|
||||
fac*= 100.0f;
|
||||
if(calc_ipo_spec(cu->ipo, CU_SPEED, &fac)==0)
|
||||
fac/= 100.0;
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */
|
||||
float quat[4], cent[3];
|
||||
|
||||
#if 0 // XXX - 2.4x Z-Up, Now use bevel tilt.
|
||||
if(cd->no_rot_axis) /* set by caller */
|
||||
dir[cd->no_rot_axis-1]= 0.0f;
|
||||
|
||||
/* -1 for compatibility with old track defines */
|
||||
vec_to_quat( quat,dir, axis-1, upflag);
|
||||
|
||||
/* the tilt */
|
||||
if(loc[3]!=0.0) {
|
||||
normalize_v3(dir);
|
||||
q[0]= (float)cos(0.5*loc[3]);
|
||||
fac= (float)sin(0.5*loc[3]);
|
||||
q[1]= -fac*dir[0];
|
||||
q[2]= -fac*dir[1];
|
||||
q[3]= -fac*dir[2];
|
||||
mul_qt_qtqt(quat, q, quat);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(cd->no_rot_axis) { /* set by caller */
|
||||
|
||||
/* this is not exactly the same as 2.4x, since the axis is having rotation removed rather than
|
||||
@@ -634,9 +597,9 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
|
||||
|
||||
/* zero the axis which is not used,
|
||||
* the big block of text above now applies to these 3 lines */
|
||||
quat_apply_track(quat, axis-1, (axis==1 || axis==3) ? 1:0); /* up flag is a dummy, set so no rotation is done */
|
||||
vec_apply_track(cent, axis-1);
|
||||
cent[axis < 4 ? axis-1 : axis-4]= 0.0f;
|
||||
quat_apply_track(quat, axis, (axis == 0 || axis == 2) ? 1:0); /* up flag is a dummy, set so no rotation is done */
|
||||
vec_apply_track(cent, axis);
|
||||
cent[index]= 0.0f;
|
||||
|
||||
|
||||
/* scale if enabled */
|
||||
@@ -650,8 +613,8 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
|
||||
/* translation */
|
||||
add_v3_v3v3(co, cent, loc);
|
||||
|
||||
if(quatp)
|
||||
copy_qt_qt(quatp, quat);
|
||||
if(quat_r)
|
||||
copy_qt_qt(quat_r, quat);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -666,6 +629,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
|
||||
int a, flag;
|
||||
CurveDeform cd;
|
||||
int use_vgroups;
|
||||
const int is_neg_axis = (defaxis > 2);
|
||||
|
||||
if(cuOb->type != OB_CURVE)
|
||||
return;
|
||||
@@ -674,10 +638,10 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
|
||||
flag = cu->flag;
|
||||
cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
|
||||
|
||||
init_curve_deform(cuOb, target, &cd, (cu->flag & CU_STRETCH)==0);
|
||||
init_curve_deform(cuOb, target, &cd);
|
||||
|
||||
/* dummy bounds, keep if CU_DEFORM_BOUNDS_OFF is set */
|
||||
if(defaxis < 3) {
|
||||
if(is_neg_axis == FALSE) {
|
||||
cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= 0.0f;
|
||||
cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 1.0f;
|
||||
}
|
||||
@@ -711,10 +675,6 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
|
||||
|
||||
|
||||
if(cu->flag & CU_DEFORM_BOUNDS_OFF) {
|
||||
/* dummy bounds */
|
||||
cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= 0.0f;
|
||||
cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 1.0f;
|
||||
|
||||
dvert = me->dvert;
|
||||
for(a = 0; a < numVerts; a++, dvert++) {
|
||||
if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
|
||||
@@ -749,6 +709,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
|
||||
weight= defvert_find_weight(dvert, index);
|
||||
|
||||
if(weight > 0.0f) {
|
||||
/* already in 'cd.curvespace', prev for loop */
|
||||
copy_v3_v3(vec, vertexCos[a]);
|
||||
calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
|
||||
interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
|
||||
@@ -776,6 +737,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
|
||||
}
|
||||
|
||||
for(a = 0; a < numVerts; a++) {
|
||||
/* already in 'cd.curvespace', prev for loop */
|
||||
calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
|
||||
mul_m4_v3(cd.objectspace, vertexCos[a]);
|
||||
}
|
||||
@@ -787,7 +749,8 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target,
|
||||
/* input vec and orco = local coord in armature space */
|
||||
/* orco is original not-animated or deformed reference point */
|
||||
/* result written in vec and mat */
|
||||
void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, float *orco, float *vec, float mat[][3], int no_rot_axis)
|
||||
void curve_deform_vector(Scene *scene, Object *cuOb, Object *target,
|
||||
float orco[3], float vec[3], float mat[][3], int no_rot_axis)
|
||||
{
|
||||
CurveDeform cd;
|
||||
float quat[4];
|
||||
@@ -797,7 +760,7 @@ void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, float *orco
|
||||
return;
|
||||
}
|
||||
|
||||
init_curve_deform(cuOb, target, &cd, 0); /* 0 no dloc */
|
||||
init_curve_deform(cuOb, target, &cd);
|
||||
cd.no_rot_axis= no_rot_axis; /* option to only rotate for XY, for example */
|
||||
|
||||
copy_v3_v3(cd.dmin, orco);
|
||||
@@ -805,7 +768,7 @@ void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, float *orco
|
||||
|
||||
mul_m4_v3(cd.curvespace, vec);
|
||||
|
||||
if(calc_curve_deform(scene, cuOb, vec, target->trackflag+1, &cd, quat)) {
|
||||
if(calc_curve_deform(scene, cuOb, vec, target->trackflag, &cd, quat)) {
|
||||
float qmat[3][3];
|
||||
|
||||
quat_to_mat3( qmat,quat);
|
||||
@@ -885,7 +848,7 @@ int object_deform_mball(Object *ob, ListBase *dispbase)
|
||||
|
||||
static BPoint *latt_bp(Lattice *lt, int u, int v, int w)
|
||||
{
|
||||
return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv;
|
||||
return <->def[LT_INDEX(lt, u, v, w)];
|
||||
}
|
||||
|
||||
void outside_lattice(Lattice *lt)
|
||||
|
||||
@@ -631,7 +631,8 @@ static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *u
|
||||
return postproc_ibuf;
|
||||
}
|
||||
|
||||
static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *user, int flag, int postprocess_flag)
|
||||
static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *user, int flag,
|
||||
int postprocess_flag, int cache_flag)
|
||||
{
|
||||
ImBuf *ibuf= NULL;
|
||||
int framenr= user->framenr, need_postprocess= 0;
|
||||
@@ -664,7 +665,7 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *u
|
||||
ibuf= movieclip_load_movie_file(clip, user, framenr, flag);
|
||||
}
|
||||
|
||||
if(ibuf)
|
||||
if(ibuf && (cache_flag & MOVIECLIP_CACHE_SKIP) == 0)
|
||||
put_imbuf_cache(clip, user, ibuf, flag);
|
||||
}
|
||||
|
||||
@@ -687,17 +688,17 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *u
|
||||
|
||||
ImBuf *BKE_movieclip_get_ibuf(MovieClip *clip, MovieClipUser *user)
|
||||
{
|
||||
return BKE_movieclip_get_ibuf_flag(clip, user, clip->flag);
|
||||
return BKE_movieclip_get_ibuf_flag(clip, user, clip->flag, 0);
|
||||
}
|
||||
|
||||
ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag)
|
||||
ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag, int cache_flag)
|
||||
{
|
||||
return movieclip_get_postprocessed_ibuf(clip, user, flag, 0);
|
||||
return movieclip_get_postprocessed_ibuf(clip, user, flag, 0, cache_flag);
|
||||
}
|
||||
|
||||
ImBuf *BKE_movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *user, int postprocess_flag)
|
||||
{
|
||||
return movieclip_get_postprocessed_ibuf(clip, user, clip->flag, postprocess_flag);
|
||||
return movieclip_get_postprocessed_ibuf(clip, user, clip->flag, postprocess_flag, 0);
|
||||
}
|
||||
|
||||
static ImBuf *get_stable_cached_frame(MovieClip *clip, MovieClipUser *user, int framenr)
|
||||
@@ -1021,7 +1022,7 @@ void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct Movi
|
||||
user.render_flag= 0;
|
||||
user.render_size= MCLIP_PROXY_RENDER_SIZE_FULL;
|
||||
|
||||
ibuf= BKE_movieclip_get_ibuf_flag(clip, &user, clip_flag);
|
||||
ibuf= BKE_movieclip_get_ibuf_flag(clip, &user, clip_flag, MOVIECLIP_CACHE_SKIP);
|
||||
|
||||
if(ibuf) {
|
||||
ImBuf *tmpibuf= ibuf;
|
||||
|
||||
@@ -344,7 +344,7 @@ int buildNavMeshData(const int nverts, const float* verts,
|
||||
int *vertsPerPoly_r, int **dtrisToPolysMap_r, int **dtrisToTrisMap_r)
|
||||
|
||||
{
|
||||
int *trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping");
|
||||
int *trisMapping;
|
||||
int i;
|
||||
struct SortContext context;
|
||||
int validTriStart, prevPolyIdx, curPolyIdx, newPolyIdx, prevpolyidx;
|
||||
@@ -360,6 +360,8 @@ int buildNavMeshData(const int nverts, const float* verts,
|
||||
return 0;
|
||||
}
|
||||
|
||||
trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping");
|
||||
|
||||
//sort the triangles by polygon idx
|
||||
for (i=0; i<ntris; i++)
|
||||
trisMapping[i]=i;
|
||||
|
||||
@@ -3480,6 +3480,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
|
||||
int totedge;
|
||||
int k;
|
||||
float hairmat[4][4];
|
||||
float (*deformedVerts)[3];
|
||||
|
||||
if(!psys->clmd) {
|
||||
psys->clmd = (ClothModifierData*)modifier_new(eModifierType_Cloth);
|
||||
@@ -3573,7 +3574,15 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
|
||||
psys->clmd->point_cache = psys->pointcache;
|
||||
psys->clmd->sim_parms->effector_weights = psys->part->effector_weights;
|
||||
|
||||
psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm);
|
||||
deformedVerts = MEM_callocN(sizeof(*deformedVerts)*dm->getNumVerts(dm), "do_hair_dynamics vertexCos");
|
||||
psys->hair_out_dm = CDDM_copy(dm);
|
||||
psys->hair_out_dm->getVertCos(psys->hair_out_dm, deformedVerts);
|
||||
|
||||
clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, deformedVerts);
|
||||
|
||||
CDDM_apply_vert_coords(psys->hair_out_dm, deformedVerts);
|
||||
|
||||
MEM_freeN(deformedVerts);
|
||||
|
||||
psys->clmd->sim_parms->effector_weights = NULL;
|
||||
}
|
||||
|
||||
@@ -242,6 +242,7 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr
|
||||
track->margin= settings->default_margin;
|
||||
track->pattern_match= settings->default_pattern_match;
|
||||
track->frames_limit= settings->default_frames_limit;
|
||||
track->flag= settings->default_flag;
|
||||
|
||||
memset(&marker, 0, sizeof(marker));
|
||||
marker.pos[0]= x;
|
||||
@@ -974,8 +975,8 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
|
||||
context->clip_flag= clip->flag&MCLIP_TIMECODE_FLAGS;
|
||||
|
||||
context->user= *user;
|
||||
context->user.render_size= 0;
|
||||
context->user.render_flag= MCLIP_PROXY_RENDER_SIZE_FULL;
|
||||
context->user.render_size= MCLIP_PROXY_RENDER_SIZE_FULL;
|
||||
context->user.render_flag= 0;
|
||||
|
||||
if(!sequence)
|
||||
BLI_begin_threaded_malloc();
|
||||
@@ -1225,7 +1226,7 @@ static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr)
|
||||
|
||||
user.framenr= framenr;
|
||||
|
||||
ibuf= BKE_movieclip_get_ibuf_flag(context->clip, &user, context->clip_flag);
|
||||
ibuf= BKE_movieclip_get_ibuf_flag(context->clip, &user, context->clip_flag, MOVIECLIP_CACHE_SKIP);
|
||||
|
||||
return ibuf;
|
||||
}
|
||||
@@ -1329,7 +1330,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
|
||||
if(context->backwards) context->user.framenr--;
|
||||
else context->user.framenr++;
|
||||
|
||||
ibuf_new= BKE_movieclip_get_ibuf_flag(context->clip, &context->user, context->clip_flag);
|
||||
ibuf_new= BKE_movieclip_get_ibuf_flag(context->clip, &context->user, context->clip_flag, MOVIECLIP_CACHE_SKIP);
|
||||
if(!ibuf_new)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -194,10 +194,12 @@ void makeFilesAbsolute(Main *bmain, const char *basedir, ReportList *reports)
|
||||
|
||||
|
||||
/* find this file recursively, use the biggest file so thumbnails dont get used by mistake
|
||||
- dir: subdir to search
|
||||
- filename: set this filename
|
||||
- filesize: filesize for the file
|
||||
*/
|
||||
* - dir: subdir to search
|
||||
* - filename: set this filename
|
||||
* - filesize: filesize for the file
|
||||
*
|
||||
* return found: 1/0.
|
||||
*/
|
||||
#define MAX_RECUR 16
|
||||
static int findFileRecursive(char *filename_new,
|
||||
const char *dirname,
|
||||
@@ -211,11 +213,14 @@ static int findFileRecursive(char *filename_new,
|
||||
struct stat status;
|
||||
char path[FILE_MAX];
|
||||
int size;
|
||||
int found = FALSE;
|
||||
|
||||
filename_new[0] = '\0';
|
||||
|
||||
dir= opendir(dirname);
|
||||
|
||||
if (dir==NULL)
|
||||
return 0;
|
||||
return found;
|
||||
|
||||
if (*filesize == -1)
|
||||
*filesize= 0; /* dir opened fine */
|
||||
@@ -237,19 +242,20 @@ static int findFileRecursive(char *filename_new,
|
||||
if ((size > 0) && (size > *filesize)) { /* find the biggest file */
|
||||
*filesize= size;
|
||||
BLI_strncpy(filename_new, path, FILE_MAX);
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (S_ISDIR(status.st_mode)) { /* is subdir */
|
||||
if (*recur_depth <= MAX_RECUR) {
|
||||
(*recur_depth)++;
|
||||
findFileRecursive(filename_new, path, filename, filesize, recur_depth);
|
||||
found |= findFileRecursive(filename_new, path, filename, filesize, recur_depth);
|
||||
(*recur_depth)--;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
return 1;
|
||||
return found;
|
||||
}
|
||||
|
||||
typedef struct BPathFind_Data
|
||||
@@ -266,19 +272,26 @@ static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char
|
||||
|
||||
int filesize= -1;
|
||||
int recur_depth= 0;
|
||||
int found;
|
||||
|
||||
findFileRecursive(filename_new,
|
||||
data->searchdir, BLI_path_basename((char *)path_src),
|
||||
&filesize, &recur_depth);
|
||||
found = findFileRecursive(filename_new,
|
||||
data->searchdir, BLI_path_basename((char *)path_src),
|
||||
&filesize, &recur_depth);
|
||||
|
||||
if (filesize == -1) { /* could not open dir */
|
||||
BKE_reportf(data->reports, RPT_WARNING,
|
||||
"Could open directory \"%s\"",
|
||||
BLI_path_basename(data->searchdir));
|
||||
return FALSE;
|
||||
}
|
||||
else if (found == FALSE) {
|
||||
BKE_reportf(data->reports, RPT_WARNING,
|
||||
"Could not find \"%s\" in \"%s\"",
|
||||
BLI_path_basename((char *)path_src), data->searchdir);
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
strcpy(path_dst, filename_new);
|
||||
BLI_strncpy(path_dst, filename_new, FILE_MAX);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -778,32 +778,38 @@ void orthogonalize_m4(float mat[][4], int axis)
|
||||
mul_v3_fl(mat[2], size[2]);
|
||||
}
|
||||
|
||||
int is_orthogonal_m3(float mat[][3])
|
||||
int is_orthogonal_m3(float m[][3])
|
||||
{
|
||||
if (fabsf(dot_v3v3(mat[0], mat[1])) > 1.5f * FLT_EPSILON)
|
||||
return 0;
|
||||
int i, j;
|
||||
|
||||
if (fabsf(dot_v3v3(mat[1], mat[2])) > 1.5f * FLT_EPSILON)
|
||||
return 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < i; j++) {
|
||||
if (fabsf(dot_v3v3(m[i], m[j])) > 1.5f * FLT_EPSILON)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fabsf(dot_v3v3(mat[0], mat[2])) > 1.5f * FLT_EPSILON)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
if (fabsf(dot_v3v3(m[i], m[i]) - 1) > 1.5f * FLT_EPSILON)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int is_orthogonal_m4(float mat[][4])
|
||||
int is_orthogonal_m4(float m[][4])
|
||||
{
|
||||
if (fabsf(dot_v3v3(mat[0], mat[1])) > 1.5f * FLT_EPSILON)
|
||||
return 0;
|
||||
int i, j;
|
||||
|
||||
if (fabsf(dot_v3v3(mat[1], mat[2])) > 1.5f * FLT_EPSILON)
|
||||
return 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < i; j++) {
|
||||
if (fabsf(dot_vn_vn(m[i], m[j], 4)) > 1.5f * FLT_EPSILON)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fabsf(dot_v3v3(mat[0], mat[2])) > 1.5f * FLT_EPSILON)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
if (fabsf(dot_vn_vn(m[i], m[i], 4) - 1) > 1.5f * FLT_EPSILON)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void normalize_m3(float mat[][3])
|
||||
|
||||
@@ -65,6 +65,7 @@ void GeometryExporter::operator()(Object *ob)
|
||||
#endif
|
||||
Mesh *me = (Mesh*)ob->data;
|
||||
std::string geom_id = get_geometry_id(ob);
|
||||
std::string geom_name = id_name(ob->data);
|
||||
std::vector<Normal> nor;
|
||||
std::vector<Face> norind;
|
||||
|
||||
@@ -78,7 +79,7 @@ void GeometryExporter::operator()(Object *ob)
|
||||
create_normals(nor, norind, me);
|
||||
|
||||
// openMesh(geoId, geoName, meshId)
|
||||
openMesh(geom_id);
|
||||
openMesh(geom_id, geom_name);
|
||||
|
||||
// writes <source> for vertex coords
|
||||
createVertsSource(geom_id, me);
|
||||
|
||||
@@ -1529,7 +1529,7 @@ static int animchannels_setflag_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
||||
/* duplicate of 'ANIM_OT_channels_setting_toggle' for menu title only, weak! */
|
||||
static void ANIM_OT_channels_setting_enable (wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
@@ -1551,7 +1551,7 @@ static void ANIM_OT_channels_setting_enable (wmOperatorType *ot)
|
||||
/* setting to set */
|
||||
ot->prop= RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
|
||||
}
|
||||
|
||||
/* duplicate of 'ANIM_OT_channels_setting_toggle' for menu title only, weak! */
|
||||
static void ANIM_OT_channels_setting_disable (wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
@@ -1574,28 +1574,6 @@ static void ANIM_OT_channels_setting_disable (wmOperatorType *ot)
|
||||
ot->prop= RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
|
||||
}
|
||||
|
||||
static void ANIM_OT_channels_setting_invert (wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Invert Channel Setting";
|
||||
ot->idname= "ANIM_OT_channels_setting_toggle";
|
||||
ot->description= "Invert specified setting on all selected animation channels";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= WM_menu_invoke;
|
||||
ot->exec= animchannels_setflag_exec;
|
||||
ot->poll= animedit_poll_channels_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* props */
|
||||
/* flag-setting mode */
|
||||
RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_INVERT, "Mode", "");
|
||||
/* setting to set */
|
||||
ot->prop= RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
|
||||
}
|
||||
|
||||
static void ANIM_OT_channels_setting_toggle (wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
@@ -2401,7 +2379,6 @@ void ED_operatortypes_animchannels(void)
|
||||
|
||||
WM_operatortype_append(ANIM_OT_channels_setting_enable);
|
||||
WM_operatortype_append(ANIM_OT_channels_setting_disable);
|
||||
WM_operatortype_append(ANIM_OT_channels_setting_invert);
|
||||
WM_operatortype_append(ANIM_OT_channels_setting_toggle);
|
||||
|
||||
WM_operatortype_append(ANIM_OT_channels_delete);
|
||||
|
||||
@@ -52,7 +52,8 @@ struct View3D;
|
||||
struct ViewContext;
|
||||
struct wmWindow;
|
||||
struct MVert;
|
||||
|
||||
struct wmOperatorType;
|
||||
struct wmOperator;
|
||||
|
||||
/* for derivedmesh drawing callbacks, for view3d_select, .... */
|
||||
typedef struct ViewContext {
|
||||
@@ -209,6 +210,7 @@ void project_short_noclip(struct ARegion *ar, const float vec[3], short adr[2]);
|
||||
void project_int(struct ARegion *ar, const float vec[3], int adr[2]);
|
||||
void project_int_noclip(struct ARegion *ar, const float vec[3], int adr[2]);
|
||||
|
||||
void apply_project_float(float persmat[4][4], int winx, int winy, const float vec[], float adr[2]);
|
||||
void project_float(struct ARegion *ar, const float vec[3], float adr[2]);
|
||||
void project_float_noclip(struct ARegion *ar, const float vec[3], float adr[2]);
|
||||
|
||||
@@ -301,4 +303,9 @@ struct BGpic *ED_view3D_background_image_new(struct View3D *v3d);
|
||||
void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic);
|
||||
void ED_view3D_background_image_clear(struct View3D *v3d);
|
||||
|
||||
/* view matrix properties utilities */
|
||||
void ED_view3d_operator_properties_viewmat(struct wmOperatorType *ot);
|
||||
void ED_view3d_operator_properties_viewmat_set(struct bContext *C, struct wmOperator *op);
|
||||
void ED_view3d_operator_properties_viewmat_get(struct wmOperator *op, int *winx, int *winy, float persmat[4][4]);
|
||||
|
||||
#endif /* ED_VIEW3D_H */
|
||||
|
||||
@@ -1529,38 +1529,40 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
|
||||
width= rect.xmax-rect.xmin+1;
|
||||
height = rect.ymax-rect.ymin;
|
||||
|
||||
zoomx= (float)width / (scopes->track_preview->x-2*margin);
|
||||
zoomy= (float)height / (scopes->track_preview->y-2*margin);
|
||||
if(width > 0 && height > 0) {
|
||||
zoomx= (float)width / (scopes->track_preview->x-2*margin);
|
||||
zoomy= (float)height / (scopes->track_preview->y-2*margin);
|
||||
|
||||
off_x= ((int)track_pos[0]-track_pos[0]+0.5)*zoomx;
|
||||
off_y= ((int)track_pos[1]-track_pos[1]+0.5)*zoomy;
|
||||
off_x= ((int)track_pos[0]-track_pos[0]+0.5)*zoomx;
|
||||
off_y= ((int)track_pos[1]-track_pos[1]+0.5)*zoomy;
|
||||
|
||||
drawibuf= scale_trackpreview_ibuf(scopes->track_preview, track_pos, width, height, margin);
|
||||
drawibuf= scale_trackpreview_ibuf(scopes->track_preview, track_pos, width, height, margin);
|
||||
|
||||
glaDrawPixelsSafe(rect.xmin, rect.ymin+1, drawibuf->x, drawibuf->y,
|
||||
drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect);
|
||||
IMB_freeImBuf(drawibuf);
|
||||
glaDrawPixelsSafe(rect.xmin, rect.ymin+1, drawibuf->x, drawibuf->y,
|
||||
drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect);
|
||||
IMB_freeImBuf(drawibuf);
|
||||
|
||||
/* draw cross for pizel position */
|
||||
glTranslatef(off_x+rect.xmin+track_pos[0]*zoomx, off_y+rect.ymin+track_pos[1]*zoomy, 0.f);
|
||||
glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin+rect.ymin, rect.xmax-rect.xmin, rect.ymax-rect.ymin);
|
||||
/* draw cross for pizel position */
|
||||
glTranslatef(off_x+rect.xmin+track_pos[0]*zoomx, off_y+rect.ymin+track_pos[1]*zoomy, 0.f);
|
||||
glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin+rect.ymin, rect.xmax-rect.xmin, rect.ymax-rect.ymin);
|
||||
|
||||
for(a= 0; a< 2; a++) {
|
||||
if(a==1) {
|
||||
glLineStipple(3, 0xaaaa);
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
UI_ThemeColor(TH_SEL_MARKER);
|
||||
for(a= 0; a< 2; a++) {
|
||||
if(a==1) {
|
||||
glLineStipple(3, 0xaaaa);
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
UI_ThemeColor(TH_SEL_MARKER);
|
||||
}
|
||||
else {
|
||||
UI_ThemeColor(TH_MARKER_OUTLINE);
|
||||
}
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(-10.0f, 0.0f);
|
||||
glVertex2f(10.0f, 0.0f);
|
||||
glVertex2f(0.0f, -10.0f);
|
||||
glVertex2f(0.0f, 10.0f);
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
UI_ThemeColor(TH_MARKER_OUTLINE);
|
||||
}
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(-10.0f, 0.0f);
|
||||
glVertex2f(10.0f, 0.0f);
|
||||
glVertex2f(0.0f, -10.0f);
|
||||
glVertex2f(0.0f, 10.0f);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
|
||||
@@ -1527,6 +1527,8 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction
|
||||
const int pos_prev= but->pos;
|
||||
const int has_sel= (but->selend - but->selsta) > 0;
|
||||
|
||||
ui_check_but(but);
|
||||
|
||||
/* special case, quit selection and set cursor */
|
||||
if (has_sel && !select) {
|
||||
if (jump == BUTTON_EDIT_JUMP_ALL) {
|
||||
@@ -3030,12 +3032,28 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
|
||||
data->value= ui_step_name_menu(but, -1);
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
ui_apply_button(C, but->block, but, data, 1);
|
||||
|
||||
/* button's state need to be changed to EXIT so moving mouse away from this mouse wouldn't lead
|
||||
* to cancel changes made to this button, but shanging state to EXIT also makes no button active for
|
||||
* a while which leads to triggering operator when doing fast scrolling mouse wheel.
|
||||
* using post activate stuff from button allows to make button be active again after checking for all
|
||||
* all that mouse leave and cancel stuff, so wuick scrool wouldnt't be an issue anumore.
|
||||
* same goes for scrolling wheel in another direction below (sergey)
|
||||
*/
|
||||
data->postbut= but;
|
||||
data->posttype= BUTTON_ACTIVATE_OVER;
|
||||
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
else if(event->type == WHEELUPMOUSE && event->alt) {
|
||||
data->value= ui_step_name_menu(but, 1);
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
ui_apply_button(C, but->block, but, data, 1);
|
||||
|
||||
/* why this is needed described above */
|
||||
data->postbut= but;
|
||||
data->posttype= BUTTON_ACTIVATE_OVER;
|
||||
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1541,6 +1541,8 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
|
||||
if(ELEM(but->type, BLOCK, PULLDOWN))
|
||||
block->xofs = -2; /* for proper alignment */
|
||||
|
||||
block->aspect = but->block->aspect;
|
||||
|
||||
ui_block_position(window, butregion, but, block);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -2150,7 +2150,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
|
||||
Object *ob= (Object*)activeptr->data;
|
||||
Key *key= (Key*)itemptr->id.data;
|
||||
|
||||
split= uiLayoutSplit(sub, 0.75f, 0);
|
||||
split= uiLayoutSplit(sub, 0.66f, 0);
|
||||
|
||||
uiItemL(split, name, icon);
|
||||
|
||||
@@ -2158,10 +2158,13 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
|
||||
row= uiLayoutRow(split, 1);
|
||||
if(i == 0 || (key->type != KEY_RELATIVE)) uiItemL(row, "", ICON_NONE);
|
||||
else uiItemR(row, itemptr, "value", 0, "", ICON_NONE);
|
||||
uiItemR(row, itemptr, "mute", 0, "", 0);
|
||||
|
||||
if(ob->mode == OB_MODE_EDIT && !((ob->shapeflag & OB_SHAPE_EDIT_MODE) && ob->type == OB_MESH))
|
||||
if( (key->flag & KEYBLOCK_MUTE) ||
|
||||
(ob->mode == OB_MODE_EDIT && !((ob->shapeflag & OB_SHAPE_EDIT_MODE) && ob->type == OB_MESH)) )
|
||||
{
|
||||
uiLayoutSetActive(row, 0);
|
||||
//uiItemR(row, itemptr, "mute", 0, "", ICON_MUTE_IPO_OFF);
|
||||
}
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
}
|
||||
else if(itemptr->type == &RNA_VertexGroup) {
|
||||
|
||||
@@ -952,6 +952,9 @@ static void ui_text_leftclip(uiFontStyle *fstyle, uiBut *but, rcti *rect)
|
||||
if(but->editstr && but->pos >= 0) {
|
||||
if(but->ofs > but->pos)
|
||||
but->ofs= but->pos;
|
||||
|
||||
if(BLF_width(fstyle->uifont_id, but->drawstr) <= okwidth)
|
||||
but->ofs = 0;
|
||||
}
|
||||
else but->ofs= 0;
|
||||
|
||||
|
||||
@@ -288,11 +288,17 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
|
||||
/* for amount of edges */
|
||||
#define MAX_CUT_EDGES 1024
|
||||
|
||||
static int knife_cut_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
ED_view3d_operator_properties_viewmat_set(C, op);
|
||||
|
||||
return WM_gesture_lines_invoke(C, op, event);
|
||||
}
|
||||
|
||||
static int knife_cut_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
EditEdge *eed;
|
||||
EditVert *eve;
|
||||
CutCurve curve[MAX_CUT_EDGES];
|
||||
@@ -302,10 +308,12 @@ static int knife_cut_exec(bContext *C, wmOperator *op)
|
||||
int len=0;
|
||||
short numcuts= RNA_int_get(op->ptr, "num_cuts");
|
||||
short mode= RNA_enum_get(op->ptr, "type");
|
||||
int winx, winy;
|
||||
float persmat[4][4];
|
||||
// int corner_cut_pattern= RNA_enum_get(op->ptr,"corner_cut_pattern");
|
||||
|
||||
/* edit-object needed for matrix, and ar->regiondata for projections to work */
|
||||
if (ELEM3(NULL, obedit, ar, ar->regiondata))
|
||||
if (obedit == NULL)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
if (EM_nvertices_selected(em) < 2) {
|
||||
@@ -328,6 +336,8 @@ static int knife_cut_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
ED_view3d_operator_properties_viewmat_get(op, &winx, &winy, persmat);
|
||||
|
||||
/*store percentage of edge cut for KNIFE_EXACT here.*/
|
||||
for(eed=em->edges.first; eed; eed= eed->next)
|
||||
eed->tmp.fp = 0.0;
|
||||
@@ -339,7 +349,7 @@ static int knife_cut_exec(bContext *C, wmOperator *op)
|
||||
VECCOPY(co, eve->co);
|
||||
co[3]= 1.0;
|
||||
mul_m4_v4(obedit->obmat, co);
|
||||
project_float(ar, co, scr);
|
||||
apply_project_float(persmat, winx, winy, co, scr);
|
||||
BLI_ghash_insert(gh, eve, scr);
|
||||
eve->f1 = 0; /*store vertex intersection flag here*/
|
||||
|
||||
@@ -390,7 +400,7 @@ void MESH_OT_knife_cut(wmOperatorType *ot)
|
||||
ot->description= "Cut selected edges and faces into parts";
|
||||
ot->idname= "MESH_OT_knife_cut";
|
||||
|
||||
ot->invoke= WM_gesture_lines_invoke;
|
||||
ot->invoke= knife_cut_invoke;
|
||||
ot->modal= WM_gesture_lines_modal;
|
||||
ot->exec= knife_cut_exec;
|
||||
ot->cancel= WM_gesture_lines_cancel;
|
||||
@@ -407,7 +417,10 @@ void MESH_OT_knife_cut(wmOperatorType *ot)
|
||||
// doesn't work atm.. RNA_def_enum(ot->srna, "corner_cut_pattern", corner_type_items, SUBDIV_CORNER_INNERVERT, "Corner Cut Pattern", "Topology pattern to use to fill a face after cutting across its corner");
|
||||
|
||||
/* internal */
|
||||
RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
|
||||
prop = RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
ED_view3d_operator_properties_viewmat(ot);
|
||||
}
|
||||
|
||||
/* ******************************************************* */
|
||||
|
||||
@@ -183,7 +183,7 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
|
||||
|
||||
layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
|
||||
if(layernum >= MAX_MTFACE)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
EM_add_data_layer(em, &em->fdata, CD_MTFACE, name);
|
||||
|
||||
@@ -196,7 +196,7 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
|
||||
else {
|
||||
layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
|
||||
if(layernum >= MAX_MTFACE)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
if(me->mtface)
|
||||
CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_DUPLICATE, me->mtface, me->totface, name);
|
||||
@@ -212,7 +212,7 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
|
||||
DAG_id_tag_update(&me->id, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
|
||||
|
||||
return 1;
|
||||
return layernum;
|
||||
}
|
||||
|
||||
int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me)
|
||||
@@ -244,7 +244,7 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes
|
||||
|
||||
layernum= CustomData_number_of_layers(&em->fdata, CD_MCOL);
|
||||
if(layernum >= MAX_MCOL)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
EM_add_data_layer(em, &em->fdata, CD_MCOL, name);
|
||||
|
||||
@@ -257,7 +257,7 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes
|
||||
else {
|
||||
layernum= CustomData_number_of_layers(&me->fdata, CD_MCOL);
|
||||
if(layernum >= MAX_MCOL)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
if(me->mcol)
|
||||
CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface, name);
|
||||
@@ -273,7 +273,7 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes
|
||||
DAG_id_tag_update(&me->id, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
|
||||
|
||||
return 1;
|
||||
return layernum;
|
||||
}
|
||||
|
||||
int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me)
|
||||
@@ -328,7 +328,7 @@ static int uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
Object *ob= ED_object_context(C);
|
||||
Mesh *me= ob->data;
|
||||
|
||||
if(!ED_mesh_uv_texture_add(C, me, NULL, TRUE))
|
||||
if(ED_mesh_uv_texture_add(C, me, NULL, TRUE) == -1)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -467,7 +467,7 @@ static int vertex_color_add_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
Object *ob= ED_object_context(C);
|
||||
Mesh *me= ob->data;
|
||||
|
||||
if(!ED_mesh_color_add(C, scene, ob, me, NULL, TRUE))
|
||||
if(ED_mesh_color_add(C, scene, ob, me, NULL, TRUE) == -1)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
@@ -1001,6 +1001,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
|
||||
DerivedMesh *cddm= CDDM_from_mesh(me, ob);
|
||||
|
||||
tmp_mmd.lvl= *lvl;
|
||||
tmp_mmd.sculptlvl= *lvl;
|
||||
dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0);
|
||||
cddm->release(cddm);
|
||||
}
|
||||
|
||||
@@ -536,7 +536,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
|
||||
int numVerts;
|
||||
float (*vertexCos)[3];
|
||||
|
||||
if (mti->type==eModifierTypeType_Constructive) {
|
||||
if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) {
|
||||
BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@@ -160,6 +161,11 @@ static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
FileBrowseOp *fbo;
|
||||
char *str;
|
||||
|
||||
if (CTX_wm_space_file(C)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't activate a file selector, one already open");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
uiFileBrowseContextProperty(C, &ptr, &prop);
|
||||
|
||||
if(!prop)
|
||||
|
||||
@@ -834,6 +834,27 @@ static void proxy_freejob(void *pjv)
|
||||
MEM_freeN(pj);
|
||||
}
|
||||
|
||||
static int proxy_bitflag_to_array(int size_flag, int build_sizes[4], int undistort)
|
||||
{
|
||||
int build_count = 0;
|
||||
int size_flags[2][4] = {{MCLIP_PROXY_SIZE_25,
|
||||
MCLIP_PROXY_SIZE_50,
|
||||
MCLIP_PROXY_SIZE_75,
|
||||
MCLIP_PROXY_SIZE_100},
|
||||
{MCLIP_PROXY_UNDISTORTED_SIZE_25,
|
||||
MCLIP_PROXY_UNDISTORTED_SIZE_50,
|
||||
MCLIP_PROXY_UNDISTORTED_SIZE_75,
|
||||
MCLIP_PROXY_UNDISTORTED_SIZE_100}};
|
||||
int size_nr = undistort ? 1 : 0;
|
||||
|
||||
if(size_flag & size_flags[size_nr][0]) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_25;
|
||||
if(size_flag & size_flags[size_nr][1]) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_50;
|
||||
if(size_flag & size_flags[size_nr][2]) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_75;
|
||||
if(size_flag & size_flags[size_nr][3]) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_100;
|
||||
|
||||
return build_count;
|
||||
}
|
||||
|
||||
/* only this runs inside thread */
|
||||
static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
@@ -841,22 +862,23 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog
|
||||
Scene *scene=pj->scene;
|
||||
MovieClip *clip= pj->clip;
|
||||
struct MovieDistortion *distortion= NULL;
|
||||
int cfra, undistort;
|
||||
short tc_flag, size_flag, quality, build_flag;
|
||||
int sfra= SFRA, efra= EFRA;
|
||||
short tc_flag, size_flag, quality;
|
||||
int cfra, sfra= SFRA, efra= EFRA;
|
||||
int build_sizes[4], build_count= 0;
|
||||
int build_undistort_sizes[4], build_undistort_count= 0;
|
||||
|
||||
tc_flag= clip->proxy.build_tc_flag;
|
||||
size_flag= clip->proxy.build_size_flag;
|
||||
quality= clip->proxy.quality;
|
||||
build_flag= clip->proxy.build_flag;
|
||||
undistort= build_flag&MCLIP_PROXY_RENDER_UNDISTORT;
|
||||
|
||||
build_count= proxy_bitflag_to_array(size_flag, build_sizes, 0);
|
||||
build_undistort_count= proxy_bitflag_to_array(size_flag, build_undistort_sizes, 1);
|
||||
|
||||
if(clip->source == MCLIP_SRC_MOVIE) {
|
||||
if(clip->anim)
|
||||
IMB_anim_index_rebuild(clip->anim, tc_flag, size_flag, quality, stop, do_update, progress);
|
||||
|
||||
if(!undistort) {
|
||||
if(!build_undistort_count) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@@ -865,20 +887,14 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog
|
||||
}
|
||||
}
|
||||
|
||||
if(size_flag&IMB_PROXY_25) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_25;
|
||||
if(size_flag&IMB_PROXY_50) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_50;
|
||||
if(size_flag&IMB_PROXY_75) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_75;
|
||||
if(size_flag&IMB_PROXY_100) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_100;
|
||||
|
||||
if(undistort)
|
||||
if(build_undistort_count)
|
||||
distortion= BKE_tracking_distortion_create();
|
||||
|
||||
for(cfra= sfra; cfra<=efra; cfra++) {
|
||||
if(clip->source != MCLIP_SRC_MOVIE)
|
||||
BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, NULL, cfra, build_sizes, build_count, 0);
|
||||
|
||||
if(undistort)
|
||||
BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, distortion, cfra, build_sizes, build_count, 1);
|
||||
BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, distortion, cfra, build_undistort_sizes, build_undistort_count, 1);
|
||||
|
||||
if(*stop || G.afbreek)
|
||||
break;
|
||||
|
||||
@@ -604,10 +604,6 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
|
||||
ar_main->alignment= RGN_ALIGN_NONE;
|
||||
view_changed= 1;
|
||||
}
|
||||
if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) {
|
||||
ar_preview->alignment= RGN_ALIGN_NONE;
|
||||
view_changed= 1;
|
||||
}
|
||||
break;
|
||||
case SC_VIEW_GRAPH:
|
||||
if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) {
|
||||
@@ -620,7 +616,7 @@ static void clip_refresh(const bContext *C, ScrArea *sa)
|
||||
ar_main->alignment= RGN_ALIGN_NONE;
|
||||
view_changed= 1;
|
||||
}
|
||||
if (ar_preview && ar_preview->alignment != RGN_ALIGN_TOP) {
|
||||
if (ar_preview && !ELEM(ar_preview->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) {
|
||||
ar_preview->alignment= RGN_ALIGN_TOP;
|
||||
view_changed= 1;
|
||||
}
|
||||
|
||||
@@ -2757,7 +2757,7 @@ static int detect_features_exec(bContext *C, wmOperator *op)
|
||||
SpaceClip *sc= CTX_wm_space_clip(C);
|
||||
MovieClip *clip= ED_space_clip(sc);
|
||||
int clip_flag= clip->flag&MCLIP_TIMECODE_FLAGS;
|
||||
ImBuf *ibuf= BKE_movieclip_get_ibuf_flag(clip, &sc->user, clip_flag);
|
||||
ImBuf *ibuf= BKE_movieclip_get_ibuf_flag(clip, &sc->user, clip_flag, MOVIECLIP_CACHE_SKIP);
|
||||
MovieTracking *tracking= &clip->tracking;
|
||||
ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
|
||||
MovieTrackingTrack *track= tracksbase->first;
|
||||
|
||||
@@ -1096,8 +1096,14 @@ static void file_expand_directory(bContext *C)
|
||||
BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BLI_getDefaultDocumentFolder(), tmpstr);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
if (sfile->params->dir[0] == '\0') {
|
||||
else if (sfile->params->dir[0] == '\0')
|
||||
#ifndef WIN32
|
||||
{
|
||||
sfile->params->dir[0] = '/';
|
||||
sfile->params->dir[1] = '\0';
|
||||
}
|
||||
#else
|
||||
{
|
||||
get_default_root(sfile->params->dir);
|
||||
}
|
||||
/* change "C:" --> "C:\", [#28102] */
|
||||
|
||||
@@ -855,14 +855,13 @@ static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(e
|
||||
SpaceNode *snode = CTX_wm_space_node(C);
|
||||
bNode *gnode;
|
||||
|
||||
gnode = nodeGetActive(snode->edittree);
|
||||
if (!gnode)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* XXX callback? */
|
||||
if(gnode && gnode->id && GS(gnode->id->name)==ID_NT && gnode->id->lib) {
|
||||
uiPupMenuOkee(C, op->type->idname, "Make group local?");
|
||||
return OPERATOR_CANCELLED;
|
||||
if (snode->nodetree==snode->edittree) {
|
||||
gnode = nodeGetActive(snode->edittree);
|
||||
if(gnode && gnode->id && GS(gnode->id->name)==ID_NT && gnode->id->lib) {
|
||||
uiPupMenuOkee(C, op->type->idname, "Make group local?");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
return node_group_edit_exec(C, op);
|
||||
|
||||
@@ -553,7 +553,10 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
|
||||
BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name);
|
||||
}
|
||||
else if (seq->type == SEQ_SOUND) {
|
||||
BLI_snprintf(str, sizeof(str), "%d | %s: %s", seq->len, name, seq->sound->name);
|
||||
if(seq->sound)
|
||||
BLI_snprintf(str, sizeof(str), "%d | %s: %s", seq->len, name, seq->sound->name);
|
||||
else
|
||||
BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name);
|
||||
}
|
||||
else if (seq->type == SEQ_MOVIE) {
|
||||
BLI_snprintf(str, sizeof(str), "%d | %s: %s%s", seq->len, name, seq->strip->dir, seq->strip->stripdata->name);
|
||||
|
||||
@@ -4042,7 +4042,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
ParticleDrawData *pdd = psys->pdd;
|
||||
Material *ma;
|
||||
float vel[3], imat[4][4];
|
||||
float timestep, pixsize=1.0, pa_size, r_tilt, r_length;
|
||||
float timestep, pixsize_scale, pa_size, r_tilt, r_length;
|
||||
float pa_time, pa_birthtime, pa_dietime, pa_health, intensity;
|
||||
float cfra;
|
||||
float ma_col[3]= {0.0f, 0.0f, 0.0f};
|
||||
@@ -4149,12 +4149,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
case PART_DRAW_CROSS:
|
||||
case PART_DRAW_AXIS:
|
||||
/* lets calculate the scale: */
|
||||
pixsize= ED_view3d_pixel_size(rv3d, ob->obmat[3]);
|
||||
|
||||
if(part->draw_size==0.0)
|
||||
pixsize *= 2.0f;
|
||||
if (part->draw_size == 0.0)
|
||||
pixsize_scale = 2.0f;
|
||||
else
|
||||
pixsize*=part->draw_size;
|
||||
pixsize_scale = part->draw_size;
|
||||
|
||||
if(draw_as==PART_DRAW_AXIS)
|
||||
create_cdata = 1;
|
||||
@@ -4342,6 +4341,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
|
||||
ct+=dt;
|
||||
for(i=0; i < trail_count; i++, ct += dt) {
|
||||
float pixsize;
|
||||
|
||||
if(part->draw & PART_ABS_PATH_TIME) {
|
||||
if(ct < pa_birthtime || ct > pa_dietime)
|
||||
continue;
|
||||
@@ -4375,6 +4376,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
bb.time = ct;
|
||||
}
|
||||
|
||||
pixsize = ED_view3d_pixel_size(rv3d, state.co) * pixsize_scale;
|
||||
|
||||
draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd);
|
||||
|
||||
totpoint++;
|
||||
@@ -4385,6 +4388,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
{
|
||||
state.time=cfra;
|
||||
if(psys_get_particle_state(&sim,a,&state,0)){
|
||||
float pixsize;
|
||||
|
||||
if(psys->parent)
|
||||
mul_m4_v3(psys->parent->obmat, state.co);
|
||||
|
||||
@@ -4408,6 +4413,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
bb.time = pa_time;
|
||||
}
|
||||
|
||||
pixsize = ED_view3d_pixel_size(rv3d, state.co) * pixsize_scale;
|
||||
|
||||
draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd);
|
||||
|
||||
totpoint++;
|
||||
|
||||
@@ -68,6 +68,9 @@
|
||||
#include "BL_System.h"
|
||||
#endif
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "view3d_intern.h" // own include
|
||||
|
||||
/* use this call when executing an operator,
|
||||
@@ -947,23 +950,29 @@ void project_short_noclip(ARegion *ar, const float vec[3], short adr[2])
|
||||
}
|
||||
}
|
||||
|
||||
void project_float(ARegion *ar, const float vec[3], float adr[2])
|
||||
void apply_project_float(float persmat[4][4], int winx, int winy, const float vec[3], float adr[2])
|
||||
{
|
||||
RegionView3D *rv3d= ar->regiondata;
|
||||
float vec4[4];
|
||||
|
||||
|
||||
copy_v3_v3(vec4, vec);
|
||||
vec4[3]= 1.0;
|
||||
adr[0]= IS_CLIPPED;
|
||||
|
||||
mul_m4_v4(rv3d->persmat, vec4);
|
||||
|
||||
|
||||
mul_m4_v4(persmat, vec4);
|
||||
|
||||
if(vec4[3] > (float)BL_NEAR_CLIP) {
|
||||
adr[0] = (float)(ar->winx/2.0f)+(ar->winx/2.0f)*vec4[0]/vec4[3];
|
||||
adr[1] = (float)(ar->winy/2.0f)+(ar->winy/2.0f)*vec4[1]/vec4[3];
|
||||
adr[0] = (float)(winx/2.0f)+(winx/2.0f)*vec4[0]/vec4[3];
|
||||
adr[1] = (float)(winy/2.0f)+(winy/2.0f)*vec4[1]/vec4[3];
|
||||
}
|
||||
}
|
||||
|
||||
void project_float(ARegion *ar, const float vec[3], float adr[2])
|
||||
{
|
||||
RegionView3D *rv3d= ar->regiondata;
|
||||
|
||||
apply_project_float(rv3d->persmat, ar->winx, ar->winy, vec, adr);
|
||||
}
|
||||
|
||||
void project_float_noclip(ARegion *ar, const float vec[3], float adr[2])
|
||||
{
|
||||
RegionView3D *rv3d= ar->regiondata;
|
||||
@@ -1854,3 +1863,42 @@ float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3])
|
||||
rv3d->persmat[2][3]*co[2])
|
||||
) * rv3d->pixsize;
|
||||
}
|
||||
|
||||
/* view matrix properties utilities */
|
||||
|
||||
void ED_view3d_operator_properties_viewmat(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_def_int(ot->srna, "region_width", 0, 0, INT_MAX, "Region Width", "", 0, INT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
prop = RNA_def_int(ot->srna, "region_height", 0, 0, INT_MAX, "Region height", "", 0, INT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
|
||||
prop = RNA_def_float_matrix(ot->srna, "perspective_matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Perspective Matrix", 0.0f, 0.0f);
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
}
|
||||
|
||||
void ED_view3d_operator_properties_viewmat_set(bContext *C, wmOperator *op)
|
||||
{
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
RegionView3D *rv3d= ED_view3d_context_rv3d(C);
|
||||
|
||||
if(!RNA_struct_property_is_set(op->ptr, "region_width"))
|
||||
RNA_int_set(op->ptr, "region_width", ar->winx);
|
||||
|
||||
if(!RNA_struct_property_is_set(op->ptr, "region_height"))
|
||||
RNA_int_set(op->ptr, "region_height", ar->winy);
|
||||
|
||||
if(!RNA_struct_property_is_set(op->ptr, "perspective_matrix"))
|
||||
RNA_float_set_array(op->ptr, "perspective_matrix", (float *)rv3d->persmat);
|
||||
}
|
||||
|
||||
void ED_view3d_operator_properties_viewmat_get(wmOperator *op, int *winx, int *winy, float persmat[4][4])
|
||||
{
|
||||
*winx = RNA_int_get(op->ptr, "region_width");
|
||||
*winy = RNA_int_get(op->ptr, "region_height");
|
||||
|
||||
RNA_float_get_array(op->ptr, "perspective_matrix", (float *)persmat);
|
||||
}
|
||||
|
||||
@@ -5640,10 +5640,13 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
|
||||
SpaceClip *sc = CTX_wm_space_clip(C);
|
||||
MovieClip *clip = ED_space_clip(sc);
|
||||
|
||||
if(!clip || !BKE_movieclip_has_frame(clip, &sc->user)) {
|
||||
t->total = 0;
|
||||
t->total = 0;
|
||||
|
||||
if(!clip || !BKE_movieclip_has_frame(clip, &sc->user))
|
||||
return;
|
||||
|
||||
if(!ELEM(t->mode, TFM_RESIZE, TFM_TRANSLATION))
|
||||
return;
|
||||
}
|
||||
|
||||
if(ar->regiontype == RGN_TYPE_PREVIEW) {
|
||||
/* transformation was called from graph editor */
|
||||
|
||||
@@ -1230,6 +1230,11 @@ void mtex_bump_tap3( vec3 texco, sampler2D ima, float hScale,
|
||||
void mtex_bump_bicubic( vec3 texco, sampler2D ima, float hScale,
|
||||
out float dBs, out float dBt )
|
||||
{
|
||||
float Hl;
|
||||
float Hr;
|
||||
float Hd;
|
||||
float Hu;
|
||||
|
||||
vec2 TexDx = dFdx(texco.xy);
|
||||
vec2 TexDy = dFdy(texco.xy);
|
||||
|
||||
@@ -1238,10 +1243,10 @@ void mtex_bump_bicubic( vec3 texco, sampler2D ima, float hScale,
|
||||
vec2 STd = texco.xy - 0.5 * TexDy ;
|
||||
vec2 STu = texco.xy + 0.5 * TexDy ;
|
||||
|
||||
float Hl = texture2D(ima, STl).x;
|
||||
float Hr = texture2D(ima, STr).x;
|
||||
float Hd = texture2D(ima, STd).x;
|
||||
float Hu = texture2D(ima, STu).x;
|
||||
rgbtobw(texture2D(ima, STl), Hl);
|
||||
rgbtobw(texture2D(ima, STr), Hr);
|
||||
rgbtobw(texture2D(ima, STd), Hd);
|
||||
rgbtobw(texture2D(ima, STu), Hu);
|
||||
|
||||
vec2 dHdxy = vec2(Hr - Hl, Hu - Hd);
|
||||
float fBlend = clamp(1.0-textureQueryLOD(ima, texco.xy).x, 0.0, 1.0);
|
||||
@@ -1251,12 +1256,14 @@ void mtex_bump_bicubic( vec3 texco, sampler2D ima, float hScale,
|
||||
ivec2 vDim;
|
||||
vDim = textureSize(ima, 0);
|
||||
|
||||
vec2 fTexLoc = vDim*texco.xy-vec2(0.5,0.5);
|
||||
// taking the fract part of the texture coordinate is a hardcoded wrap mode.
|
||||
// this is acceptable as textures use wrap mode exclusively in 3D view elsewhere in blender.
|
||||
// this is done so that we can still get a valid texel with uvs outside the 0,1 range
|
||||
// by texelFetch below, as coordinates are clamped when using this function.
|
||||
vec2 fTexLoc = vDim*fract(texco.xy) - vec2(0.5, 0.5);
|
||||
ivec2 iTexLoc = ivec2(floor(fTexLoc));
|
||||
vec2 t = clamp(fTexLoc - iTexLoc, 0.0, 1.0); // sat just to be pedantic
|
||||
|
||||
ivec2 iTexLocMod = iTexLoc + ivec2(-1, -1);
|
||||
|
||||
/*******************************************************************************************
|
||||
* This block will replace the one below when one channel textures are properly supported. *
|
||||
*******************************************************************************************
|
||||
@@ -1264,17 +1271,26 @@ void mtex_bump_bicubic( vec3 texco, sampler2D ima, float hScale,
|
||||
vec4 vSamplesUR = textureGather(ima, (iTexLoc+ivec2(1,-1) + vec2(0.5,0.5))/vDim );
|
||||
vec4 vSamplesLL = textureGather(ima, (iTexLoc+ivec2(-1,1) + vec2(0.5,0.5))/vDim );
|
||||
vec4 vSamplesLR = textureGather(ima, (iTexLoc+ivec2(1,1) + vec2(0.5,0.5))/vDim );
|
||||
|
||||
|
||||
mat4 H = mat4(vSamplesUL.w, vSamplesUL.x, vSamplesLL.w, vSamplesLL.x,
|
||||
vSamplesUL.z, vSamplesUL.y, vSamplesLL.z, vSamplesLL.y,
|
||||
vSamplesUR.w, vSamplesUR.x, vSamplesLR.w, vSamplesLR.x,
|
||||
vSamplesUR.z, vSamplesUR.y, vSamplesLR.z, vSamplesLR.y);
|
||||
*/
|
||||
ivec2 iTexLocMod = iTexLoc + ivec2(-1, -1);
|
||||
|
||||
mat4 H;
|
||||
|
||||
for(int i = 0; i < 4; i++){
|
||||
for(int j = 0; j < 4; j++){
|
||||
mtex_rgbtoint(texelFetch(ima, (iTexLocMod + ivec2(i,j)), 0), H[i][j]);
|
||||
ivec2 iTexTmp = iTexLocMod + ivec2(i,j);
|
||||
|
||||
// wrap texture coordinates manually for texelFetch to work on uvs oitside the 0,1 range.
|
||||
// this is guaranteed to work since we take the fractional part of the uv above.
|
||||
iTexTmp.x = (iTexTmp.x < 0)? iTexTmp.x + vDim.x : ((iTexTmp.x >= vDim.x)? iTexTmp.x - vDim.x : iTexTmp.x);
|
||||
iTexTmp.y = (iTexTmp.y < 0)? iTexTmp.y + vDim.y : ((iTexTmp.y >= vDim.y)? iTexTmp.y - vDim.y : iTexTmp.y);
|
||||
|
||||
rgbtobw(texelFetch(ima, iTexTmp, 0), H[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -147,10 +147,10 @@ static void IMB_moviecache_destructor(void *p)
|
||||
}
|
||||
|
||||
/* approximate size of ImBuf in memory */
|
||||
static intptr_t IMB_get_size_in_memory(ImBuf *ibuf)
|
||||
static size_t IMB_get_size_in_memory(ImBuf *ibuf)
|
||||
{
|
||||
int a;
|
||||
intptr_t size= 0, channel_size= 0;
|
||||
size_t size= 0, channel_size= 0;
|
||||
|
||||
size+= sizeof(ImBuf);
|
||||
|
||||
@@ -176,9 +176,9 @@ static intptr_t IMB_get_size_in_memory(ImBuf *ibuf)
|
||||
return size;
|
||||
}
|
||||
|
||||
static intptr_t get_item_size (void *p)
|
||||
static size_t get_item_size (void *p)
|
||||
{
|
||||
intptr_t size= sizeof(MovieCacheItem);
|
||||
size_t size= sizeof(MovieCacheItem);
|
||||
MovieCacheItem *item= (MovieCacheItem *) p;
|
||||
|
||||
if(item->ibuf)
|
||||
|
||||
@@ -57,8 +57,6 @@ typedef struct MovieClipProxy {
|
||||
short quality; /* proxy build quality */
|
||||
short build_size_flag; /* size flags (see below) of all proxies to build */
|
||||
short build_tc_flag; /* time code flags (see below) of all tc indices to build */
|
||||
short build_flag, pad; /* other build flags */
|
||||
char pad2[4];
|
||||
} MovieClipProxy;
|
||||
|
||||
typedef struct MovieClip {
|
||||
@@ -98,8 +96,15 @@ typedef struct MovieClipScopes {
|
||||
float slide_scale[2]; /* scale used for sliding from previewe area */
|
||||
} MovieClipScopes;
|
||||
|
||||
/* MovieClipProxy->build_flag */
|
||||
#define MCLIP_PROXY_BUILD_UNDISTORT 1 /* build undistorted proxies as well */
|
||||
/* MovieClipProxy->build_size_flag */
|
||||
#define MCLIP_PROXY_SIZE_25 (1<<0)
|
||||
#define MCLIP_PROXY_SIZE_50 (1<<1)
|
||||
#define MCLIP_PROXY_SIZE_75 (1<<2)
|
||||
#define MCLIP_PROXY_SIZE_100 (1<<3)
|
||||
#define MCLIP_PROXY_UNDISTORTED_SIZE_25 (1<<4)
|
||||
#define MCLIP_PROXY_UNDISTORTED_SIZE_50 (1<<5)
|
||||
#define MCLIP_PROXY_UNDISTORTED_SIZE_75 (1<<6)
|
||||
#define MCLIP_PROXY_UNDISTORTED_SIZE_100 (1<<7)
|
||||
|
||||
/* MovieClip->source */
|
||||
#define MCLIP_SRC_SEQUENCE 1
|
||||
|
||||
@@ -74,6 +74,9 @@ typedef struct FluidsimSettings {
|
||||
float animStart, animEnd;
|
||||
/* bake start end time (in blender frames) */
|
||||
int bakeStart, bakeEnd;
|
||||
/* offset for baked frames */
|
||||
int frameOffset;
|
||||
int pad;
|
||||
/* g star param (LBM compressibility) */
|
||||
float gstar;
|
||||
/* activate refinement? */
|
||||
|
||||
@@ -121,6 +121,9 @@ typedef struct MovieTrackingSettings {
|
||||
short default_frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */
|
||||
short default_margin; /* margin from frame boundaries */
|
||||
short default_pattern_match; /* re-adjust every N frames */
|
||||
short default_flag; /* default flags like color channels used by default */
|
||||
|
||||
short pod;
|
||||
|
||||
/* ** common tracker settings ** */
|
||||
short speed; /* speed of tracking */
|
||||
@@ -129,7 +132,7 @@ typedef struct MovieTrackingSettings {
|
||||
int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */
|
||||
|
||||
/* ** which camera intrinsics to refine. uses on the REFINE_* flags */
|
||||
short refine_camera_intrinsics, pad2;
|
||||
short refine_camera_intrinsics, pad23;
|
||||
|
||||
/* ** tool settings ** */
|
||||
|
||||
@@ -142,6 +145,8 @@ typedef struct MovieTrackingSettings {
|
||||
|
||||
/* set object scale */
|
||||
float object_distance; /* distance between two bundles used for object scaling */
|
||||
|
||||
int pad3;
|
||||
} MovieTrackingSettings;
|
||||
|
||||
typedef struct MovieTrackingStabilization {
|
||||
|
||||
@@ -78,24 +78,24 @@ EnumPropertyItem constraint_type_items[] ={
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem target_space_pchan_items[] = {
|
||||
{0, "WORLD", 0, "World Space", "The transformation of the target is evaluated relative to the world coordinate system"},
|
||||
{2, "POSE", 0, "Pose Space", "The transformation of the target is only evaluated in the Pose Space, the target armature object transformation is ignored"},
|
||||
{3, "LOCAL_WITH_PARENT", 0, "Local With Parent", "The transformation of the target bone is evaluated relative its local coordinate system, with the parent transformation added"},
|
||||
{1, "LOCAL", 0, "Local Space", "The transformation of the target is evaluated relative to its local coordinate system"},
|
||||
{CONSTRAINT_SPACE_WORLD, "WORLD", 0, "World Space", "The transformation of the target is evaluated relative to the world coordinate system"},
|
||||
{CONSTRAINT_SPACE_POSE, "POSE", 0, "Pose Space", "The transformation of the target is only evaluated in the Pose Space, the target armature object transformation is ignored"},
|
||||
{CONSTRAINT_SPACE_PARLOCAL, "LOCAL_WITH_PARENT", 0, "Local With Parent", "The transformation of the target bone is evaluated relative its local coordinate system, with the parent transformation added"},
|
||||
{CONSTRAINT_SPACE_LOCAL, "LOCAL", 0, "Local Space", "The transformation of the target is evaluated relative to its local coordinate system"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem owner_space_pchan_items[] = {
|
||||
{0, "WORLD", 0, "World Space", "The constraint is applied relative to the world coordinate system"},
|
||||
{2, "POSE", 0, "Pose Space", "The constraint is applied in Pose Space, the object transformation is ignored"},
|
||||
{3, "LOCAL_WITH_PARENT", 0, "Local With Parent", "The constraint is applied relative to the local coordinate system of the object, with the parent transformation added"},
|
||||
{1, "LOCAL", 0, "Local Space", "The constraint is applied relative to the local coordinate sytem of the object"},
|
||||
{CONSTRAINT_SPACE_WORLD, "WORLD", 0, "World Space", "The constraint is applied relative to the world coordinate system"},
|
||||
{CONSTRAINT_SPACE_POSE, "POSE", 0, "Pose Space", "The constraint is applied in Pose Space, the object transformation is ignored"},
|
||||
{CONSTRAINT_SPACE_PARLOCAL, "LOCAL_WITH_PARENT", 0, "Local With Parent", "The constraint is applied relative to the local coordinate system of the object, with the parent transformation added"},
|
||||
{CONSTRAINT_SPACE_LOCAL, "LOCAL", 0, "Local Space", "The constraint is applied relative to the local coordinate sytem of the object"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
static EnumPropertyItem space_object_items[] = {
|
||||
{0, "WORLD", 0, "World Space", "The transformation of the target is evaluated relative to the world coordinate system"},
|
||||
{1, "LOCAL", 0, "Local Space", "The transformation of the target is evaluated relative to its local coordinate system"},
|
||||
{CONSTRAINT_SPACE_WORLD, "WORLD", 0, "World Space", "The transformation of the target is evaluated relative to the world coordinate system"},
|
||||
{CONSTRAINT_SPACE_LOCAL, "LOCAL", 0, "Local Space", "The transformation of the target is evaluated relative to its local coordinate system"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
@@ -293,8 +293,8 @@ static void rna_ActionConstraint_minmax_range(PointerRNA *ptr, float *min, float
|
||||
|
||||
/* 0, 1, 2 = magic numbers for rotX, rotY, rotZ */
|
||||
if (ELEM3(acon->type, 0, 1, 2)) {
|
||||
*min= -90.f;
|
||||
*max= 90.f;
|
||||
*min= -180.0f;
|
||||
*max= 180.0f;
|
||||
} else {
|
||||
*min= -1000.f;
|
||||
*max= 1000.f;
|
||||
@@ -1026,15 +1026,15 @@ static void rna_def_constraint_action(BlenderRNA *brna)
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem transform_channel_items[] = {
|
||||
{20, "LOCATION_X", 0, "Location X", ""},
|
||||
{21, "LOCATION_Y", 0, "Location Y", ""},
|
||||
{22, "LOCATION_Z", 0, "Location Z", ""},
|
||||
{00, "ROTATION_X", 0, "Rotation X", ""},
|
||||
{01, "ROTATION_Y", 0, "Rotation Y", ""},
|
||||
{02, "ROTATION_Z", 0, "Rotation Z", ""},
|
||||
{10, "SCALE_X", 0, "Scale X", ""},
|
||||
{11, "SCALE_Y", 0, "Scale Y", ""},
|
||||
{12, "SCALE_Z", 0, "Scale Z", ""},
|
||||
{20, "LOCATION_X", 0, "X Location", ""},
|
||||
{21, "LOCATION_Y", 0, "Y Location", ""},
|
||||
{22, "LOCATION_Z", 0, "Z Location", ""},
|
||||
{00, "ROTATION_X", 0, "X Rotation", ""},
|
||||
{01, "ROTATION_Y", 0, "Y Rotation", ""},
|
||||
{02, "ROTATION_Z", 0, "Z Rotation", ""},
|
||||
{10, "SCALE_X", 0, "X Scale", ""},
|
||||
{11, "SCALE_Y", 0, "Y Scale", ""},
|
||||
{12, "SCALE_Z", 0, "Z Scale", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
srna= RNA_def_struct(brna, "ActionConstraint", "Constraint");
|
||||
@@ -2011,12 +2011,12 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
|
||||
RNA_def_property_int_sdna(prop, NULL, "chainlen");
|
||||
RNA_def_property_range(prop, 1, 255); // TODO: this should really check the max length of the chain the constraint is attached to
|
||||
RNA_def_property_ui_text(prop, "Chain Length", "How many bones are included in the chain");
|
||||
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
|
||||
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); // XXX: this update goes wrong... needs extra flush?
|
||||
|
||||
/* direct access to bindings */
|
||||
// NOTE: only to be used by experienced users
|
||||
prop= RNA_def_property(srna, "joint_bindings", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_array(prop, 32); // XXX this is the maximum value allowed
|
||||
RNA_def_property_array(prop, 32); // XXX this is the maximum value allowed - why?
|
||||
RNA_def_property_flag(prop, PROP_DYNAMIC);
|
||||
RNA_def_property_dynamic_array_funcs(prop, "rna_SplineIKConstraint_joint_bindings_get_length");
|
||||
RNA_def_property_float_funcs(prop, "rna_SplineIKConstraint_joint_bindings_get", "rna_SplineIKConstraint_joint_bindings_set", NULL);
|
||||
|
||||
@@ -335,6 +335,11 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
|
||||
RNA_def_property_range(prop, 0, 100);
|
||||
RNA_def_property_ui_text(prop, "End Time", "Simulation time of the last blender frame (in seconds)");
|
||||
|
||||
prop= RNA_def_property(srna, "frame_offset", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "frameOffset");
|
||||
RNA_def_property_ui_text(prop, "Cache Offset", "Offset when reading baked cache");
|
||||
RNA_def_property_update(prop, NC_OBJECT, "rna_fluid_update");
|
||||
|
||||
prop= RNA_def_property(srna, "simulation_scale", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "realsize");
|
||||
RNA_def_property_range(prop, 0.001, 10);
|
||||
|
||||
@@ -559,7 +559,7 @@ static void rna_def_keyblock(BlenderRNA *brna)
|
||||
prop= RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYBLOCK_MUTE);
|
||||
RNA_def_property_ui_text(prop, "Mute", "Mute this shape key");
|
||||
RNA_def_property_ui_icon(prop, ICON_MUTE_IPO_OFF, 1);
|
||||
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1);
|
||||
RNA_def_property_update(prop, 0, "rna_Key_update_data");
|
||||
|
||||
prop= RNA_def_property(srna, "slider_min", PROP_FLOAT, PROP_NONE);
|
||||
|
||||
@@ -93,10 +93,14 @@ static void rna_Material_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *p
|
||||
Material *ma= ptr->id.data;
|
||||
|
||||
DAG_id_tag_update(&ma->id, 0);
|
||||
if(scene->gm.matmode == GAME_MAT_GLSL)
|
||||
WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ma);
|
||||
else
|
||||
WM_main_add_notifier(NC_MATERIAL|ND_SHADING, ma);
|
||||
if (scene) { /* can be NULL, see [#30025] */
|
||||
if (scene->gm.matmode == GAME_MAT_GLSL) {
|
||||
WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, ma);
|
||||
}
|
||||
else {
|
||||
WM_main_add_notifier(NC_MATERIAL|ND_SHADING, ma);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_Material_draw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "rna_internal.h"
|
||||
@@ -1132,22 +1133,25 @@ static int rna_Mesh_tot_face_get(PointerRNA *ptr)
|
||||
return me->edit_mesh ? me->edit_mesh->totfacesel : 0;
|
||||
}
|
||||
|
||||
static CustomDataLayer *rna_Mesh_vertex_color_new(struct Mesh *me, struct bContext *C, const char *name)
|
||||
static PointerRNA rna_Mesh_vertex_color_new(struct Mesh *me, struct bContext *C, const char *name)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
CustomData *fdata;
|
||||
CustomDataLayer *cdl= NULL;
|
||||
int index;
|
||||
int index= ED_mesh_color_add(C, NULL, NULL, me, name, FALSE);
|
||||
|
||||
if(ED_mesh_color_add(C, NULL, NULL, me, name, FALSE)) {
|
||||
if(index != -1) {
|
||||
fdata= rna_mesh_fdata(me);
|
||||
index= CustomData_get_named_layer_index(fdata, CD_MCOL, name);
|
||||
cdl= (index == -1)? NULL: &fdata->layers[index];
|
||||
cdl= &fdata->layers[CustomData_get_layer_index_n(fdata, CD_MCOL, index)];
|
||||
}
|
||||
return cdl;
|
||||
|
||||
RNA_pointer_create(&me->id, &RNA_MeshColorLayer, cdl, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static CustomDataLayer *rna_Mesh_int_property_new(struct Mesh *me, struct bContext *C, const char *name)
|
||||
static PointerRNA rna_Mesh_int_property_new(struct Mesh *me, struct bContext *C, const char *name)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
CustomDataLayer *cdl = NULL;
|
||||
int index;
|
||||
|
||||
@@ -1156,11 +1160,13 @@ static CustomDataLayer *rna_Mesh_int_property_new(struct Mesh *me, struct bConte
|
||||
|
||||
cdl = (index == -1) ? NULL : &(me->fdata.layers[index]);
|
||||
|
||||
return cdl;
|
||||
RNA_pointer_create(&me->id, &RNA_MeshIntPropertyLayer, cdl, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static CustomDataLayer *rna_Mesh_float_property_new(struct Mesh *me, struct bContext *C, const char *name)
|
||||
static PointerRNA rna_Mesh_float_property_new(struct Mesh *me, struct bContext *C, const char *name)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
CustomDataLayer *cdl = NULL;
|
||||
int index;
|
||||
|
||||
@@ -1169,11 +1175,13 @@ static CustomDataLayer *rna_Mesh_float_property_new(struct Mesh *me, struct bCon
|
||||
|
||||
cdl = (index == -1) ? NULL : &(me->fdata.layers[index]);
|
||||
|
||||
return cdl;
|
||||
RNA_pointer_create(&me->id, &RNA_MeshFloatPropertyLayer, cdl, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static CustomDataLayer *rna_Mesh_string_property_new(struct Mesh *me, struct bContext *C, const char *name)
|
||||
static PointerRNA rna_Mesh_string_property_new(struct Mesh *me, struct bContext *C, const char *name)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
CustomDataLayer *cdl = NULL;
|
||||
int index;
|
||||
|
||||
@@ -1182,21 +1190,24 @@ static CustomDataLayer *rna_Mesh_string_property_new(struct Mesh *me, struct bCo
|
||||
|
||||
cdl = (index == -1) ? NULL : &(me->fdata.layers[index]);
|
||||
|
||||
return cdl;
|
||||
RNA_pointer_create(&me->id, &RNA_MeshStringPropertyLayer, cdl, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static CustomDataLayer *rna_Mesh_uv_texture_new(struct Mesh *me, struct bContext *C, const char *name)
|
||||
static PointerRNA rna_Mesh_uv_texture_new(struct Mesh *me, struct bContext *C, const char *name)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
CustomData *fdata;
|
||||
CustomDataLayer *cdl= NULL;
|
||||
int index;
|
||||
int index= ED_mesh_uv_texture_add(C, me, name, FALSE);
|
||||
|
||||
if(ED_mesh_uv_texture_add(C, me, name, FALSE)) {
|
||||
if(index != -1) {
|
||||
fdata= rna_mesh_fdata(me);
|
||||
index= CustomData_get_named_layer_index(fdata, CD_MTFACE, name);
|
||||
cdl= (index == -1)? NULL: &fdata->layers[index];
|
||||
cdl= &fdata->layers[CustomData_get_layer_index_n(fdata, CD_MTFACE, index)];
|
||||
}
|
||||
return cdl;
|
||||
|
||||
RNA_pointer_create(&me->id, &RNA_MeshTextureFaceLayer, cdl, &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -1783,6 +1794,7 @@ static void rna_def_vertex_colors(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
RNA_def_function_ui_description(func, "Add a vertex color layer to Mesh");
|
||||
RNA_def_string(func, "name", "Col", 0, "", "Vertex color name");
|
||||
parm= RNA_def_pointer(func, "layer", "MeshColorLayer", "", "The newly created layer");
|
||||
RNA_def_property_flag(parm, PROP_RNAPTR);
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
/*
|
||||
@@ -1823,6 +1835,7 @@ static void rna_def_int_layers(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
RNA_def_function_ui_description(func, "Add a integer property layer to Mesh");
|
||||
RNA_def_string(func, "name", "Int Prop", 0, "", "Int property name");
|
||||
parm= RNA_def_pointer(func, "layer", "MeshIntPropertyLayer", "", "The newly created layer");
|
||||
RNA_def_property_flag(parm, PROP_RNAPTR);
|
||||
RNA_def_function_return(func, parm);
|
||||
}
|
||||
|
||||
@@ -1844,6 +1857,7 @@ static void rna_def_float_layers(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
RNA_def_function_ui_description(func, "Add a float property layer to Mesh");
|
||||
RNA_def_string(func, "name", "Float Prop", 0, "", "Float property name");
|
||||
parm= RNA_def_pointer(func, "layer", "MeshFloatPropertyLayer", "", "The newly created layer");
|
||||
RNA_def_property_flag(parm, PROP_RNAPTR);
|
||||
RNA_def_function_return(func, parm);
|
||||
}
|
||||
|
||||
@@ -1865,6 +1879,7 @@ static void rna_def_string_layers(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
RNA_def_function_ui_description(func, "Add a string property layer to Mesh");
|
||||
RNA_def_string(func, "name", "String Prop", 0, "", "String property name");
|
||||
parm= RNA_def_pointer(func, "layer", "MeshStringPropertyLayer", "", "The newly created layer");
|
||||
RNA_def_property_flag(parm, PROP_RNAPTR);
|
||||
RNA_def_function_return(func, parm);
|
||||
}
|
||||
|
||||
@@ -1887,6 +1902,7 @@ static void rna_def_uv_textures(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
RNA_def_function_ui_description(func, "Add a UV texture layer to Mesh");
|
||||
RNA_def_string(func, "name", "UVMap", 0, "", "UV map name");
|
||||
parm= RNA_def_pointer(func, "layer", "MeshTextureFaceLayer", "", "The newly created layer");
|
||||
RNA_def_property_flag(parm, PROP_RNAPTR);
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
/*
|
||||
|
||||
@@ -87,24 +87,36 @@ static void rna_def_movieclip_proxy(BlenderRNA *brna)
|
||||
|
||||
/* build proxy sized */
|
||||
prop= RNA_def_property(srna, "build_25", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_25);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_25);
|
||||
RNA_def_property_ui_text(prop, "25%", "Build proxy resolution 25% of the original footage dimension");
|
||||
|
||||
prop= RNA_def_property(srna, "build_50", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_50);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_50);
|
||||
RNA_def_property_ui_text(prop, "50%", "Build proxy resolution 50% of the original footage dimension");
|
||||
|
||||
prop= RNA_def_property(srna, "build_75", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_75);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_75);
|
||||
RNA_def_property_ui_text(prop, "75%", "Build proxy resolution 75% of the original footage dimension");
|
||||
|
||||
prop= RNA_def_property(srna, "build_100", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_100);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_SIZE_100);
|
||||
RNA_def_property_ui_text(prop, "100%", "Build proxy resolution 100% of the original footage dimension");
|
||||
|
||||
prop= RNA_def_property(srna, "build_undistorted", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_flag", MCLIP_PROXY_BUILD_UNDISTORT);
|
||||
RNA_def_property_ui_text(prop, "Build Undistorted", "Also build undistorted proxies for selected sizes");
|
||||
prop= RNA_def_property(srna, "build_undistorted_25", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_25);
|
||||
RNA_def_property_ui_text(prop, "25%", "Build proxy resolution 25% of the original undistorted footage dimension");
|
||||
|
||||
prop= RNA_def_property(srna, "build_undistorted_50", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_50);
|
||||
RNA_def_property_ui_text(prop, "50%", "Build proxy resolution 50% of the original undistorted footage dimension");
|
||||
|
||||
prop= RNA_def_property(srna, "build_undistorted_75", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_75);
|
||||
RNA_def_property_ui_text(prop, "75%", "Build proxy resolution 75% of the original undistorted footage dimension");
|
||||
|
||||
prop= RNA_def_property(srna, "build_undistorted_100", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", MCLIP_PROXY_UNDISTORTED_SIZE_100);
|
||||
RNA_def_property_ui_text(prop, "100%", "Build proxy resolution 100% of the original undistorted footage dimension");
|
||||
|
||||
/* build timecodes */
|
||||
prop= RNA_def_property(srna, "build_record_run", PROP_BOOLEAN, PROP_NONE);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user