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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/cycles/blender/addon/properties.py4
-rw-r--r--intern/cycles/blender/blender_camera.cpp6
-rw-r--r--intern/cycles/blender/blender_mesh.cpp10
-rw-r--r--intern/cycles/render/camera.cpp40
-rw-r--r--intern/cycles/render/camera.h8
-rw-r--r--intern/cycles/subd/subd_dice.cpp5
-rw-r--r--intern/cycles/subd/subd_dice.h1
-rw-r--r--intern/cycles/subd/subd_split.cpp54
-rw-r--r--intern/cycles/subd/subd_split.h2
9 files changed, 117 insertions, 13 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 01aa619b306..3b5755e8062 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -938,8 +938,8 @@ class CyclesMeshSettings(bpy.types.PropertyGroup):
)
cls.dicing_rate = FloatProperty(
name="Dicing Rate",
- description="",
- min=0.001, max=1000.0,
+ description="Size of a micropolygon in pixels",
+ min=0.1, max=1000.0,
default=1.0,
)
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 5bc9dfc7904..6b459ae575f 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -360,6 +360,12 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
blender_camera_viewplane(bcam, width, height,
&cam->viewplane, &aspectratio, &sensor_size);
+ cam->width = bcam->full_width;
+ cam->height = bcam->full_height;
+
+ cam->full_width = width;
+ cam->full_height = height;
+
/* panorama sensor */
if(bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) {
float fit_xratio = (float)bcam->full_width*bcam->pixelaspect.x;
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 9eb4626eb3c..48c14a34aad 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -18,6 +18,7 @@
#include "mesh.h"
#include "object.h"
#include "scene.h"
+#include "camera.h"
#include "blender_sync.h"
#include "blender_session.h"
@@ -655,6 +656,7 @@ static void create_mesh(Scene *scene,
static void create_subd_mesh(Scene *scene,
Mesh *mesh,
+ BL::Object b_ob,
BL::Mesh& b_mesh,
PointerRNA *cmesh,
const vector<uint>& used_shaders)
@@ -691,8 +693,10 @@ static void create_subd_mesh(Scene *scene,
SubdParams sdparams(mesh, used_shaders[0], true, need_ptex);
sdparams.dicing_rate = RNA_float_get(cmesh, "dicing_rate");
- //scene->camera->update();
- //sdparams.camera = scene->camera;
+
+ scene->camera->update();
+ sdparams.camera = scene->camera;
+ sdparams.objecttoworld = get_transform(b_ob.matrix_world());
/* tesselate */
DiagSplit dsplit(sdparams);
@@ -805,7 +809,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
if(b_mesh) {
if(render_layer.use_surfaces && !hide_tris) {
if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
- create_subd_mesh(scene, mesh, b_mesh, &cmesh, used_shaders);
+ create_subd_mesh(scene, mesh, b_ob, b_mesh, &cmesh, used_shaders);
else
create_mesh(scene, mesh, b_mesh, used_shaders);
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 0e343822223..028916c1b8f 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -158,12 +158,15 @@ void Camera::update()
/* ndc to raster */
Transform ndctoraster = transform_scale(width, height, 1.0f) * bordertofull;
+ Transform full_ndctoraster = transform_scale(full_width, full_height, 1.0f) * bordertofull;
/* raster to screen */
Transform screentondc = fulltoborder * transform_from_viewplane(viewplane);
Transform screentoraster = ndctoraster * screentondc;
Transform rastertoscreen = transform_inverse(screentoraster);
+ Transform full_screentoraster = full_ndctoraster * screentondc;
+ Transform full_rastertoscreen = transform_inverse(full_screentoraster);
/* screen to camera */
Transform cameratoscreen;
@@ -177,6 +180,7 @@ void Camera::update()
Transform screentocamera = transform_inverse(cameratoscreen);
rastertocamera = screentocamera * rastertoscreen;
+ Transform full_rastertocamera = screentocamera * full_rastertoscreen;
cameratoraster = screentoraster * cameratoscreen;
cameratoworld = matrix;
@@ -196,12 +200,18 @@ void Camera::update()
if(type == CAMERA_ORTHOGRAPHIC) {
dx = transform_direction(&rastertocamera, make_float3(1, 0, 0));
dy = transform_direction(&rastertocamera, make_float3(0, 1, 0));
+ full_dx = transform_direction(&full_rastertocamera, make_float3(1, 0, 0));
+ full_dy = transform_direction(&full_rastertocamera, make_float3(0, 1, 0));
}
else if(type == CAMERA_PERSPECTIVE) {
dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) -
transform_perspective(&rastertocamera, make_float3(0, 0, 0));
dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) -
transform_perspective(&rastertocamera, make_float3(0, 0, 0));
+ full_dx = transform_perspective(&full_rastertocamera, make_float3(1, 0, 0)) -
+ transform_perspective(&full_rastertocamera, make_float3(0, 0, 0));
+ full_dy = transform_perspective(&full_rastertocamera, make_float3(0, 1, 0)) -
+ transform_perspective(&full_rastertocamera, make_float3(0, 0, 0));
}
else {
dx = make_float3(0.0f, 0.0f, 0.0f);
@@ -210,6 +220,8 @@ void Camera::update()
dx = transform_direction(&cameratoworld, dx);
dy = transform_direction(&cameratoworld, dy);
+ full_dx = transform_direction(&cameratoworld, full_dx);
+ full_dy = transform_direction(&cameratoworld, full_dy);
/* TODO(sergey): Support other types of camera. */
if(type == CAMERA_PERSPECTIVE) {
@@ -539,4 +551,32 @@ BoundBox Camera::viewplane_bounds_get()
return bounds;
}
+float Camera::world_to_raster_size(float3 P)
+{
+ if(type == CAMERA_ORTHOGRAPHIC) {
+ return min(len(full_dx), len(full_dy));
+ }
+ else if(type == CAMERA_PERSPECTIVE) {
+ /* Calculate as if point is directly ahead of the camera. */
+ float3 raster = make_float3(0.5f*width, 0.5f*height, 0.0f);
+ float3 Pcamera = transform_perspective(&rastertocamera, raster);
+
+ /* dDdx */
+ float3 Ddiff = transform_direction(&cameratoworld, Pcamera);
+ float3 dx = len_squared(full_dx) < len_squared(full_dy) ? full_dx : full_dy;
+ float3 dDdx = normalize(Ddiff + dx) - normalize(Ddiff);
+
+ /* dPdx */
+ float dist = len(transform_point(&worldtocamera, P));
+ float3 D = normalize(Ddiff);
+ return len(dist*dDdx - dot(dist*dDdx, D)*D);
+ }
+ else {
+ // TODO(mai): implement for CAMERA_PANORAMA
+ assert(!"pixel width calculation for panoramic projection not implemented yet");
+ }
+
+ return 1.0f;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 6fbb1dc3bc8..684b4458dfc 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -120,6 +120,8 @@ public:
int width, height;
int resolution;
BoundBox2D viewplane;
+ /* width and height change during preview, so we need these for calculating dice rates. */
+ int full_width, full_height;
/* border */
BoundBox2D border;
@@ -151,6 +153,9 @@ public:
float3 dx;
float3 dy;
+ float3 full_dx;
+ float3 full_dy;
+
/* update */
bool need_update;
bool need_device_update;
@@ -176,6 +181,9 @@ public:
/* Public utility functions. */
BoundBox viewplane_bounds_get();
+ /* Calculates the width of a pixel at point in world space. */
+ float world_to_raster_size(float3 P);
+
private:
/* Private utility functions. */
float3 transform_raster_to_world(float raster_x, float raster_y);
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index 44bab066dde..301f30c8d95 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -305,7 +305,12 @@ void QuadDice::dice(SubPatch& sub, EdgeFactors& ef)
int Mu = max(ef.tu0, ef.tu1);
int Mv = max(ef.tv0, ef.tv1);
+#if 0 /* Doesnt work very well, especially at grazing angles. */
float S = scale_factor(sub, ef, Mu, Mv);
+#else
+ float S = 1.0f;
+#endif
+
Mu = max((int)ceil(S*Mu), 2); // XXX handle 0 & 1?
Mv = max((int)ceil(S*Mv), 2); // XXX handle 0 & 1?
diff --git a/intern/cycles/subd/subd_dice.h b/intern/cycles/subd/subd_dice.h
index b7e61748779..2b11e4b0bf5 100644
--- a/intern/cycles/subd/subd_dice.h
+++ b/intern/cycles/subd/subd_dice.h
@@ -41,6 +41,7 @@ struct SubdParams {
int split_threshold;
float dicing_rate;
Camera *camera;
+ Transform objecttoworld;
SubdParams(Mesh *mesh_, int shader_, bool smooth_ = true, bool ptex_ = false)
{
diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp
index df4d451e8eb..095eefeab22 100644
--- a/intern/cycles/subd/subd_split.cpp
+++ b/intern/cycles/subd/subd_split.cpp
@@ -46,13 +46,13 @@ void DiagSplit::dispatch(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors&
edgefactors_triangle.push_back(ef);
}
-float3 DiagSplit::project(Patch *patch, float2 uv)
+float3 DiagSplit::to_world(Patch *patch, float2 uv)
{
float3 P;
patch->eval(&P, NULL, NULL, uv.x, uv.y);
if(params.camera)
- P = transform_perspective(&params.camera->worldtoraster, P);
+ P = transform_point(&params.objecttoworld, P);
return P;
}
@@ -66,10 +66,21 @@ int DiagSplit::T(Patch *patch, float2 Pstart, float2 Pend)
for(int i = 0; i < params.test_steps; i++) {
float t = i/(float)(params.test_steps-1);
- float3 P = project(patch, Pstart + t*(Pend - Pstart));
+ float3 P = to_world(patch, Pstart + t*(Pend - Pstart));
if(i > 0) {
- float L = len(P - Plast);
+ float L;
+
+ if(!params.camera) {
+ L = len(P - Plast);
+ }
+ else {
+ Camera* cam = params.camera;
+
+ float pixel_width = cam->world_to_raster_size((P + Plast) * 0.5f);
+ L = len(P - Plast) / pixel_width;
+ }
+
Lsum += L;
Lmax = max(L, Lmax);
}
@@ -103,6 +114,16 @@ void DiagSplit::partition_edge(Patch *patch, float2 *P, int *t0, int *t1, float2
void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef, int depth)
{
+ if(depth > 32) {
+ /* We should never get here, but just in case end recursion safely. */
+ ef.tu = 1;
+ ef.tv = 1;
+ ef.tw = 1;
+
+ dispatch(sub, ef);
+ return;
+ }
+
assert(ef.tu == T(sub.patch, sub.Pv, sub.Pw));
assert(ef.tv == T(sub.patch, sub.Pw, sub.Pu));
assert(ef.tw == T(sub.patch, sub.Pu, sub.Pv));
@@ -187,7 +208,25 @@ void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef
void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int depth)
{
- if((ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM)) {
+ if(depth > 32) {
+ /* We should never get here, but just in case end recursion safely. */
+ ef.tu0 = 1;
+ ef.tu1 = 1;
+ ef.tv0 = 1;
+ ef.tv1 = 1;
+
+ dispatch(sub, ef);
+ return;
+ }
+
+ bool split_u = (ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM);
+ bool split_v = (ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM);
+
+ if(split_u && split_v) {
+ split_u = depth % 2;
+ }
+
+ if(split_u) {
/* partition edges */
QuadDice::EdgeFactors ef0, ef1;
float2 Pu0, Pu1;
@@ -212,7 +251,7 @@ void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int de
split(sub0, ef0, depth+1);
split(sub1, ef1, depth+1);
}
- else if(ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM) {
+ else if(split_v) {
/* partition edges */
QuadDice::EdgeFactors ef0, ef1;
float2 Pv0, Pv1;
@@ -237,8 +276,9 @@ void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int de
split(sub0, ef0, depth+1);
split(sub1, ef1, depth+1);
}
- else
+ else {
dispatch(sub, ef);
+ }
}
void DiagSplit::split_triangle(Patch *patch)
diff --git a/intern/cycles/subd/subd_split.h b/intern/cycles/subd/subd_split.h
index df4935ee624..f04c51dedfe 100644
--- a/intern/cycles/subd/subd_split.h
+++ b/intern/cycles/subd/subd_split.h
@@ -45,7 +45,7 @@ public:
DiagSplit(const SubdParams& params);
- float3 project(Patch *patch, float2 uv);
+ float3 to_world(Patch *patch, float2 uv);
int T(Patch *patch, float2 Pstart, float2 Pend);
void partition_edge(Patch *patch, float2 *P, int *t0, int *t1,
float2 Pstart, float2 Pend, int t);