solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit 970d9ab36f4e8c40d480d9f8625de379f7fba12a
parent cfeb38895a8d20f44378ebd7ffd70219c02ec1bd
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 24 Jun 2016 18:35:05 +0200

First try to quadrics.

What is done compiles. Far from being complete, though.
No test yet.

Diffstat:
Mcmake/CMakeLists.txt | 2++
Msrc/ssol.h | 70++++++++++++++++++++++++++++++++++++++++++----------------------------
Asrc/ssol_quadric.c | 427+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ssol_quadric_c.h | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 540 insertions(+), 28 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -48,6 +48,7 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(SSOL_FILES_SRC ssol_device.c + ssol_quadric.c ssol_shape.c) set(SSOL_FILES_INC_API @@ -55,6 +56,7 @@ set(SSOL_FILES_INC_API set(SSOL_FILES_INC ssol_device_c.h + ssol_quadric_c.h ssol_shape_c.h) set(SSOL_FILES_DOC COPYING README.md) diff --git a/src/ssol.h b/src/ssol.h @@ -51,6 +51,7 @@ struct ssol_material; struct ssol_object; struct ssol_object_instance; struct ssol_scene; +struct ssol_quadric; struct ssol_shape; struct ssol_spectrum; struct ssol_sun; @@ -65,12 +66,6 @@ enum ssol_parametrization_type { SSOL_PARAMETRIZATION_PRIMITIVE_ID /* Map from 3D to 1D with primitive id */ }; -enum ssol_quadric_type { - SSOL_QUADRIC_PLANE, - SSOL_QUADRIC_PARABOL, - SSOL_QUADRIC_PARABOLIC_CYLINDER -}; - enum ssol_carving_type { SSOL_CARVING_CIRCLE, SSOL_CARVING_POLYGON @@ -108,27 +103,6 @@ struct ssol_image_layout { static const struct ssol_vertex_data SSOL_VERTEX_DATA_NULL = SSOL_VERTEX_DATA_NULL__; -/* The following quadric definitions are in local coordinate system. */ -struct ssol_quadric_plane { - char unused; /* Define z = 0 */ -}; -struct ssol_quadric_parabol { - double focal; /* Define x^2 + y^2 - 4 focal z = 0 */ -}; - -struct ssol_quadric_parabolic_cylinder { - double focal; /* Define y^2 - 4 focal z = 0 */ -}; - -struct ssol_quadric { - enum ssol_quadric_type type; - union { - struct ssol_quadric_plane plane; - struct ssol_quadric_parabol parabol; - struct ssol_quadric_parabolic_cylinder parabolic_cylinder; - } data; -}; - struct ssol_carving_circle { double radius; }; @@ -151,7 +125,7 @@ struct ssol_carving { }; struct ssol_punched_surface { - struct ssol_quadric quadric; + struct ssol_quadric* quadric; struct ssol_carving* carvings; size_t nb_carvings; }; @@ -309,6 +283,46 @@ ssol_mesh_setup void* data); /******************************************************************************* +* Quadric API - Define an equation that can be used to define a punched surface +******************************************************************************/ + +/* Define z = 0 in local space; no further setting available */ +SSOL_API res_T +ssol_quadric_plane + (struct ssol_device* dev, + struct ssol_quadric** plane); + +SSOL_API res_T +ssol_quadric_parabol + (struct ssol_device* dev, + struct ssol_quadric** parabol); + +SSOL_API res_T +ssol_quadric_parabolic_cylinder + (struct ssol_device* dev, + struct ssol_quadric** parabolic_cylinder); + +/* Define x^2 + y^2 - 4 focal z = 0 in local space */ +SSOL_API res_T +ssol_quadric_parabol_set_focal + (struct ssol_quadric* parabol, + double focal); + +/* Define y^2 - 4 focal z = 0 in local space */ +SSOL_API res_T +ssol_quadric_parabolic_cylinder_set_focal + (struct ssol_quadric* parabolic_cylinder, + double focal); + +SSOL_API res_T +ssol_quadric_ref_get + (struct ssol_quadric* quadric); + +SSOL_API res_T +ssol_quadric_ref_put + (struct ssol_quadric* quadric); + +/******************************************************************************* * Material API - Define the surfacic (e.g.: BRDF) as well as the volumic * (e.g.: refractive index) properties of a geometry. ******************************************************************************/ diff --git a/src/ssol_quadric.c b/src/ssol_quadric.c @@ -0,0 +1,427 @@ +/* Copyright (C) CNRS 2016 +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "ssol.h" +#include "ssol_quadric_c.h" +#include "ssol_device_c.h" + +#include <rsys\rsys.h> +#include <rsys\mem_allocator.h> +#include <rsys\ref_count.h> + +/******************************************************************************* +* Helper functions +******************************************************************************/ + +static void +plane_release(ref_T* ref) +{ + struct quadric_plane* plane; + ASSERT(ref); + + plane = CONTAINER_OF(ref, struct quadric_plane, ref); + + ASSERT(plane->dev && plane->dev->allocator); + MEM_RM(plane->dev->allocator, plane); + SSOL(device_ref_put(plane->dev)); +} + +static void +plane_ref_get(struct quadric_plane* plane) +{ + ASSERT(plane); + ref_get(&plane->ref); +} + +static void +plane_ref_put(struct quadric_plane* plane) +{ + ASSERT(plane); + ref_put(&plane->ref, plane_release); +} + +static void +parabol_release(ref_T* ref) +{ + struct quadric_parabol* parabol; + ASSERT(ref); + + parabol = CONTAINER_OF(ref, struct quadric_parabol, ref); + + ASSERT(parabol->dev && parabol->dev->allocator); + MEM_RM(parabol->dev->allocator, parabol); + SSOL(device_ref_put(parabol->dev)); +} + +static void +parabol_ref_get(struct quadric_parabol* parabol) +{ + ASSERT(parabol); + ref_get(&parabol->ref); +} + +static void +parabol_ref_put(struct quadric_parabol* parabol) +{ + ASSERT(parabol); + ref_put(&parabol->ref, parabol_release); +} + +static void +parabolic_cylinder_release(ref_T* ref) +{ + struct quadric_parabolic_cylinder* parabolic_cylinder; + ASSERT(ref); + + parabolic_cylinder = CONTAINER_OF(ref, struct quadric_parabolic_cylinder, ref); + + ASSERT(parabolic_cylinder->dev && parabolic_cylinder->dev->allocator); + MEM_RM(parabolic_cylinder->dev->allocator, parabolic_cylinder); + SSOL(device_ref_put(parabolic_cylinder->dev)); +} + +static void +parabolic_cylinder_ref_get(struct quadric_parabolic_cylinder* parabolic_cylinder) +{ + ASSERT(parabolic_cylinder); + ref_get(&parabolic_cylinder->ref); +} + +static void +parabolic_cylinder_ref_put(struct quadric_parabolic_cylinder* parabolic_cylinder) +{ + ASSERT(parabolic_cylinder); + ref_put(&parabolic_cylinder->ref, parabolic_cylinder_release); +} + +static void +quadric_release(ref_T* ref) +{ + struct ssol_quadric* quadric; + ASSERT(ref); + quadric = CONTAINER_OF(ref, struct ssol_quadric, ref); + + switch (quadric->type) { + case QUADRIC_NONE: + break; + case QUADRIC_PLANE: + if (quadric->data.plane) plane_ref_put(quadric->data.plane); + break; + case QUADRIC_PARABOL: + if (quadric->data.parabol) parabol_ref_put(quadric->data.parabol); + break; + case QUADRIC_PARABOLIC_CYLINDER: + if (quadric->data.parabolic_cylinder) parabolic_cylinder_ref_put(quadric->data.parabolic_cylinder); + break; + default: FATAL("Unreachable code \n"); break; + } + + ASSERT(quadric->dev && quadric->dev->allocator); + MEM_RM(quadric->dev->allocator, quadric); + SSOL(device_ref_put(quadric->dev)); +} + +/******************************************************************************* +* Local functions +******************************************************************************/ + +static res_T +quadric_create(struct ssol_device* dev, struct ssol_quadric** out_quadric) +{ + struct ssol_quadric* quadric = NULL; + res_T res = RES_OK; + + ASSERT(dev && out_quadric); + + quadric = (struct ssol_quadric*)MEM_CALLOC + (dev->allocator, 1, sizeof(struct ssol_quadric)); + if (!quadric) { + res = RES_MEM_ERR; + goto error; + } + + SSOL(device_ref_get(dev)); + quadric->dev = dev; + ref_init(&quadric->ref); + quadric->type = QUADRIC_NONE; + +exit: + if (out_quadric) *out_quadric = quadric; + return res; +error: + if (quadric) { + SSOL(quadric_ref_put(quadric)); + quadric = NULL; + } + goto exit; +} + +static res_T +quadric_plane_create(struct ssol_device* dev, struct quadric_plane** out_plane) +{ + struct quadric_plane* plane = NULL; + res_T res = RES_OK; + + ASSERT(dev && out_plane); + + plane = (struct quadric_plane*)MEM_CALLOC + (dev->allocator, 1, sizeof(struct quadric_plane)); + if (!plane) { + res = RES_MEM_ERR; + goto error; + } + + SSOL(device_ref_get(dev)); + plane->dev = dev; + ref_init(&plane->ref); + +exit: + if (out_plane) *out_plane = plane; + return res; +error: + if (plane) { + plane_ref_put(plane); + plane = NULL; + } + goto exit; + +} + +static res_T +quadric_parabol_create(struct ssol_device* dev, struct quadric_parabol** out_parabol) +{ + struct quadric_parabol* parabol = NULL; + res_T res = RES_OK; + + ASSERT(dev && out_parabol); + + parabol = (struct quadric_parabol*)MEM_CALLOC + (dev->allocator, 1, sizeof(struct quadric_parabol)); + if (!parabol) { + res = RES_MEM_ERR; + goto error; + } + + SSOL(device_ref_get(dev)); + parabol->dev = dev; + ref_init(&parabol->ref); + +exit: + if (out_parabol) *out_parabol = parabol; + return res; +error: + if (parabol) { + parabol_ref_put(parabol); + parabol = NULL; + } + goto exit; + +} + +static res_T +quadric_parabolic_cylinder_create(struct ssol_device* dev, struct quadric_parabolic_cylinder** out_parabolic_cylinder) +{ + struct quadric_parabolic_cylinder* parabolic_cylinder = NULL; + res_T res = RES_OK; + + ASSERT(dev && out_parabolic_cylinder); + + parabolic_cylinder = (struct quadric_parabolic_cylinder*)MEM_CALLOC + (dev->allocator, 1, sizeof(struct quadric_parabolic_cylinder)); + if (!parabolic_cylinder) { + res = RES_MEM_ERR; + goto error; + } + + SSOL(device_ref_get(dev)); + parabolic_cylinder->dev = dev; + ref_init(&parabolic_cylinder->ref); + +exit: + if (out_parabolic_cylinder) *out_parabolic_cylinder = parabolic_cylinder; + return res; +error: + if (parabolic_cylinder) { + parabolic_cylinder_ref_put(parabolic_cylinder); + parabolic_cylinder = NULL; + } + goto exit; + +} + +/******************************************************************************* +* Exported ssol_quadric functions +******************************************************************************/ + +res_T +ssol_quadric_plane +(struct ssol_device* dev, + struct ssol_quadric** out_plane) +{ + struct ssol_quadric* plane = NULL; + res_T res = RES_OK; + + if (!dev || !out_plane) { + res = RES_BAD_ARG; + goto error; + } + + res = quadric_create(dev, &plane); + if (res != RES_OK) + goto error; + + res = quadric_plane_create(dev, &plane->data.plane); + if (res != RES_OK) + goto error; + + plane->type = QUADRIC_PLANE; + plane->dev = dev; + ref_init(&plane->ref); + +exit: + if (out_plane) *out_plane = plane; + return res; +error: + if (plane) { + SSOL(quadric_ref_put(plane)); + plane = NULL; + } + goto exit; +} + +res_T +ssol_quadric_parabol +(struct ssol_device* dev, + struct ssol_quadric** out_parabol) +{ + struct ssol_quadric* parabol = NULL; + res_T res = RES_OK; + + if (!dev || !out_parabol) { + res = RES_BAD_ARG; + goto error; + } + + res = quadric_create(dev, &parabol); + if (res != RES_OK) + goto error; + + res = quadric_parabol_create(dev, &parabol->data.parabol); + if (res != RES_OK) + goto error; + + parabol->type = QUADRIC_PARABOL; + parabol->data.parabol->focal = 1; /* default focal length */ + parabol->dev = dev; + ref_init(&parabol->ref); + +exit: + if (out_parabol) *out_parabol = parabol; + return res; +error: + if (parabol) { + SSOL(quadric_ref_put(parabol)); + parabol = NULL; + } + goto exit; +} + +res_T +ssol_quadric_parabolic_cylinder +(struct ssol_device* dev, + struct ssol_quadric** out_parabolic_cylinder) +{ + struct ssol_quadric* parabolic_cylinder = NULL; + res_T res = RES_OK; + + if (!dev || !out_parabolic_cylinder) { + res = RES_BAD_ARG; + goto error; + } + + res = quadric_create(dev, &parabolic_cylinder); + if (res != RES_OK) + goto error; + + res = quadric_parabolic_cylinder_create + (dev, &parabolic_cylinder->data.parabolic_cylinder); + if (res != RES_OK) + goto error; + + parabolic_cylinder->type = QUADRIC_PARABOLIC_CYLINDER; + parabolic_cylinder->data.parabolic_cylinder->focal = 1; /* default focal length */ + parabolic_cylinder->dev = dev; + ref_init(&parabolic_cylinder->ref); + +exit: + if (out_parabolic_cylinder) *out_parabolic_cylinder = parabolic_cylinder; + return res; +error: + if (parabolic_cylinder) { + SSOL(quadric_ref_put(parabolic_cylinder)); + parabolic_cylinder = NULL; + } + goto exit; +} + +res_T +ssol_quadric_parabol_set_focal + (struct ssol_quadric* parabol, + double focal) +{ + if (focal <= 0 || !parabol || parabol->type != QUADRIC_PARABOL) { + return RES_BAD_ARG; + } + + parabol->data.parabol->focal = focal; + + return RES_OK; + +} + + res_T + ssol_quadric_parabolic_cylinder_set_focal + (struct ssol_quadric* parabolic_cylinder, + double focal) + { + if (focal <= 0 + || !parabolic_cylinder + || parabolic_cylinder->type != QUADRIC_PARABOLIC_CYLINDER) + { + return RES_BAD_ARG; + } + + parabolic_cylinder->data.parabolic_cylinder->focal = focal; + + return RES_OK; + } + +res_T +ssol_quadric_ref_get +(struct ssol_quadric* quadric) +{ + if (!quadric) return RES_BAD_ARG; + ref_get(&quadric->ref); + return RES_OK; +} + +res_T +ssol_quadric_ref_put +(struct ssol_quadric* quadric) +{ + if (!quadric) return RES_BAD_ARG; + ref_put(&quadric->ref, quadric_release); + return RES_OK; +} diff --git a/src/ssol_quadric_c.h b/src/ssol_quadric_c.h @@ -0,0 +1,69 @@ +/* Copyright (C) CNRS 2016 +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SSOL_QUADRIC_C_H +#define SSOL_QUADRIC_C_H + +#include <rsys/ref_count.h> + +enum quadric_type { + QUADRIC_NONE, + QUADRIC_PLANE, + QUADRIC_PARABOL, + QUADRIC_PARABOLIC_CYLINDER +}; + +/* The following quadric definitions are in local coordinate system. */ +struct quadric_plane { + /* local space definition is z = 0 */ + /* scene space definition */ + /* TODO */ + + struct ssol_device* dev; + ref_T ref; +}; +struct quadric_parabol { + /* local space definition: x^2 + y^2 - 4 focal z = 0 */ + double focal; + /* scene space definition */ + /* TODO */ + + struct ssol_device* dev; + ref_T ref; +}; + +struct quadric_parabolic_cylinder { + /* local space definition: y^2 - 4 focal z = 0 */ + double focal; + /* scene space definition */ + /* TODO */ + + struct ssol_device* dev; + ref_T ref; +}; + +struct ssol_quadric { + enum quadric_type type; + union { + struct quadric_plane* plane; + struct quadric_parabol* parabol; + struct quadric_parabolic_cylinder* parabolic_cylinder; + } data; + + struct ssol_device* dev; + ref_T ref; +}; + +#endif /* SSOL_QUADRIC_C_H */