diff options
Diffstat (limited to 'source')
557 files changed, 73282 insertions, 68 deletions
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 6263261ae1c..f18a6e8142b 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -41,6 +41,7 @@ ADD_SUBDIRECTORY(readblenfile) ADD_SUBDIRECTORY(render) ADD_SUBDIRECTORY(blenfont) ADD_SUBDIRECTORY(ikplugin) +ADD_SUBDIRECTORY(freestyle) IF(WITH_OPENEXR) ADD_SUBDIRECTORY(imbuf/intern/openexr) diff --git a/source/blender/SConscript b/source/blender/SConscript index 9910db1902f..04be9a2e34f 100644 --- a/source/blender/SConscript +++ b/source/blender/SConscript @@ -9,6 +9,7 @@ SConscript(['avi/SConscript', 'blenpluginapi/SConscript', 'gpu/SConscript', 'editors/SConscript', + 'freestyle/SConscript', 'imbuf/SConscript', 'imbuf/intern/cineon/SConscript', 'makesdna/SConscript', diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index da5e73bbb45..3c054d49871 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -30,7 +30,7 @@ SET(INC . ../../../intern/guardedalloc ../../../intern/memutil ../editors/include ../blenlib ../makesdna ../render/extern/include ../../../intern/decimation/extern ../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern - ../../../intern/iksolver/extern ../blenloader ../ikplugin + ../../../intern/iksolver/extern ../blenloader ../ikplugin ../freestyle ../nodes ../../../extern/glew/include ../gpu ../makesrna ../../../intern/smoke/extern ../../../intern/bsp/extern ../blenfont ../../../intern/audaspace/intern diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 37a63be6389..73f6a8393ed 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -7,7 +7,7 @@ incs = '. #/intern/guardedalloc #/intern/memutil ../editors/include' incs += ' ../blenlib ../blenfont ../makesdna ../windowmanager' incs += ' ../render/extern/include #/intern/decimation/extern ../makesrna' incs += ' ../imbuf ../ikplugin ../avi #/intern/elbeem/extern ../nodes' -incs += ' #/intern/iksolver/extern ../blenloader' +incs += ' #/intern/iksolver/extern ../blenloader ../freestyle' incs += ' #/extern/bullet2/src' incs += ' #/intern/opennl/extern #/intern/bsp/extern' incs += ' ../gpu #/extern/glew/include' diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 9cc154a3c2c..09f3b573fae 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -144,6 +144,7 @@ void init_material(Material *ma) ma->tx_limit= 0.0; ma->tx_falloff= 1.0; ma->shad_alpha= 1.0f; + ma->vcol_alpha= 0; ma->gloss_mir = ma->gloss_tra= 1.0; ma->samp_gloss_mir = ma->samp_gloss_tra= 18; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index fe97d892a74..aeeae28e54c 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -95,6 +95,8 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "FRS_freestyle_config.h" + //XXX #include "nla.h" #ifdef WIN32 @@ -244,7 +246,8 @@ Scene *copy_scene(Main *bmain, Scene *sce, int type) void free_scene(Scene *sce) { Base *base; - + SceneRenderLayer *srl; + base= sce->base.first; while(base) { base->object->id.us--; @@ -284,6 +287,10 @@ void free_scene(Scene *sce) sce->r.ffcodecdata.properties = NULL; } + for(srl= sce->r.layers.first; srl; srl= srl->next) { + BLI_freelistN( &srl->freestyleConfig.modules); + } + BLI_freelistN(&sce->markers); BLI_freelistN(&sce->transform_spaces); BLI_freelistN(&sce->r.layers); @@ -955,6 +962,7 @@ void scene_add_render_layer(Scene *sce) srl->lay= (1<<20) -1; srl->layflag= 0x7FFF; /* solid ztra halo edge strand */ srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z; + FRS_add_freestyle_config( srl ); } /* render simplification */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f4112bde8da..93aeb858283 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4211,6 +4211,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) Editing *ed; Sequence *seq; MetaStack *ms; + SceneRenderLayer *srl; sce->theDag = NULL; sce->dagisvalid = 0; @@ -4384,6 +4385,10 @@ static void direct_link_scene(FileData *fd, Scene *sce) link_list(fd, &(sce->transform_spaces)); link_list(fd, &(sce->r.layers)); + for(srl= sce->r.layers.first; srl; srl= srl->next) { + link_list(fd, &(srl->freestyleConfig.modules)); + } + sce->nodetree= newdataadr(fd, sce->nodetree); if(sce->nodetree) direct_link_nodetree(fd, sce->nodetree); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 3e3ca8dd174..1cd68ec6f04 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1782,6 +1782,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase) TimeMarker *marker; TransformOrientation *ts; SceneRenderLayer *srl; + FreestyleModuleConfig *fmc; ToolSettings *tos; sce= scebase->first; @@ -1906,8 +1907,14 @@ static void write_scenes(WriteData *wd, ListBase *scebase) for(ts = sce->transform_spaces.first; ts; ts = ts->next) writestruct(wd, DATA, "TransformOrientation", 1, ts); - for(srl= sce->r.layers.first; srl; srl= srl->next) + for(srl= sce->r.layers.first; srl; srl= srl->next) { writestruct(wd, DATA, "SceneRenderLayer", 1, srl); + + for(fmc= srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) { + writestruct(wd, DATA, "FreestyleModuleConfig", 1, fmc); + } + + } if(sce->nodetree) { writestruct(wd, DATA, "bNodeTree", 1, sce->nodetree); diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index 86085aa0573..58a52f7041d 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -39,6 +39,7 @@ SET(INC ../windowmanager ../../../intern/audaspace/intern ../nodes ../gpu + ../freestyle ../blenfont ../ikplugin ) diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript index 575f988544c..cb901be2494 100644 --- a/source/blender/editors/render/SConscript +++ b/source/blender/editors/render/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' -incs += ' ../../gpu' +incs += ' ../../gpu ../../freestyle' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' incs += ' ../../blenloader' diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index 99b68c2bb74..86df5ee7150 100644 --- a/source/blender/editors/render/render_intern.h +++ b/source/blender/editors/render/render_intern.h @@ -48,6 +48,10 @@ void MATERIAL_OT_paste(struct wmOperatorType *ot); void SCENE_OT_render_layer_add(struct wmOperatorType *ot); void SCENE_OT_render_layer_remove(struct wmOperatorType *ot); +void SCENE_OT_freestyle_module_add(struct wmOperatorType *ot); +void SCENE_OT_freestyle_module_remove(struct wmOperatorType *ot); +void SCENE_OT_freestyle_module_move_up(struct wmOperatorType *ot); +void SCENE_OT_freestyle_module_move_down(struct wmOperatorType *ot); void TEXTURE_OT_slot_move(struct wmOperatorType *ot); diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c index 62fb48c34ff..68b14a4103a 100644 --- a/source/blender/editors/render/render_ops.c +++ b/source/blender/editors/render/render_ops.c @@ -59,6 +59,11 @@ void ED_operatortypes_render(void) WM_operatortype_append(SCENE_OT_render_layer_add); WM_operatortype_append(SCENE_OT_render_layer_remove); + WM_operatortype_append(SCENE_OT_freestyle_module_add); + WM_operatortype_append(SCENE_OT_freestyle_module_remove); + WM_operatortype_append(SCENE_OT_freestyle_module_move_up); + WM_operatortype_append(SCENE_OT_freestyle_module_move_down); + #if (defined(WITH_QUICKTIME) && !defined(USE_QTKIT)) WM_operatortype_append(SCENE_OT_render_data_set_quicktime_codec); #endif diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 21e3b55ba0f..e117c609f83 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -58,6 +58,8 @@ #include "GPU_material.h" +#include "FRS_freestyle.h" + #include "RNA_access.h" #include "RNA_enum_types.h" @@ -686,6 +688,126 @@ void SCENE_OT_render_layer_remove(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +static int freestyle_module_add_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SceneRenderLayer *srl = (SceneRenderLayer*) BLI_findlink(&scene->r.layers, scene->r.actlay); + + FRS_add_module(&srl->freestyleConfig); + + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_module_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Freestyle Module"; + ot->idname= "SCENE_OT_freestyle_module_add"; + ot->description="Add a style module into the list of modules."; + + /* api callbacks */ + ot->exec= freestyle_module_add_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int freestyle_module_remove_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SceneRenderLayer *srl = (SceneRenderLayer*) BLI_findlink(&scene->r.layers, scene->r.actlay); + PointerRNA ptr= CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings); + FreestyleModuleConfig *module= ptr.data; + + FRS_delete_module(&srl->freestyleConfig, module); + + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_module_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove Freestyle Module"; + ot->idname= "SCENE_OT_freestyle_module_remove"; + ot->description="Remove the style module from the stack."; + + /* api callbacks */ + ot->exec= freestyle_module_remove_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int freestyle_module_move_up_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SceneRenderLayer *srl = (SceneRenderLayer*) BLI_findlink(&scene->r.layers, scene->r.actlay); + PointerRNA ptr= CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings); + FreestyleModuleConfig *module= ptr.data; + int active = RNA_boolean_get(op->ptr, "active"); + + if(active) + FRS_move_up_module(&srl->freestyleConfig, module); + + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_module_move_up(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Move Up Freestyle Module"; + ot->idname= "SCENE_OT_freestyle_module_move_up"; + ot->description="Move the style module up in the stack."; + + /* api callbacks */ + ot->exec= freestyle_module_move_up_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* props */ + RNA_def_boolean(ot->srna, "active", 0, "Active", "True if the operator is enabled."); +} + +static int freestyle_module_move_down_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SceneRenderLayer *srl = (SceneRenderLayer*) BLI_findlink(&scene->r.layers, scene->r.actlay); + PointerRNA ptr= CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings); + FreestyleModuleConfig *module= ptr.data; + int active = RNA_boolean_get(op->ptr, "active"); + + if(active) + FRS_move_down_module(&srl->freestyleConfig, module); + + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_OPTIONS, scene); + + return OPERATOR_FINISHED; +} + +void SCENE_OT_freestyle_module_move_down(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Move Down Freestyle Module"; + ot->idname= "SCENE_OT_freestyle_module_move_down"; + ot->description="Move the style module down in the stack."; + + /* api callbacks */ + ot->exec= freestyle_module_move_down_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* props */ + RNA_def_boolean(ot->srna, "active", 0, "Active", "True if the operator is enabled."); +} + static int texture_slot_move(bContext *C, wmOperator *op) { ID *id= CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 728ce622d9b..49f292ec432 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2901,6 +2901,9 @@ static int screen_render_exec(bContext *C, wmOperator *op) } RE_test_break_cb(re, NULL, (int (*)(void *)) blender_test_break); + /* inform Freestyle of the context */ + FRS_set_context(C); + if(RNA_boolean_get(op->ptr, "animation")) RE_BlenderAnim(re, scene, scene->r.sfra, scene->r.efra, scene->r.frame_step, op->reports); else @@ -3191,6 +3194,9 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) /* handle UI stuff */ WM_cursor_wait(1); + /* inform Freestyle of the context */ + FRS_set_context(C); + /* flush multires changes (for sculpt) */ multires_force_render_update(CTX_data_active_object(C)); diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index c4db054ff50..6286b18a7e0 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -4360,11 +4360,6 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa int active; for(te= lb->first; te; te= te->next) { - - /* exit drawing early */ - if((*offsx) - OL_X > xmax) - break; - tselem= TREESTORE(te); /* object hierarchy always, further constrained on level */ diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 0c2e64f9799..81a508de139 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -772,7 +772,7 @@ void VIEW3D_OT_rotate(wmOperatorType *ot) /* api callbacks */ ot->invoke= viewrotate_invoke; ot->modal= viewrotate_modal; - ot->poll= ED_operator_view3d_rotate; + ot->poll= ED_operator_view3d_active; /* flags */ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; @@ -2033,7 +2033,7 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot) /* api callbacks */ ot->exec= vieworbit_exec; - ot->poll= ED_operator_view3d_rotate; + ot->poll= ED_operator_view3d_active; /* flags */ ot->flag= 0; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index b6d0d3d3cc5..38f53de9078 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -542,9 +542,6 @@ int transformEvent(TransInfo *t, wmEvent *event) if (event->type == MOUSEMOVE) { - if (t->modifiers & MOD_CONSTRAINT_SELECT) - t->con.mode |= CON_SELECT; - t->mval[0] = event->x - t->ar->winrct.xmin; t->mval[1] = event->y - t->ar->winrct.ymin; @@ -1634,6 +1631,9 @@ void transformApply(const bContext *C, TransInfo *t) { if ((t->redraw & TREDRAW_HARD) || (t->draw_handle_apply == NULL && (t->redraw & TREDRAW_SOFT))) { + if (t->modifiers & MOD_CONSTRAINT_SELECT) + t->con.mode |= CON_SELECT; + selectConstraint(t); if (t->transform) { t->transform(t, t->mval); // calls recalcData() diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 76df012565e..4c0f192ed40 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -518,7 +518,6 @@ void initTransformOrientation(bContext *C, TransInfo *t) switch(t->current_orientation) { case V3D_MANIP_GLOBAL: - unit_m3(t->spacemtx); strcpy(t->spacename, "global"); break; diff --git a/source/blender/freestyle/CMakeLists.txt b/source/blender/freestyle/CMakeLists.txt new file mode 100644 index 00000000000..18f721ccfdc --- /dev/null +++ b/source/blender/freestyle/CMakeLists.txt @@ -0,0 +1,42 @@ +# $Id: CMakeLists.txt 14444 2008-04-16 22:40:48Z hos $ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Jacques Beaurain. +# +# ***** END GPL LICENSE BLOCK ***** + +FILE(GLOB_RECURSE SRC *.cpp) + +SET(INC + ../blenkernel ../blenloader ../blenlib ../imbuf ../makesdna ../makesrna + ../python ../python/intern + ../render/extern/include ../render/intern/include ../include ../src + ../../../extern/glew/include ../../../intern/guardedalloc ../freestyle + ${PYTHON_INC} + ${PNG_INC} +) + +IF(WIN32) + SET(INC ${INC} ${PTHREADS_INC}) +ENDIF(WIN32) + +BLENDERLIB(bf_freestyle "${SRC}" "${INC}") diff --git a/source/blender/freestyle/FRS_freestyle.h b/source/blender/freestyle/FRS_freestyle.h new file mode 100644 index 00000000000..3d8e785ce99 --- /dev/null +++ b/source/blender/freestyle/FRS_freestyle.h @@ -0,0 +1,35 @@ +#ifndef FRS_FREESTYLE_H +#define FRS_FREESTYLE_H + +#ifdef __cplusplus +extern "C" { +#endif + + #include "DNA_listBase.h" + #include "DNA_scene_types.h" + + #include "BKE_context.h" + + extern Scene *freestyle_scene; + extern float freestyle_viewpoint[3]; + extern float freestyle_mv[4][4]; + extern float freestyle_proj[4][4]; + extern int freestyle_viewport[4]; + + // Rendering + void FRS_initialize(); + void FRS_set_context(bContext* C); + void FRS_add_Freestyle( struct Render* re); + void FRS_exit(); + + // Panel configuration + void FRS_add_module(FreestyleConfig *config); + void FRS_delete_module(FreestyleConfig *config, FreestyleModuleConfig *module_conf); + void FRS_move_up_module(FreestyleConfig *config, FreestyleModuleConfig *module_conf); + void FRS_move_down_module(FreestyleConfig *config, FreestyleModuleConfig *module_conf); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/freestyle/FRS_freestyle_config.h b/source/blender/freestyle/FRS_freestyle_config.h new file mode 100644 index 00000000000..86a05d1aa22 --- /dev/null +++ b/source/blender/freestyle/FRS_freestyle_config.h @@ -0,0 +1,17 @@ +#ifndef FRS_FREESTYLE_CONFIG_H +#define FRS_FREESTYLE_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + + #include "DNA_scene_types.h" + + void FRS_add_freestyle_config( SceneRenderLayer* srl ); + void FRS_free_freestyle_config( SceneRenderLayer* srl ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/freestyle/SConscript b/source/blender/freestyle/SConscript new file mode 100644 index 00000000000..eefee0cc2c4 --- /dev/null +++ b/source/blender/freestyle/SConscript @@ -0,0 +1,86 @@ +#!/usr/bin/python +import sys +Import ('env') + +sources = [] +defs = [] +incs = '' + +incs += '../blenkernel ../blenloader ../blenlib ../imbuf ../makesdna ../makesrna' +incs += ' ../python ../python/intern' +incs += ' ../render/extern/include ../render/intern/include ../include ../src' +incs += ' #/extern/glew/include #/intern/guardedalloc ../freestyle' +incs += ' ' + env['BF_PYTHON_INC'] +incs += ' ' + env['BF_PNG_INC'] + + +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + +######################################################## +# folders sources +######################################################## + +# system +prefix = 'intern/system' +system_sources = env.Glob(prefix + '/*.cpp') + +# image +prefix = 'intern/image' +image_sources = env.Glob(prefix + '/*.cpp') + +# geometry +prefix = 'intern/geometry' +geometry_sources = env.Glob(prefix + '/*.cpp') + +# scene_graph +prefix = 'intern/scene_graph' +scene_graph_sources = env.Glob(prefix + '/*.cpp') + +# winged_edge +prefix = 'intern/winged_edge' +winged_edge_sources = env.Glob(prefix + '/*.cpp') + +# view_map +prefix = 'intern/view_map' +view_map_sources = env.Glob(prefix + '/*.cpp') + +# stroke +prefix = 'intern/stroke' +stroke_sources = env.Glob(prefix + '/*.cpp') + +# rendering +prefix = 'intern/rendering' +rendering_sources = env.Glob(prefix + '/GL*.cpp') + +# application +prefix = 'intern/application' +application_sources = env.Glob(prefix + '/*.cpp') + +# blender_interface +prefix = 'intern/blender_interface' +interface_sources = env.Glob(prefix + '/*.cpp') + +# Python +prefix = 'intern/python' +python_sources = env.Glob(prefix + '/*.cpp') \ + + env.Glob(prefix + '/*/*.cpp') \ + + env.Glob(prefix + '/*/*/*.cpp') \ + + env.Glob(prefix + '/*/*/*/*.cpp') + +sources = system_sources + image_sources + geometry_sources + scene_graph_sources \ + + winged_edge_sources + view_map_sources + stroke_sources + rendering_sources \ + + application_sources + interface_sources + python_sources + +env.BlenderLib (libname="bf_freestyle", + sources=sources, + includes=Split(incs), + defines=defs, + libtype=['core'], + priority = [370] # bf_python is 361 + ) + diff --git a/source/blender/freestyle/intern/application/AppCanvas.cpp b/source/blender/freestyle/intern/application/AppCanvas.cpp new file mode 100755 index 00000000000..4d4ab33cc59 --- /dev/null +++ b/source/blender/freestyle/intern/application/AppCanvas.cpp @@ -0,0 +1,178 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "../rendering/GLBlendEquation.h" + +#include "AppView.h" +#include "../image/Image.h" +#include "../system/TimeStamp.h" +#include "Controller.h" +#include "../stroke/StrokeRenderer.h" +#include "AppCanvas.h" +#include "../rendering/GLRenderer.h" +#include "../rendering/GLStrokeRenderer.h" +#include "AppConfig.h" + +#include "../system/StringUtils.h" + +AppCanvas::AppCanvas() +:Canvas() +{ + _pViewer = 0; + _MapsPath = StringUtils::toAscii( Config::Path::getInstance()->getMapsDir() ).c_str(); +} + +AppCanvas::AppCanvas(AppView* iViewer) +:Canvas() +{ + _pViewer = iViewer; +} + +AppCanvas::AppCanvas(const AppCanvas& iBrother) +:Canvas(iBrother) +{ + _pViewer = iBrother._pViewer; +} + +AppCanvas::~AppCanvas() +{ + _pViewer = 0; +} + +void AppCanvas::setViewer(AppView *iViewer) +{ + _pViewer = iViewer; +} + +int AppCanvas::width() const +{ + return _pViewer->width(); +} + +int AppCanvas::height() const +{ + return _pViewer->height();; +} + +BBox<Vec3r> AppCanvas::scene3DBBox() const +{ + return _pViewer->scene3DBBox(); +} + +void AppCanvas::preDraw() +{ + Canvas::preDraw(); +} + +void AppCanvas::init() +{ + + // static bool firsttime = true; + // if (firsttime) { + // + // _Renderer = new BlenderStrokeRenderer; + // if(!StrokeRenderer::loadTextures()) + // { + // cerr << "unable to load stroke textures" << endl; + // return; + // } + // } +} + +void AppCanvas::postDraw() +{ + Canvas::postDraw(); +} + +void AppCanvas::Erase() +{ + Canvas::Erase(); +} + +// Abstract + +void AppCanvas::readColorPixels(int x,int y,int w, int h, RGBImage& oImage) const +{ + float *rgb = new float[3*w*h]; + memset(rgb, 0, sizeof(float) * 3 * w * h); + int xsch = width(); + int ysch = height(); + if (_pass_diffuse.buf) { + int rectx = _pass_z.width; + int recty = _pass_z.height; + float xfac = ((float)rectx) / ((float)xsch); + float yfac = ((float)recty) / ((float)ysch); + printf("readColorPixels %d x %d @ (%d, %d) in %d x %d -- %d x %d @ %d%%\n", w, h, x, y, xsch, ysch, rectx, recty, (int)(xfac * 100.0f)); + int ii, jj; + for (int j = 0; j < h; j++) { + jj = (int)((y + j) * yfac); + if (jj < 0 || jj >= recty) + continue; + for (int i = 0; i < w; i++) { + ii = (int)((x + i) * xfac); + if (ii < 0 || ii >= rectx) + continue; + memcpy(rgb + (w * j + i) * 3, _pass_diffuse.buf + (rectx * jj + ii) * 3, sizeof(float) * 3); + } + } + } + oImage.setArray(rgb, xsch, ysch, w, h, x, y, false); +} + +void AppCanvas::readDepthPixels(int x,int y,int w, int h, GrayImage& oImage) const +{ + float *z = new float[w*h]; + memset(z, 0, sizeof(float) * w * h); + int xsch = width(); + int ysch = height(); + if (_pass_z.buf) { + int rectx = _pass_z.width; + int recty = _pass_z.height; + float xfac = ((float)rectx) / ((float)xsch); + float yfac = ((float)recty) / ((float)ysch); + printf("readDepthPixels %d x %d @ (%d, %d) in %d x %d -- %d x %d @ %d%%\n", w, h, x, y, xsch, ysch, rectx, recty, (int)(xfac * 100.0f)); + int ii, jj; + for (int j = 0; j < h; j++) { + jj = (int)((y + j) * yfac); + if (jj < 0 || jj >= recty) + continue; + for (int i = 0; i < w; i++) { + ii = (int)((x + i) * xfac); + if (ii < 0 || ii >= rectx) + continue; + z[w * j + i] = _pass_z.buf[rectx * jj + ii]; + } + } + } + oImage.setArray(z, xsch, ysch, w, h, x, y, false); +} + +void AppCanvas::RenderStroke(Stroke *iStroke) { + + if(_basic) + iStroke->RenderBasic(_Renderer); + else + iStroke->Render(_Renderer); +} + + +void AppCanvas::update() {} + diff --git a/source/blender/freestyle/intern/application/AppCanvas.h b/source/blender/freestyle/intern/application/AppCanvas.h new file mode 100755 index 00000000000..b45aafbaf33 --- /dev/null +++ b/source/blender/freestyle/intern/application/AppCanvas.h @@ -0,0 +1,69 @@ +#ifndef ARTCANVAS_H +#define ARTCANVAS_H + +#include "../stroke/Canvas.h" +#include "AppView.h" + +class AppCanvas : public Canvas +{ + +public: + AppCanvas(); + AppCanvas(AppView *iViewer); + AppCanvas(const AppCanvas& iBrother); + virtual ~AppCanvas(); + + /*! operations that need to be done before a draw */ + virtual void preDraw(); + + /*! operations that need to be done after a draw */ + virtual void postDraw(); + + /*! Erases the layers and clears the canvas */ + virtual void Erase(); + + /* init the canvas */ + virtual void init(); + + /*! Reads a pixel area from the canvas */ + virtual void readColorPixels(int x,int y,int w, int h, RGBImage& oImage) const; + /*! Reads a depth pixel area from the canvas */ + virtual void readDepthPixels(int x,int y,int w, int h, GrayImage& oImage) const; + + virtual BBox<Vec3r> scene3DBBox() const ; + + // abstract + virtual void RenderStroke(Stroke*); + virtual void update(); + + + /*! accessors */ + virtual int width() const ; + virtual int height() const ; + + AppView *_pViewer; + inline const AppView * viewer() const {return _pViewer;} + + /*! modifiers */ + void setViewer(AppView *iViewer) ; + + // soc + void setPassDiffuse(float *buf, int width, int height) { + _pass_diffuse.buf = buf; + _pass_diffuse.width = width; + _pass_diffuse.height = height; + } + void setPassZ(float *buf, int width, int height) { + _pass_z.buf = buf; + _pass_z.width = width; + _pass_z.height = height; + } +private: + struct { + float *buf; + int width, height; + } _pass_diffuse, _pass_z; +}; + + +#endif diff --git a/source/blender/freestyle/intern/application/AppConfig.cpp b/source/blender/freestyle/intern/application/AppConfig.cpp new file mode 100755 index 00000000000..761f0104dd1 --- /dev/null +++ b/source/blender/freestyle/intern/application/AppConfig.cpp @@ -0,0 +1,92 @@ +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "AppConfig.h" +#include <iostream> + +#include "../system/StringUtils.h" +using namespace std; + +extern "C" { + #include "BLI_path_util.h" +} + +namespace Config { +Path* Path::_pInstance = 0; +Path::Path() { + // get the root directory + //soc + setRootDir( BLI_gethome_folder("scripts", BLI_GETHOME_ALL) ); + + _pInstance = this; +} +void Path::setRootDir(const string& iRootDir) { + _ProjectDir = iRootDir + string(DIR_SEP.c_str()) + "freestyle"; + _ModelsPath = ""; + _PatternsPath = _ProjectDir + string(DIR_SEP.c_str()) + "data" + + string(DIR_SEP.c_str()) + "textures" + string(DIR_SEP.c_str()) + + "variation_patterns" + string(DIR_SEP.c_str()); + _BrushesPath = _ProjectDir + string(DIR_SEP.c_str()) + "data" + + string(DIR_SEP.c_str()) + "textures" + string(DIR_SEP.c_str()) + + "brushes" + string(DIR_SEP.c_str()); + _PythonPath = _ProjectDir + string(DIR_SEP.c_str()) ++ "style_modules" + string(DIR_SEP.c_str()) ; + if (getenv("PYTHONPATH")) { + _PythonPath += string(PATH_SEP.c_str()) + string(getenv("PYTHONPATH")); + } +#ifdef WIN32 + _BrowserCmd = "C:\\Program Files\\Internet Explorer\\iexplore.exe %s"; +#else + _BrowserCmd = "mozilla %s"; +#endif + _HelpIndexPath = _ProjectDir + string(DIR_SEP.c_str()) + "doc" + + string(DIR_SEP.c_str()) + "html" + string(DIR_SEP.c_str()) + + "index.html"; + _EnvMapDir = _ProjectDir + string(DIR_SEP.c_str()) + "data" + + string(DIR_SEP.c_str()) + "env_map" + string(DIR_SEP.c_str()); + _MapsDir = _ProjectDir + string(DIR_SEP.c_str()) + "data" + + string(DIR_SEP.c_str()) + "maps" + string(DIR_SEP.c_str()); +} +void Path::setHomeDir(const string& iHomeDir) { + _HomeDir = iHomeDir; +} +Path::~Path() { + _pInstance = 0; +} +Path* Path::getInstance() { + return _pInstance; +} +string Path::getEnvVar(const string& iEnvVarName) { + string value; + if (!getenv(StringUtils::toAscii(iEnvVarName).c_str() ) ) { + cerr << "Warning: You may want to set the $" + << StringUtils::toAscii(iEnvVarName) + << " environment variable to use Freestyle." << endl + << " Otherwise, the current directory will be used instead." + << endl; + value = "."; + } else { + value = getenv(StringUtils::toAscii(iEnvVarName).c_str() ); + } + return value; +} + +} // End of namepace Config + diff --git a/source/blender/freestyle/intern/application/AppConfig.h b/source/blender/freestyle/intern/application/AppConfig.h new file mode 100755 index 00000000000..59e85ca2e17 --- /dev/null +++ b/source/blender/freestyle/intern/application/AppConfig.h @@ -0,0 +1,105 @@ +// +// Filename : AppConfig.h +// Author : Emmanuel Turquin +// Purpose : Configuration file +// Date of creation : 26/02/2003 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef APP_CONFIG_H +# define APP_CONFIG_H + +# include <string> +# include "../system/FreestyleConfig.h" +# include "../system/Precision.h" + +using namespace std; + +namespace Config { + + class Path{ + protected: + static Path * _pInstance; + string _ProjectDir; + string _ModelsPath; + string _PatternsPath; + string _BrushesPath; + string _PythonPath; + string _BrowserCmd; + string _HelpIndexPath; + string _EnvMapDir; + string _MapsDir; + string _HomeDir; + public: + Path(); + virtual ~Path(); + static Path* getInstance(); + + void setRootDir(const string& iRootDir) ; + void setHomeDir(const string& iHomeDir) ; + + const string& getProjectDir() const {return _ProjectDir;} + const string& getModelsPath() const {return _ModelsPath;} + const string& getPatternsPath() const {return _PatternsPath;} + const string& getBrushesPath() const {return _BrushesPath;} + const string& getPythonPath() const {return _PythonPath;} + const string& getBrowserCmd() const {return _BrowserCmd;} + const string& getHelpIndexpath() const {return _HelpIndexPath;} + const string& getEnvMapDir() const {return _EnvMapDir;} + const string& getMapsDir() const {return _MapsDir;} + const string& getHomeDir() const {return _HomeDir;} + + static string getEnvVar(const string& iEnvVarName); + + }; + + // + // Configuration, default values + // + ////////////////////////////////////////////////////////////// + + // Application + static const string APPLICATION_NAME("APPNAME"); + static const string APPLICATION_VERSION("APPVERSION"); + + // ViewMap + static const string VIEWMAP_EXTENSION("vm"); + static const string VIEWMAP_MAGIC("ViewMap File"); + static const string VIEWMAP_VERSION("1.9"); + + // Style modules + static const string STYLE_MODULE_EXTENSION("py"); + static const string STYLE_MODULES_LIST_EXTENSION("sml"); + + // Options + static const string OPTIONS_DIR("." + APPLICATION_NAME); + static const string OPTIONS_FILE("options.xml"); + static const string OPTIONS_CURRENT_DIRS_FILE("current_dirs.xml"); + static const string OPTIONS_QGLVIEWER_FILE("qglviewer.xml"); + + // Default options + static const real DEFAULT_SPHERE_RADIUS = 1.0; + static const real DEFAULT_DKR_EPSILON = 0.0; + +} // End of namepace Config + +#endif // APP_CONFIG_H diff --git a/source/blender/freestyle/intern/application/AppView.cpp b/source/blender/freestyle/intern/application/AppView.cpp new file mode 100644 index 00000000000..886fa31bc93 --- /dev/null +++ b/source/blender/freestyle/intern/application/AppView.cpp @@ -0,0 +1,179 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +extern "C" { +#include "BLI_jitter.h" +} + +#include <iostream> +#include "../stroke/Canvas.h" +#include "AppView.h" +#include "../scene_graph/NodeLight.h" +#include "Controller.h" +#include "../view_map/Silhouette.h" +#include "../view_map/ViewMap.h" +#include "../scene_graph/LineRep.h" +#include "../scene_graph/NodeShape.h" +#include "../scene_graph/VertexRep.h" +#include "AppConfig.h" + +#include "../system/StringUtils.h" + +extern "C" { +#include "BLI_blenlib.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +#if 1 // FRS_antialiasing +#include "BKE_global.h" +#include "DNA_scene_types.h" +#endif + +#include "../../FRS_freestyle.h" + +} + +AppView::AppView(const char *iName) +{ + _Fovy = 30.f * M_PI / 180.0; + _ModelRootNode = new NodeDrawingStyle; + _SilhouetteRootNode = new NodeDrawingStyle; + _DebugRootNode = new NodeDrawingStyle; + + _RootNode.AddChild(_ModelRootNode); + _SilhouetteRootNode->setStyle(DrawingStyle::LINES); + _SilhouetteRootNode->setLightingEnabled(false); + _SilhouetteRootNode->setLineWidth(2.f); + _SilhouetteRootNode->setPointSize(3.f); + + _RootNode.AddChild(_SilhouetteRootNode); + + _DebugRootNode->setStyle(DrawingStyle::LINES); + _DebugRootNode->setLightingEnabled(false); + _DebugRootNode->setLineWidth(1.f); + + _RootNode.AddChild(_DebugRootNode); + + _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], + _ModelRootNode->bbox().getMin()[1]), + _ModelRootNode->bbox().getMin()[2]); + _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], + _ModelRootNode->bbox().getMax()[1]), + _ModelRootNode->bbox().getMax()[2]); + + _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox)); + _minAbs = __min(rabs(_minBBox), rabs(_maxBBox)); + + _p2DSelectionNode = new NodeDrawingStyle; + _p2DSelectionNode->setLightingEnabled(false); + _p2DSelectionNode->setStyle(DrawingStyle::LINES); + _p2DSelectionNode->setLineWidth(5.f); + + _p2DNode.AddChild(_p2DSelectionNode); + + + NodeLight *light = new NodeLight; + _Light.AddChild(light); +} + +AppView::~AppView() +{ + int ref = _RootNode.destroy(); + + _Light.destroy(); + ref = _p2DNode.destroy(); + +} + +real AppView::distanceToSceneCenter() { + BBox<Vec3r> bbox = _ModelRootNode->bbox(); + + Vec3r v( freestyle_viewpoint[0], freestyle_viewpoint[1], freestyle_viewpoint[2]); + v -= 0.5 * (bbox.getMin() + bbox.getMax()); + + return v.norm(); +} + + +real AppView::znear() { + + BBox<Vec3r> bbox = _ModelRootNode->bbox(); + Vec3r u = bbox.getMin(); + Vec3r v = bbox.getMax(); + Vec3r cameraCenter( freestyle_viewpoint[0], freestyle_viewpoint[1], freestyle_viewpoint[2]); + + Vec3r w1( u[0], u[1], u[2] ); + Vec3r w2( v[0], u[1], u[2] ); + Vec3r w3( u[0], v[1], u[2] ); + Vec3r w4( v[0], v[1], u[2] ); + Vec3r w5( u[0], u[1], v[2] ); + Vec3r w6( v[0], u[1], v[2] ); + Vec3r w7( u[0], v[1], v[2] ); + Vec3r w8( v[0], v[1], v[2] ); + + real _znear = __min( (w1-cameraCenter).norm(), + __min( (w2-cameraCenter).norm(), + __min( (w3-cameraCenter).norm(), + __min( (w4-cameraCenter).norm(), + __min( (w5-cameraCenter).norm(), + __min( (w6-cameraCenter).norm(), + __min( (w7-cameraCenter).norm(), + (w8-cameraCenter).norm() ))))))); + + return __max(_znear, 0.001); + + } + + real AppView::zfar() { + + BBox<Vec3r> bbox = _ModelRootNode->bbox(); + Vec3r u = bbox.getMin(); + Vec3r v = bbox.getMax(); + Vec3r cameraCenter( freestyle_viewpoint[0], freestyle_viewpoint[1], freestyle_viewpoint[2]); + + Vec3r w1( u[0], u[1], u[2] ); + Vec3r w2( v[0], u[1], u[2] ); + Vec3r w3( u[0], v[1], u[2] ); + Vec3r w4( v[0], v[1], u[2] ); + Vec3r w5( u[0], u[1], v[2] ); + Vec3r w6( v[0], u[1], v[2] ); + Vec3r w7( u[0], v[1], v[2] ); + Vec3r w8( v[0], v[1], v[2] ); + + real _zfar = __max( (w1-cameraCenter).norm(), + __max( (w2-cameraCenter).norm(), + __max( (w3-cameraCenter).norm(), + __max( (w4-cameraCenter).norm(), + __max( (w5-cameraCenter).norm(), + __max( (w6-cameraCenter).norm(), + __max( (w7-cameraCenter).norm(), + (w8-cameraCenter).norm() ))))))); + + return _zfar; + + } + + real AppView::GetFocalLength() + { + real Near = __max(0.1,(real)(-2.f*_maxAbs+ distanceToSceneCenter() )); + return Near; + } + + diff --git a/source/blender/freestyle/intern/application/AppView.h b/source/blender/freestyle/intern/application/AppView.h new file mode 100644 index 00000000000..b6a5dfcf1cc --- /dev/null +++ b/source/blender/freestyle/intern/application/AppView.h @@ -0,0 +1,221 @@ +#ifndef APPVIEW_H +# define APPVIEW_H + +# if !defined(WIN32) || defined(__GNUC__) +# include <algorithm> +using namespace std; +# define __min(x,y) (min(x,y)) +# define __max(x,y) (max(x,y)) +# endif // WIN32 + +# include "../geometry/Geom.h" +# include "../geometry/BBox.h" +# include "../scene_graph/NodeDrawingStyle.h" +# include "../system/Precision.h" +# include "AppConfig.h" + +using namespace Geometry; + +class AppView +{ + +public: + + AppView(const char *iName = 0); + virtual ~AppView(); + +public: + + //inherited + inline unsigned int width() { return _width; } + inline unsigned int height() { return _height; } + inline void setWidth( unsigned int width ) { _width = width; } + inline void setHeight( unsigned int height ) { _height = height; } + +protected: + unsigned int _width, _height; + +public: + + /*! Sets the model to draw in the viewer + * iModel + * The Root Node of the model + */ + inline void setModel(NodeGroup *iModel) + { + if(0 != _ModelRootNode->numberOfChildren()) + { + _ModelRootNode->DetachChildren(); + _ModelRootNode->clearBBox(); + } + + AddModel(iModel); + } + + /*! Adds a model for displaying in the viewer */ + inline void AddModel(NodeGroup *iModel) + { + _ModelRootNode->AddChild(iModel); + + _ModelRootNode->UpdateBBox(); + + _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], + _ModelRootNode->bbox().getMin()[1]), + _ModelRootNode->bbox().getMin()[2]); + _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], + _ModelRootNode->bbox().getMax()[1]), + _ModelRootNode->bbox().getMax()[2]); + + _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox)); + + _minAbs = __min(rabs(_minBBox), rabs(_maxBBox)); + + } + + inline void AddSilhouette(NodeGroup* iSilhouette) + { + _SilhouetteRootNode->AddChild(iSilhouette); + } + + inline void Add2DSilhouette(NodeGroup *iSilhouette) + { + //_pFENode->AddChild(iSilhouette); + } + + inline void Add2DVisibleSilhouette(NodeGroup *iVSilhouette) + { + //_pVisibleSilhouetteNode->AddChild(iVSilhouette); + } + + inline void setDebug(NodeGroup* iDebug) + { + if(0 != _DebugRootNode->numberOfChildren()) + { + _DebugRootNode->DetachChildren(); + _DebugRootNode->clearBBox(); + } + + AddDebug(iDebug); + } + + inline void AddDebug(NodeGroup* iDebug) + { + _DebugRootNode->AddChild(iDebug); + } + + inline void DetachModel(Node *iModel) + { + _ModelRootNode->DetachChild(iModel); + _ModelRootNode->UpdateBBox(); + + _minBBox = __min(__min(_ModelRootNode->bbox().getMin()[0], + _ModelRootNode->bbox().getMin()[1]), + _ModelRootNode->bbox().getMin()[2]); + _maxBBox = __max(__max(_ModelRootNode->bbox().getMax()[0], + _ModelRootNode->bbox().getMax()[1]), + _ModelRootNode->bbox().getMax()[2]); + + _maxAbs = __max(rabs(_minBBox), rabs(_maxBBox)); + _minAbs = __min(rabs(_minBBox), rabs(_maxBBox)); + } + + inline void DetachModel() + { + _ModelRootNode->DetachChildren(); + _ModelRootNode->clearBBox(); + + // 2D Scene + //_p2DNode.DetachChildren(); + //_pFENode->DetachChildren(); + //_pVisibleSilhouetteNode->DetachChildren(); + + } + + inline void DetachSilhouette() + { + _SilhouetteRootNode->DetachChildren(); + //_pFENode->DetachChildren(); + //_pVisibleSilhouetteNode->DetachChildren(); + _p2DSelectionNode->destroy(); + } + + inline void DetachVisibleSilhouette() + { + //_pVisibleSilhouetteNode->DetachChildren(); + _p2DSelectionNode->destroy(); + } + + inline void DetachDebug() + { + _DebugRootNode->DetachChildren(); + } + + + + real distanceToSceneCenter(); + real GetFocalLength(); + + inline real GetAspect() const + { + return ((real) _width/(real) _height); + } + + void setHorizontalFov( float hfov ) +{ + _Fovy = 2.0 * atan (tan(hfov / 2.0) / GetAspect()); +} + inline real GetFovyRadian() const + { + return _Fovy; + } + + inline real GetFovyDegrees() const + { + return _Fovy * 180.0 / M_PI; + } + + BBox<Vec3r> scene3DBBox() const { return _ModelRootNode->bbox(); } + + real znear(); + real zfar(); + + +public: + /*! Core scene drawing */ + void DrawScene(SceneVisitor *iRenderer); + + /*! 2D Scene Drawing */ + void Draw2DScene(SceneVisitor *iRenderer); + + +protected: + + /*! fabs or abs */ + inline int rabs(int x) {return abs(x);} + inline real rabs(real x) {return fabs(x);} + + +protected: + float _Fovy; + + //The root node container + NodeGroup _RootNode; + NodeDrawingStyle *_ModelRootNode; + NodeDrawingStyle *_SilhouetteRootNode; + NodeDrawingStyle *_DebugRootNode; + + NodeGroup _Light; + + real _minBBox; + real _maxBBox; + real _maxAbs; + real _minAbs; + + // 2D Scene + bool _Draw2DScene; + bool _Draw3DScene; NodeGroup _p2DNode; + NodeDrawingStyle *_p2DSelectionNode; + +}; + +#endif // APPVIEW_H diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp new file mode 100755 index 00000000000..43f091d3fa1 --- /dev/null +++ b/source/blender/freestyle/intern/application/Controller.cpp @@ -0,0 +1,877 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +// Must be included before any QT header, because of moc +#include "../system/PythonInterpreter.h" + +#include <string> +#include <fstream> +#include <float.h> + +#include "AppView.h" +#include "AppCanvas.h" +#include "AppConfig.h" + + +#include "../system/StringUtils.h" +#include "../scene_graph/NodeShape.h" +#include "../scene_graph/NodeTransform.h" +#include "../scene_graph/NodeDrawingStyle.h" +#include "../winged_edge/WingedEdgeBuilder.h" +#include "../winged_edge/WEdge.h" +#include "../scene_graph/VertexRep.h" +#include "../winged_edge/WXEdgeBuilder.h" +#include "../scene_graph/ScenePrettyPrinter.h" +#include "../winged_edge/WFillGrid.h" + +#include "../view_map/ViewMapTesselator.h" +#include "../stroke/StrokeTesselator.h" +#include "../view_map/ViewMapIO.h" +#include "Controller.h" +#include "../view_map/ViewMap.h" +#include "../winged_edge/Curvature.h" +#include "../image/Image.h" +#include "../view_map/SteerableViewMap.h" +#include "../stroke/PSStrokeRenderer.h" +#include "../stroke/TextStrokeRenderer.h" +#include "../stroke/StyleModule.h" + +#include "../system/StringUtils.h" + +#include "../blender_interface/BlenderFileLoader.h" +#include "../blender_interface/BlenderStrokeRenderer.h" + +#ifdef __cplusplus +extern "C" { +#endif + + #include "../../FRS_freestyle.h" + +#ifdef __cplusplus +} +#endif + + + +Controller::Controller() +{ + + const string sep(Config::DIR_SEP.c_str()); + //const string filename = Config::Path::getInstance()->getHomeDir() + sep + Config::OPTIONS_DIR + sep + Config::OPTIONS_CURRENT_DIRS_FILE; + //_current_dirs = new ConfigIO(filename, Config::APPLICATION_NAME + "CurrentDirs", true); + + _RootNode = new NodeGroup; + _RootNode->addRef(); + + _SilhouetteNode = NULL; + //_ProjectedSilhouette = NULL; + //_VisibleProjectedSilhouette = NULL; + + _DebugNode = new NodeGroup; + _DebugNode->addRef(); + + _winged_edge = NULL; + + _pView = NULL; + + _edgeTesselationNature = (Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE); + + _ProgressBar = new ProgressBar; + _SceneNumFaces = 0; + _minEdgeSize = DBL_MAX; + _EPSILON = 1e-6; + _bboxDiag = 0; + + _ViewMap = 0; + + _Canvas = 0; + + _VisibilityAlgo = ViewMapBuilder::ray_casting; + //_VisibilityAlgo = ViewMapBuilder::ray_casting_fast; + + _Canvas = new AppCanvas; + + _inter = new PythonInterpreter(); + _EnableQI = true; + _ComputeRidges = true; + _ComputeSteerableViewMap = false; + _ComputeSuggestive = true; + _sphereRadius = 1.0; + + init_options(); +} + +Controller::~Controller() +{ + if(NULL != _RootNode) + { + int ref = _RootNode->destroy(); + if(0 == ref) + delete _RootNode; + } + + if(NULL != _SilhouetteNode) + { + int ref = _SilhouetteNode->destroy(); + if(0 == ref) + delete _SilhouetteNode; + } + + if(NULL != _DebugNode) + { + int ref = _DebugNode->destroy(); + if(0 == ref) + delete _DebugNode; + } + + if(_winged_edge) { + delete _winged_edge; + _winged_edge = NULL; + } + + if(0 != _ViewMap) + { + delete _ViewMap; + _ViewMap = 0; + } + + if(0 != _Canvas) + { + delete _Canvas; + _Canvas = 0; + } + + if (_inter) { + delete _inter; + _inter = NULL; + } + + //delete _current_dirs; +} + +void Controller::setView(AppView *iView) +{ + if(NULL == iView) + return; + + _pView = iView; + _Canvas->setViewer(_pView); +} + +void Controller::setPassDiffuse(float *buf, int width, int height) +{ + AppCanvas *app_canvas = dynamic_cast<AppCanvas *>(_Canvas); + assert(app_canvas != 0); + app_canvas->setPassDiffuse(buf, width, height); +} + +void Controller::setPassZ(float *buf, int width, int height) +{ + AppCanvas *app_canvas = dynamic_cast<AppCanvas *>(_Canvas); + assert(app_canvas != 0); + app_canvas->setPassZ(buf, width, height); +} + +void Controller::setContext(bContext *C) +{ + PythonInterpreter* py_inter = dynamic_cast<PythonInterpreter*>(_inter); + assert(py_inter != 0); + py_inter->setContext(C); +} + +int Controller::LoadMesh(Render *re, SceneRenderLayer* srl) +{ + + BlenderFileLoader loader(re, srl); + + _Chrono.start(); + + NodeGroup *blenderScene = loader.Load(); + + if (blenderScene == NULL) { + cout << "Cannot load scene" << endl; + return 1; + } + + if( blenderScene->numberOfChildren() < 1) { + cout << "Empty scene" << endl; + blenderScene->destroy(); + delete blenderScene; + return 1; + } + + cout << "Scene loaded" << endl; + printf("Mesh cleaning : %lf\n", _Chrono.stop()); + _SceneNumFaces += loader.numFacesRead(); + + if(loader.minEdgeSize() < _minEdgeSize) + { + _minEdgeSize = loader.minEdgeSize(); + } + + // DEBUG + // ScenePrettyPrinter spp; + // blenderScene->accept(spp); + + _RootNode->AddChild(blenderScene); + _RootNode->UpdateBBox(); // FIXME: Correct that by making a Renderer to compute the bbox + + _pView->setModel(_RootNode); + //_pView->FitBBox(); + + + _Chrono.start(); + + + WXEdgeBuilder wx_builder; + blenderScene->accept(wx_builder); + _winged_edge = wx_builder.getWingedEdge(); + + printf("WEdge building : %lf\n", _Chrono.stop()); + + _Chrono.start(); + + _Grid.clear(); + Vec3r size; + for(unsigned int i=0; i<3; i++) + { + size[i] = fabs(_RootNode->bbox().getMax()[i] - _RootNode->bbox().getMin()[i]); + size[i] += size[i]/10.0; // let make the grid 1/10 bigger to avoid numerical errors while computing triangles/cells intersections + if(size[i]==0){ + cout << "Warning: the bbox size is 0 in dimension "<<i<<endl; + } + } + _Grid.configure(Vec3r(_RootNode->bbox().getMin() - size / 20.0), size, + _SceneNumFaces); + + // Fill in the grid: + WFillGrid fillGridRenderer(&_Grid, _winged_edge); + fillGridRenderer.fillGrid(); + + printf("Grid building : %lf\n", _Chrono.stop()); + + // DEBUG + _Grid.displayDebug(); + // + // _pView->setDebug(_DebugNode); + + //delete stuff + // if(0 != ws_builder) + // { + // delete ws_builder; + // ws_builder = 0; + // } + + //soc QFileInfo qfi(iFileName); + //soc string basename((const char*)qfi.fileName().toAscii().data()); + // char cleaned[FILE_MAX]; + // BLI_strncpy(cleaned, iFileName, FILE_MAX); + // BLI_cleanup_file(NULL, cleaned); + // string basename = StringUtils::toAscii( string(cleaned) ); + + _ListOfModels.push_back("Blender_models"); + + cout << "Triangles nb : " << _SceneNumFaces << endl; + _bboxDiag = (_RootNode->bbox().getMax()-_RootNode->bbox().getMin()).norm(); + cout << "Bounding Box : " << _bboxDiag << endl; + return 0; +} + + +void Controller::CloseFile() +{ + WShape::setCurrentId(0); + _pView->DetachModel(); + _ListOfModels.clear(); + if(NULL != _RootNode) + { + int ref = _RootNode->destroy(); + if(0 == ref) + _RootNode->addRef(); + + _RootNode->clearBBox(); + } + + _pView->DetachSilhouette(); + if (NULL != _SilhouetteNode) + { + int ref = _SilhouetteNode->destroy(); + if(0 == ref) + { + delete _SilhouetteNode; + _SilhouetteNode = NULL; + } + } + // if(NULL != _ProjectedSilhouette) + // { + // int ref = _ProjectedSilhouette->destroy(); + // if(0 == ref) + // { + // delete _ProjectedSilhouette; + // _ProjectedSilhouette = NULL; + // } + // } + // if(NULL != _VisibleProjectedSilhouette) + // { + // int ref = _VisibleProjectedSilhouette->destroy(); + // if(0 == ref) + // { + // delete _VisibleProjectedSilhouette; + // _VisibleProjectedSilhouette = NULL; + // } + // } + + _pView->DetachDebug(); + if(NULL != _DebugNode) + { + int ref = _DebugNode->destroy(); + if(0 == ref) + _DebugNode->addRef(); + } + + if(_winged_edge) { + delete _winged_edge; + _winged_edge = NULL; + } + + // We deallocate the memory: + if(NULL != _ViewMap) + { + delete _ViewMap; + _ViewMap = 0; + } + + // clears the canvas + _Canvas->Erase(); + + // clears the grid + _Grid.clear(); + _SceneNumFaces = 0; + _minEdgeSize = DBL_MAX; + + // soc: reset passes + setPassDiffuse(NULL, 0, 0); + setPassZ(NULL, 0, 0); +} + + + +void Controller::ComputeViewMap() +{ + + if (!_ListOfModels.size()) + return; + + if(NULL != _ViewMap) + { + delete _ViewMap; + _ViewMap = 0; + } + + _pView->DetachDebug(); + if(NULL != _DebugNode) + { + int ref = _DebugNode->destroy(); + if(0 == ref) + _DebugNode->addRef(); + } + + + _pView->DetachSilhouette(); + if (NULL != _SilhouetteNode) + { + int ref = _SilhouetteNode->destroy(); + if(0 == ref) + delete _SilhouetteNode; + } + // if(NULL != _ProjectedSilhouette) + // { + // int ref = _ProjectedSilhouette->destroy(); + // if(0 == ref) + // delete _ProjectedSilhouette; + // } + // if(NULL != _VisibleProjectedSilhouette) + // { + // int ref = _VisibleProjectedSilhouette->destroy(); + // if(0 == ref) + // { + // delete _VisibleProjectedSilhouette; + // _VisibleProjectedSilhouette = 0; + // } + // } + + // retrieve the 3D viewpoint and transformations information + //---------------------------------------------------------- + // Save the viewpoint context at the view level in order + // to be able to restore it later: + + // Restore the context of view: + // we need to perform all these operations while the + // 3D context is on. + Vec3r vp( freestyle_viewpoint[0], freestyle_viewpoint[1], freestyle_viewpoint[2]); + + //cout << "mv" << endl; + real mv[4][4]; + for( int i= 0; i < 4; i++) { + for( int j= 0; j < 4; j++) { + mv[i][j] = freestyle_mv[i][j]; + //cout << mv[i][j] << " "; + } + // cout << endl; + } + + //cout << "\nproj" << endl; + real proj[4][4]; + for( int i= 0; i < 4; i++) { + for( int j= 0; j < 4; j++) { + proj[i][j] = freestyle_proj[i][j]; + //cout << proj[i][j] << " "; + } + //cout << endl; + } + + int viewport[4]; + for( int i= 0; i < 4; i++) + viewport[i] = freestyle_viewport[i]; + + //cout << "\nfocal:" << _pView->GetFocalLength() << endl << endl; + + + + // Flag the WXEdge structure for silhouette edge detection: + //---------------------------------------------------------- + + cout << "\n=== Detecting silhouette edges ===" << endl; + _Chrono.start(); + + edgeDetector.setViewpoint(Vec3r(vp)); + edgeDetector.enableOrthographicProjection(proj[3][3] != 0.0); + edgeDetector.enableRidgesAndValleysFlag(_ComputeRidges); + edgeDetector.enableSuggestiveContours(_ComputeSuggestive); + edgeDetector.setSphereRadius(_sphereRadius); + edgeDetector.setSuggestiveContourKrDerivativeEpsilon(_suggestiveContourKrDerivativeEpsilon); + edgeDetector.processShapes(*_winged_edge); + + real duration = _Chrono.stop(); + printf("Feature lines : %lf\n", duration); + + // Builds the view map structure from the flagged WSEdge structure: + //---------------------------------------------------------- + ViewMapBuilder vmBuilder; + vmBuilder.setEnableQI(_EnableQI); + vmBuilder.setViewpoint(Vec3r(vp)); + vmBuilder.setTransform( mv, proj,viewport, _pView->GetFocalLength(), _pView->GetAspect(), _pView->GetFovyRadian()); + vmBuilder.setFrustum(_pView->znear(), _pView->zfar()); + vmBuilder.setGrid(&_Grid); + + // Builds a tesselated form of the silhouette for display purpose: + //--------------------------------------------------------------- + ViewMapTesselator3D sTesselator3d; + //ViewMapTesselator2D sTesselator2d; + //sTesselator2d.setNature(_edgeTesselationNature); + sTesselator3d.setNature(_edgeTesselationNature); + + cout << "\n=== Building the view map ===" << endl; + _Chrono.start(); + // Build View Map + _ViewMap = vmBuilder.BuildViewMap(*_winged_edge, _VisibilityAlgo, _EPSILON); + _ViewMap->setScene3dBBox(_RootNode->bbox()); + + printf("ViewMap edge count : %i\n", _ViewMap->viewedges_size() ); + + //Tesselate the 3D edges: + _SilhouetteNode = sTesselator3d.Tesselate(_ViewMap); + _SilhouetteNode->addRef(); + + // Tesselate 2D edges + // _ProjectedSilhouette = sTesselator2d.Tesselate(_ViewMap); + // _ProjectedSilhouette->addRef(); + + duration = _Chrono.stop(); + printf("ViewMap building : %lf\n", duration); + + + _pView->AddSilhouette(_SilhouetteNode); + //_pView->AddSilhouette(_WRoot); + //_pView->Add2DSilhouette(_ProjectedSilhouette); + //_pView->Add2DVisibleSilhouette(_VisibleProjectedSilhouette); + _pView->AddDebug(_DebugNode); + + // Draw the steerable density map: + //-------------------------------- + if(_ComputeSteerableViewMap){ + ComputeSteerableViewMap(); + } + // Reset Style modules modification flags + resetModified(true); +} + +void Controller::ComputeSteerableViewMap(){ +//soc + // if((!_Canvas) || (!_ViewMap)) + // return; + // + // // Build 4 nodes containing the edges in the 4 directions + // NodeGroup *ng[Canvas::NB_STEERABLE_VIEWMAP]; + // unsigned i; + // real c = 32.f/255.f; // see SteerableViewMap::readSteerableViewMapPixel() for information about this 32. + // for(i=0; i<Canvas::NB_STEERABLE_VIEWMAP; ++i){ + // ng[i] = new NodeGroup; + // } + // NodeShape *completeNS = new NodeShape; + // completeNS->material().setDiffuse(c,c,c,1); + // ng[Canvas::NB_STEERABLE_VIEWMAP-1]->AddChild(completeNS); + // SteerableViewMap * svm = _Canvas->getSteerableViewMap(); + // svm->Reset(); + // + // ViewMap::fedges_container& fedges = _ViewMap->FEdges(); + // LineRep * fRep; + // NodeShape *ns; + // for(ViewMap::fedges_container::iterator f=fedges.begin(), fend=fedges.end(); + // f!=fend; + // ++f){ + // if((*f)->viewedge()->qi() != 0) + // continue; + // fRep = new LineRep((*f)->vertexA()->point2d(),(*f)->vertexB()->point2d()) ; + // completeNS->AddRep(fRep); // add to the complete map anyway + // double *oweights = svm->AddFEdge(*f); + // for(i=0; i<Canvas::NB_STEERABLE_VIEWMAP-1; ++i){ + // ns = new NodeShape; + // double wc = oweights[i]*c; + // if(oweights[i] == 0) + // continue; + // ns->material().setDiffuse(wc, wc, wc, 1); + // ns->AddRep(fRep); + // ng[i]->AddChild(ns); + // } + // } + // + // GrayImage *img[Canvas::NB_STEERABLE_VIEWMAP]; + // //#ifdef WIN32 + // QGLBasicWidget offscreenBuffer(_pView, "SteerableViewMap", _pView->width(), _pView->height()); + // QPixmap pm; + // QImage qimg; + // for(i=0; i<Canvas::NB_STEERABLE_VIEWMAP; ++i){ + // offscreenBuffer.AddNode(ng[i]); + // //img[i] = new GrayImage(_pView->width(), _pView->height()); + // //offscreenBuffer.readPixels(0,0,_pView->width(), _pView->height(), img[i]->getArray()); + // pm = offscreenBuffer.renderPixmap(_pView->width(), _pView->height()); + // + // if(pm.isNull()) + // cout << "BuildViewMap Warning: couldn't render the steerable ViewMap" << endl; + // //pm.save(QString("steerable")+QString::number(i)+QString(".bmp"), "BMP"); + // // FIXME!! Lost of time ! + // qimg = pm.toImage(); + // // FIXME !! again! + // img[i] = new GrayImage(_pView->width(), _pView->height()); + // for(unsigned y=0;y<img[i]->height();++y){ + // for(unsigned x=0;x<img[i]->width();++x){ + // //img[i]->setPixel(x,y,(float)qGray(qimg.pixel(x,y))/255.f); + // img[i]->setPixel(x,y,(float)qGray(qimg.pixel(x,y))); + // // float c = qGray(qimg.pixel(x,y)); + // // img[i]->setPixel(x,y,qGray(qimg.pixel(x,y))); + // } + // } + // offscreenBuffer.DetachNode(ng[i]); + // ng[i]->destroy(); + // delete ng[i]; + // // check + // // qimg = QImage(_pView->width(), _pView->height(), 32); + // // for(y=0;y<img[i]->height();++y){ + // // for(unsigned x=0;x<img[i]->width();++x){ + // // float v = img[i]->pixel(x,y); + // // qimg.setPixel(x,y,qRgb(v,v,v)); + // // } + // // } + // // qimg.save(QString("newsteerable")+QString::number(i)+QString(".bmp"), "BMP"); + // } + // + // + // svm->buildImagesPyramids(img,false,0,1.f); +} + +void Controller::saveSteerableViewMapImages(){ + SteerableViewMap * svm = _Canvas->getSteerableViewMap(); + if(!svm){ + cerr << "the Steerable ViewMap has not been computed yet" << endl; + return; + } + svm->saveSteerableViewMap(); +} + +void Controller::toggleVisibilityAlgo() +{ + if(_VisibilityAlgo == ViewMapBuilder::ray_casting) { + _VisibilityAlgo = ViewMapBuilder::ray_casting_fast; + } + else if (_VisibilityAlgo == ViewMapBuilder::ray_casting_fast) { + _VisibilityAlgo = ViewMapBuilder::ray_casting_very_fast; + } + else { + _VisibilityAlgo = ViewMapBuilder::ray_casting; + } +} + +void Controller::setQuantitativeInvisibility(bool iBool) +{ + _EnableQI = iBool; +} + +bool Controller::getQuantitativeInvisibility() const +{ + return _EnableQI; +} + +void Controller::setComputeRidgesAndValleysFlag(bool iBool){ + _ComputeRidges = iBool; +} + +bool Controller::getComputeRidgesAndValleysFlag() const { + return _ComputeRidges; +} +void Controller::setComputeSuggestiveContoursFlag(bool b){ + _ComputeSuggestive = b; +} + +bool Controller::getComputeSuggestiveContoursFlag() const { + return _ComputeSuggestive; +} +void Controller::setComputeSteerableViewMapFlag(bool iBool){ + _ComputeSteerableViewMap = iBool; +} + +bool Controller::getComputeSteerableViewMapFlag() const { + return _ComputeSteerableViewMap; +} + +void Controller::DrawStrokes() +{ + if(_ViewMap == 0) + return; + + cout << "\n=== Stroke drawing ===" << endl; + _Chrono.start(); + _Canvas->Draw(); + real d = _Chrono.stop(); + cout << "Strokes generation : " << d << endl; + cout << "Stroke count : " << _Canvas->stroke_count << endl; + resetModified(); +} + +Render* Controller::RenderStrokes(Render *re) { + BlenderStrokeRenderer* blenderRenderer = new BlenderStrokeRenderer(re); + _Canvas->Render( blenderRenderer ); + Render* freestyle_render = blenderRenderer->RenderScene(re); + delete blenderRenderer; + + return freestyle_render; +} + +void Controller::InsertStyleModule(unsigned index, const char *iFileName) +{ + if( !BLI_testextensie(iFileName, ".py") ) { + cerr << "Error: Cannot load \"" << StringUtils::toAscii( string(iFileName) ) + << "\", unknown extension" << endl; + return; + } + + StyleModule* sm = new StyleModule(iFileName, _inter); + _Canvas->InsertStyleModule(index, sm); + +} + +void Controller::AddStyleModule(const char *iFileName) +{ + //_pStyleWindow->Add(iFileName); +} + +void Controller::RemoveStyleModule(unsigned index) +{ + _Canvas->RemoveStyleModule(index); +} + +void Controller::Clear() +{ + _Canvas->Clear(); +} + +void Controller::ReloadStyleModule(unsigned index, const char * iFileName) +{ + StyleModule* sm = new StyleModule(iFileName, _inter); + _Canvas->ReplaceStyleModule(index, sm); +} + +void Controller::SwapStyleModules(unsigned i1, unsigned i2) +{ + _Canvas->SwapStyleModules(i1, i2); +} + + +void Controller::toggleLayer(unsigned index, bool iDisplay) +{ + _Canvas->setVisible(index, iDisplay); +} + +void Controller::setModified(unsigned index, bool iMod) +{ + //_pStyleWindow->setModified(index, iMod); + _Canvas->setModified(index, iMod); + updateCausalStyleModules(index + 1); +} + +void Controller::updateCausalStyleModules(unsigned index) { + vector<unsigned> vec; + _Canvas->causalStyleModules(vec, index); + for (vector<unsigned>::const_iterator it = vec.begin(); it != vec.end(); it++) { + //_pStyleWindow->setModified(*it, true); + _Canvas->setModified(*it, true); + } +} + +void Controller::resetModified(bool iMod) +{ + //_pStyleWindow->resetModified(iMod); + _Canvas->resetModified(iMod); +} + +NodeGroup * Controller::BuildRep(vector<ViewEdge*>::iterator vedges_begin, + vector<ViewEdge*>::iterator vedges_end) +{ + ViewMapTesselator2D tesselator2D; + FrsMaterial mat; + mat.setDiffuse(1,1,0.3,1); + tesselator2D.setFrsMaterial(mat); + + return (tesselator2D.Tesselate(vedges_begin, vedges_end)); +} + +void Controller::toggleEdgeTesselationNature(Nature::EdgeNature iNature) +{ + _edgeTesselationNature ^= (iNature); + ComputeViewMap(); +} + +void Controller::setModelsDir(const string& dir) { + //_current_dirs->setValue("models/dir", dir); +} + +string Controller::getModelsDir() const { + string dir = "."; + //_current_dirs->getValue("models/dir", dir); + return dir; +} + +void Controller::setModulesDir(const string& dir) { + //_current_dirs->setValue("modules/dir", dir); +} + +string Controller::getModulesDir() const { + string dir = "."; + //_current_dirs->getValue("modules/dir", dir); + return dir; +} + +void Controller::setHelpIndex(const string& index) { + _help_index = index; +} + +string Controller::getHelpIndex() const { + return _help_index; +} + +void Controller::setBrowserCmd(const string& cmd) { + _browser_cmd = cmd; +} + +string Controller::getBrowserCmd() const { + return _browser_cmd; +} + +void Controller::resetInterpreter() { + if (_inter) + _inter->reset(); +} + + +void Controller::displayDensityCurves(int x, int y){ + SteerableViewMap * svm = _Canvas->getSteerableViewMap(); + if(!svm) + return; + + unsigned i,j; + typedef vector<Vec3r> densityCurve; + vector<densityCurve> curves(svm->getNumberOfOrientations()+1); + vector<densityCurve> curvesDirection(svm->getNumberOfPyramidLevels()); + + // collect the curves values + unsigned nbCurves = svm->getNumberOfOrientations()+1; + unsigned nbPoints = svm->getNumberOfPyramidLevels(); + if(!nbPoints) + return; + + // build the density/nbLevels curves for each orientation + for(i=0;i<nbCurves; ++i){ + for(j=0; j<nbPoints; ++j){ + curves[i].push_back(Vec3r(j, svm->readSteerableViewMapPixel(i, j, x, y), 0)); + } + } + // build the density/nbOrientations curves for each level + for(i=0;i<nbPoints; ++i){ + for(j=0; j<nbCurves; ++j){ + curvesDirection[i].push_back(Vec3r(j, svm->readSteerableViewMapPixel(j, i, x, y), 0)); + } + } + + // display the curves + // for(i=0; i<nbCurves; ++i) + // _pDensityCurvesWindow->setOrientationCurve(i, Vec2d(0,0), Vec2d(nbPoints, 1), curves[i], "scale", "density"); + // for(i=1; i<=8; ++i) + // _pDensityCurvesWindow->setLevelCurve(i, Vec2d(0,0), Vec2d(nbCurves, 1), curvesDirection[i], "orientation", "density"); + // _pDensityCurvesWindow->show(); +} + +void Controller::init_options(){ +// from AppOptionsWindow.cpp +// Default init options + + Config::Path * cpath = Config::Path::getInstance(); + + // Directories + ViewMapIO::Options::setModelsPath( StringUtils::toAscii( cpath->getModelsPath() ) ); + PythonInterpreter::Options::setPythonPath( StringUtils::toAscii( cpath->getPythonPath() ) ); + TextureManager::Options::setPatternsPath( StringUtils::toAscii( cpath->getPatternsPath() ) ); + TextureManager::Options::setBrushesPath( StringUtils::toAscii( cpath->getModelsPath() ) ); + + // ViewMap Format + ViewMapIO::Options::rmFlags(ViewMapIO::Options::FLOAT_VECTORS); + ViewMapIO::Options::rmFlags(ViewMapIO::Options::NO_OCCLUDERS); + setComputeSteerableViewMapFlag( false ); + + // Visibility + setQuantitativeInvisibility(true); + + // soc: initialize canvas + _Canvas->init(); + + // soc: initialize passes + setPassDiffuse(NULL, 0, 0); + setPassZ(NULL, 0, 0); +} diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h new file mode 100755 index 00000000000..9d1db24a026 --- /dev/null +++ b/source/blender/freestyle/intern/application/Controller.h @@ -0,0 +1,233 @@ +// +// Filename : Controller.h +// Author : Stephane Grabli +// Purpose : The spinal tap of the system +// Date of creation : 01/07/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CONTROLLER_H +# define CONTROLLER_H + +# include <string> +//# include "ConfigIO.h" +# include "../geometry/FastGrid.h" +# include "../geometry/HashGrid.h" +# include "../view_map/ViewMapBuilder.h" +# include "../system/TimeUtils.h" +# include "../system/ProgressBar.h" +# include "../system/Precision.h" +# include "../system/Interpreter.h" +# include "../view_map/FEdgeXDetector.h" + +class AppView; +class NodeGroup; +class WShape; +class SShape; +class ViewMap; +class ViewEdge; +class AppCanvas; +class InteractiveShader; +class Shader; +class StrokeRenderer; + +#ifdef __cplusplus +extern "C" { +#endif + + #include "render_types.h" + #include "DNA_scene_types.h" + +#ifdef __cplusplus +} +#endif + +class Controller +{ +public: + Controller() ; + ~Controller() ; + + void setView(AppView *iView); + void setPassDiffuse(float *buf, int width, int height); + void setPassZ(float *buf, int width, int height); + void setContext(bContext *C); + + //soc + void init_options(); + + int LoadMesh( Render *re, SceneRenderLayer* srl ); + int Load3DSFile(const char *iFileName); + void CloseFile(); + void ComputeViewMap(); + void ComputeSteerableViewMap(); + void saveSteerableViewMapImages(); + void toggleEdgeTesselationNature(Nature::EdgeNature iNature); + void DrawStrokes(); + Render* RenderStrokes(Render *re); + void SwapStyleModules(unsigned i1, unsigned i2); + void InsertStyleModule(unsigned index, const char *iFileName); + void AddStyleModule(const char *iFileName); + void RemoveStyleModule(unsigned index); + void ReloadStyleModule(unsigned index, const char * iFileName); + void Clear(); + void toggleLayer(unsigned index, bool iDisplay); + void setModified(unsigned index, bool iMod); + void resetModified(bool iMod=false); + void updateCausalStyleModules(unsigned index); + void displayDensityCurves(int x, int y); + + + ViewEdge * SelectViewEdge(real x, real y); + FEdge * SelectFEdge(real x, real y); + NodeGroup* BuildRep(vector<ViewEdge*>::iterator vedges_begin, + vector<ViewEdge*>::iterator vedges_end) ; + + NodeGroup* debugNode() {return _DebugNode;} + AppView * view() {return _pView;} + NodeGroup* debugScene() {return _DebugNode;} + Grid& grid() {return _Grid;} + + void toggleVisibilityAlgo(); + + void setQuantitativeInvisibility(bool iBool); // if true, we compute quantitativeInvisibility + bool getQuantitativeInvisibility() const; + + void setComputeRidgesAndValleysFlag(bool b); + bool getComputeRidgesAndValleysFlag() const ; + void setComputeSuggestiveContoursFlag(bool b); + bool getComputeSuggestiveContoursFlag() const ; + + void setComputeSteerableViewMapFlag(bool iBool); + bool getComputeSteerableViewMapFlag() const; + void setSphereRadius(real s){_sphereRadius=s;} + real getSphereRadius() const {return _sphereRadius;} + void setSuggestiveContourKrDerivativeEpsilon(real dkr){_suggestiveContourKrDerivativeEpsilon=dkr;} + real getSuggestiveContourKrDerivativeEpsilon() const {return _suggestiveContourKrDerivativeEpsilon;} + + void setModelsDir(const string& dir); + string getModelsDir() const; + void setModulesDir(const string& dir); + string getModulesDir() const; + void setHelpIndex(const string& dir); + string getHelpIndex() const; + void setBrowserCmd(const string& cmd); + string getBrowserCmd() const; + + void resetInterpreter(); + +public: + // Viewmap data structure + ViewMap * _ViewMap; + + // Canvas + AppCanvas *_Canvas; + +private: + + // Main Window: + //AppMainWindow *_pMainWindow; + + // List of models currently loaded + vector<string> _ListOfModels; + + // Current directories + //ConfigIO* _current_dirs; + + + + //View + // 3D + AppView *_pView; + + // 2D + //Viewer2DWindow *_pView2DWindow; + //Viewer2D *_pView2D; + + //Model + // Drawing Structure + NodeGroup *_RootNode; + + // Winged-Edge structure + WingedEdge* _winged_edge; + + // Silhouette structure: + //std::vector<SShape*> _SShapes; + //NodeGroup *_SRoot; + + // Silhouette + NodeGroup *_SilhouetteNode; + NodeGroup *_ProjectedSilhouette; + NodeGroup *_VisibleProjectedSilhouette; + + // more Debug info + NodeGroup *_DebugNode; + + // debug + // NodeUser<ViewMap> *_ViewMapNode; // FIXME + + // Chronometer: + Chronometer _Chrono; + + // Progress Bar + ProgressBar *_ProgressBar; + + // edges tesselation nature + int _edgeTesselationNature; + + FastGrid _Grid; + //HashGrid _Grid; + + unsigned int _SceneNumFaces; + real _minEdgeSize; + real _EPSILON; + real _bboxDiag; + + + //AppStyleWindow *_pStyleWindow; + //AppOptionsWindow *_pOptionsWindow; + //AppDensityCurvesWindow *_pDensityCurvesWindow; + + ViewMapBuilder::visibility_algo _VisibilityAlgo; + + // Script Interpreter + Interpreter* _inter; + + string _help_index; + string _browser_cmd; + + bool _EnableQI; + bool _ComputeRidges; + bool _ComputeSuggestive; + real _sphereRadius; + real _suggestiveContourKrDerivativeEpsilon; + + bool _ComputeSteerableViewMap; + + FEdgeXDetector edgeDetector; +}; + +extern Controller *g_pController; + +#endif // CONTROLLER_H diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp new file mode 100644 index 00000000000..b6b6b50c07c --- /dev/null +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -0,0 +1,404 @@ +#include "BlenderFileLoader.h" + +#include <assert.h> + +BlenderFileLoader::BlenderFileLoader(Render *re, SceneRenderLayer* srl) +{ + _re = re; + _srl = srl; + _Scene = NULL; + _numFacesRead = 0; + _minEdgeSize = DBL_MAX; +} + +BlenderFileLoader::~BlenderFileLoader() +{ + _Scene = NULL; +} + +NodeGroup* BlenderFileLoader::Load() +{ + ObjectInstanceRen *obi; + ObjectRen *obr; + + cout << "\n=== Importing triangular meshes into Blender ===" << endl; + + // creation of the scene root node + _Scene = new NodeGroup; + + _viewplane_left= _re->viewplane.xmin; + _viewplane_right= _re->viewplane.xmax; + _viewplane_bottom= _re->viewplane.ymin; + _viewplane_top= _re->viewplane.ymax; + _z_near= -_re->clipsta; + _z_far= -_re->clipend; +#if 0 + cout << "frustrum: l " << _viewplane_left << " r " << _viewplane_right + << " b " << _viewplane_bottom << " t " << _viewplane_top + << " n " << _z_near << " f " << _z_far << endl; +#endif + + int id = 0; + for(obi= (ObjectInstanceRen *) _re->instancetable.first; obi; obi=obi->next) { + if (!(obi->lay & _re->scene->lay & _srl->lay)) + continue; + + obr= obi->obr; + + if( obr->totvlak > 0) + insertShapeNode(obr, ++id); + else + cout << " Sorry, only vlak-based shapes are supported." << endl; + } + + //Returns the built scene. + return _Scene; +} + +#define CLIPPED_BY_NEAR -1 +#define NOT_CLIPPED 0 +#define CLIPPED_BY_FAR 1 + +// check if each vertex of a triangle (V1, V2, V3) is clipped by the near/far plane +// and calculate the number of triangles to be generated by clipping +int BlenderFileLoader::countClippedFaces(VertRen *v1, VertRen *v2, VertRen *v3, int clip[3]) +{ + VertRen *v[3]; + int numClipped, sum, numTris; + + v[0] = v1; + v[1] = v2; + v[2] = v3; + numClipped = sum = 0; + for (int i = 0; i < 3; i++) { + if (v[i]->co[2] > _z_near) { + clip[i] = CLIPPED_BY_NEAR; + numClipped++; + } else if (v[i]->co[2] < _z_far) { + clip[i] = CLIPPED_BY_FAR; + numClipped++; + } else { + clip[i] = NOT_CLIPPED; + } +// printf("%d %s\n", i, (clip[i] == NOT_CLIPPED) ? "not" : (clip[i] == CLIPPED_BY_NEAR) ? "near" : "far"); + sum += clip[i]; + } + switch (numClipped) { + case 0: + numTris = 1; // triangle + break; + case 1: + numTris = 2; // tetragon + break; + case 2: + if (sum == 0) + numTris = 3; // pentagon + else + numTris = 1; // triangle + break; + case 3: + if (sum == 3 || sum == -3) + numTris = 0; + else + numTris = 2; // tetragon + break; + } + return numTris; +} + +// find the intersection point C between the line segment from V1 to V2 and +// a clipping plane at depth Z (i.e., the Z component of C is known, while +// the X and Y components are unknown). +void BlenderFileLoader::clipLine(VertRen *v1, VertRen *v2, float c[3], float z) +{ + double d[3]; + for (int i = 0; i < 3; i++) + d[i] = v2->co[i] - v1->co[i]; + double t = (z - v1->co[2]) / d[2]; + c[0] = v1->co[0] + t * d[0]; + c[1] = v1->co[1] + t * d[1]; + c[2] = z; +} + +// clip the triangle (V1, V2, V3) by the near and far clipping plane and +// obtain a set of vertices after the clipping. The number of vertices +// is at most 5. +void BlenderFileLoader::clipTriangle(int numTris, float triCoords[][3], VertRen *v1, VertRen *v2, VertRen *v3, int clip[3]) +{ + VertRen *v[3]; + int i, j, k; + + v[0] = v1; + v[1] = v2; + v[2] = v3; + k = 0; + for (i = 0; i < 3; i++) { + j = (i + 1) % 3; + if (clip[i] == NOT_CLIPPED) { + copy_v3_v3(triCoords[k++], v[i]->co); + if (clip[j] != NOT_CLIPPED) { + clipLine(v[i], v[j], triCoords[k++], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + } + } else if (clip[i] != clip[j]) { + if (clip[j] == NOT_CLIPPED) { + clipLine(v[i], v[j], triCoords[k++], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + } else { + clipLine(v[i], v[j], triCoords[k++], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + clipLine(v[i], v[j], triCoords[k++], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + } + } + } + assert (k == 2 + numTris); +} + +void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v2[3], float v3[3]) +{ + float v12[3], v13[3], n[3]; + float *fv[3], len; + unsigned i, j; + + // initialize the bounding box by the first vertex + if (ls->currentIndex == 0) { + copy_v3_v3(ls->minBBox, v1); + copy_v3_v3(ls->maxBBox, v1); + } + + // compute the normal of the triangle + sub_v3_v3v3(v12, v1, v2); + sub_v3_v3v3(v13, v1, v3); + cross_v3_v3v3(n, v12, v13); + normalize_v3(n); + + fv[0] = v1; + fv[1] = v2; + fv[2] = v3; + for (i = 0; i < 3; i++) { + + copy_v3_v3(ls->pv, fv[i]); + copy_v3_v3(ls->pn, n); + + // update the bounding box + for (j = 0; j < 3; j++) + { + if (ls->minBBox[j] > ls->pv[j]) + ls->minBBox[j] = ls->pv[j]; + + if (ls->maxBBox[j] < ls->pv[j]) + ls->maxBBox[j] = ls->pv[j]; + } + + len = len_v3v3(fv[i], fv[(i + 1) % 3]); + if (_minEdgeSize > len) + _minEdgeSize = len; + + *ls->pvi = ls->currentIndex; + *ls->pni = ls->currentIndex; + *ls->pmi = ls->currentMIndex; + + ls->currentIndex +=3; + ls->pv += 3; + ls->pn += 3; + + ls->pvi++; + ls->pni++; + ls->pmi++; + } +} + +void BlenderFileLoader::insertShapeNode(ObjectRen *obr, int id) +{ + // We parse vlak nodes and count the number of faces after the clipping by + // the near and far view planes is applied (Note: mesh vertices are in the + // camera coordinate system). + VlakRen *vlr; + unsigned numFaces = 0; + int clip_1[3], clip_2[3]; + for(int a=0; a < obr->totvlak; a++) { + if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; + else vlr++; +// printf("v1 %f, %f, %f\n", vlr->v1->co[0], vlr->v1->co[1], vlr->v1->co[2]); +// printf("v2 %f, %f, %f\n", vlr->v2->co[0], vlr->v2->co[1], vlr->v2->co[2]); +// printf("v3 %f, %f, %f\n", vlr->v3->co[0], vlr->v3->co[1], vlr->v3->co[2]); +// if (vlr->v4) printf("v4 %f, %f, %f\n", vlr->v4->co[0], vlr->v4->co[1], vlr->v4->co[2]); + numFaces += countClippedFaces(vlr->v1, vlr->v2, vlr->v3, clip_1); + if (vlr->v4) + numFaces += countClippedFaces(vlr->v1, vlr->v3, vlr->v4, clip_2); + } +// cout <<"numFaces " <<numFaces<<endl; + if (numFaces == 0) + return; + + // We allocate memory for the meshes to be imported + NodeTransform *currentMesh = new NodeTransform; + NodeShape * shape = new NodeShape; + + unsigned vSize = 3*3*numFaces; + float *vertices = new float[vSize]; + unsigned nSize = vSize; + float *normals = new float[nSize]; + unsigned *numVertexPerFaces = new unsigned[numFaces]; + vector<FrsMaterial> meshFrsMaterials; + + IndexedFaceSet::TRIANGLES_STYLE *faceStyle = new IndexedFaceSet::TRIANGLES_STYLE[numFaces]; + unsigned i; + for (i = 0; i <numFaces; i++) { + faceStyle[i] = IndexedFaceSet::TRIANGLES; + numVertexPerFaces[i] = 3; + } + + unsigned viSize = 3*numFaces; + unsigned *VIndices = new unsigned[viSize]; + unsigned niSize = viSize; + unsigned *NIndices = new unsigned[niSize]; + unsigned *MIndices = new unsigned[viSize]; // Material Indices + + struct LoaderState ls; + ls.pv = vertices; + ls.pn = normals; + ls.pvi = VIndices; + ls.pni = NIndices; + ls.pmi = MIndices; + ls.currentIndex = 0; + ls.currentMIndex = 0; + + FrsMaterial tmpMat; + + // We parse the vlak nodes again and import meshes while applying the clipping + // by the near and far view planes. + int p; + for(p=0; p < obr->totvlak; ++p) // we parse the faces of the mesh + { + // Lib3dsFace *f=&mesh->faceL[p]; + // Lib3dsMaterial *mat=0; + if((p & 255)==0) vlr = obr->vlaknodes[p>>8].vlak; + else vlr++; + + unsigned numTris_1, numTris_2; + numTris_1 = countClippedFaces(vlr->v1, vlr->v2, vlr->v3, clip_1); + numTris_2 = (vlr->v4) ? countClippedFaces(vlr->v1, vlr->v3, vlr->v4, clip_2) : 0; + if (numTris_1 == 0 && numTris_2 == 0) + continue; + + Material *mat = vlr->mat; + + if (mat) + { + tmpMat.setDiffuse( mat->r, mat->g, mat->b, mat->alpha ); + tmpMat.setSpecular( mat->specr, mat->specg, mat->specb, mat->spectra); + float s = 1.0 * (mat->har + 1) / 4 ; // in Blender: [1;511] => in OpenGL: [0;128] + if(s > 128.f) + s = 128.f; + tmpMat.setShininess(s); + } + + if(meshFrsMaterials.empty()) + { + meshFrsMaterials.push_back(tmpMat); + shape->setFrsMaterial(tmpMat); + } else { + // find if the material is aleady in the list + unsigned i=0; + bool found = false; + + for(vector<FrsMaterial>::iterator it=meshFrsMaterials.begin(), itend=meshFrsMaterials.end(); + it!=itend; + ++it){ + if(*it == tmpMat){ + ls.currentMIndex = i; + found = true; + break; + } + ++i; + } + + if(!found){ + meshFrsMaterials.push_back(tmpMat); + ls.currentMIndex = meshFrsMaterials.size()-1; + } + } + + float triCoords[5][3]; + + if (numTris_1 > 0) { + clipTriangle(numTris_1, triCoords, vlr->v1, vlr->v2, vlr->v3, clip_1); + for (i = 0; i < numTris_1; i++) { + addTriangle(&ls, triCoords[0], triCoords[i+1], triCoords[i+2]); + _numFacesRead++; + } + } + + if (numTris_2 > 0) { + clipTriangle(numTris_2, triCoords, vlr->v1, vlr->v3, vlr->v4, clip_2); + for (i = 0; i < numTris_2; i++) { + addTriangle(&ls, triCoords[0], triCoords[i+1], triCoords[i+2]); + _numFacesRead++; + } + } + } + + // We might have several times the same vertex. We want a clean + // shape with no real-vertex. Here, we are making a cleaning + // pass. + real *cleanVertices = NULL; + unsigned cvSize; + unsigned *cleanVIndices = NULL; + + GeomCleaner::CleanIndexedVertexArray( + vertices, vSize, + VIndices, viSize, + &cleanVertices, &cvSize, + &cleanVIndices); + + real *cleanNormals = NULL; + unsigned cnSize; + unsigned *cleanNIndices = NULL; + + GeomCleaner::CleanIndexedVertexArray( + normals, nSize, + NIndices, niSize, + &cleanNormals, &cnSize, + &cleanNIndices); + + // format materials array + FrsMaterial** marray = new FrsMaterial*[meshFrsMaterials.size()]; + unsigned mindex=0; + for(vector<FrsMaterial>::iterator m=meshFrsMaterials.begin(), mend=meshFrsMaterials.end(); + m!=mend; + ++m){ + marray[mindex] = new FrsMaterial(*m); + ++mindex; + } + // deallocates memory: + delete [] vertices; + delete [] normals; + delete [] VIndices; + delete [] NIndices; + + // Create the IndexedFaceSet with the retrieved attributes + IndexedFaceSet *rep; + rep = new IndexedFaceSet(cleanVertices, cvSize, + cleanNormals, cnSize, + marray, meshFrsMaterials.size(), + 0, 0, + numFaces, numVertexPerFaces, faceStyle, + cleanVIndices, viSize, + cleanNIndices, niSize, + MIndices, viSize, + 0,0, + 0); + // sets the id of the rep + rep->setId(Id(id, 0)); + + const BBox<Vec3r> bbox = BBox<Vec3r>(Vec3r(ls.minBBox[0], ls.minBBox[1], ls.minBBox[2]), + Vec3r(ls.maxBBox[0], ls.maxBBox[1], ls.maxBBox[2])); + rep->setBBox(bbox); + shape->AddRep(rep); + + Matrix44r meshMat = Matrix44r::identity(); + currentMesh->setMatrix(meshMat); + currentMesh->Translate(0,0,0); + + currentMesh->AddChild(shape); + _Scene->AddChild(currentMesh); + +} diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h new file mode 100644 index 00000000000..59fa5923b36 --- /dev/null +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h @@ -0,0 +1,84 @@ +#ifndef BLENDER_FILE_LOADER_H +# define BLENDER_FILE_LOADER_H + +# include <string.h> +# include <float.h> + +# include "../system/FreestyleConfig.h" +# include "../scene_graph/NodeGroup.h" +# include "../scene_graph/NodeTransform.h" +# include "../scene_graph/NodeShape.h" +# include "../scene_graph/IndexedFaceSet.h" +# include "../geometry/BBox.h" +# include "../geometry/Geom.h" +# include "../geometry/GeomCleaner.h" + +#ifdef __cplusplus +extern "C" { +#endif + + #include "DNA_material_types.h" + #include "DNA_scene_types.h" + #include "render_types.h" + #include "renderdatabase.h" + + #include "BKE_mesh.h" + #include "BKE_scene.h" + #include "BLI_math.h" + +#ifdef __cplusplus +} +#endif + + +class NodeGroup; + +struct LoaderState { + float *pv; + float *pn; + unsigned *pvi; + unsigned *pni; + unsigned *pmi; + unsigned currentIndex; + unsigned currentMIndex; + float minBBox[3]; + float maxBBox[3]; +}; + +class LIB_SCENE_GRAPH_EXPORT BlenderFileLoader +{ +public: + /*! Builds a MaxFileLoader */ + BlenderFileLoader(Render *re, SceneRenderLayer* srl); + virtual ~BlenderFileLoader(); + + /*! Loads the 3D scene and returns a pointer to the scene root node */ + NodeGroup * Load(); + + /*! Gets the number of read faces */ + inline unsigned int numFacesRead() {return _numFacesRead;} + + /*! Gets the smallest edge size read */ + inline real minEdgeSize() {return _minEdgeSize;} + +protected: + void insertShapeNode(ObjectRen *obr, int id); + int countClippedFaces(VertRen *v1, VertRen *v2, VertRen *v3, int clipped[3]); + void clipLine(VertRen *v1, VertRen *v2, float c[3], float z); + void clipTriangle(int numTris, float triCoords[][3], VertRen *v1, VertRen *v2, VertRen *v3, int clip[3]); + void addTriangle(struct LoaderState *state, float v1[3], float v2[3], float v3[3]); + +protected: + Render* _re; + SceneRenderLayer* _srl; + NodeGroup* _Scene; + unsigned _numFacesRead; + real _minEdgeSize; + float _viewplane_left; + float _viewplane_right; + float _viewplane_bottom; + float _viewplane_top; + float _z_near, _z_far; +}; + +#endif // BLENDER_FILE_LOADER_H diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp new file mode 100644 index 00000000000..30577287b72 --- /dev/null +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -0,0 +1,346 @@ +# include "BlenderStrokeRenderer.h" +# include "../stroke/Canvas.h" +# include "../application/AppConfig.h" + +# include "BlenderTextureManager.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "MEM_guardedalloc.h" + +#include "DNA_camera_types.h" +#include "DNA_customdata_types.h" +#include "DNA_listBase.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_screen_types.h" + +#include "BKE_customdata.h" +#include "BKE_global.h" +#include "BKE_library.h" /* free_libblock */ +#include "BKE_material.h" +#include "BKE_main.h" /* struct Main */ +#include "BKE_object.h" +#include "BKE_scene.h" + +#include "RE_pipeline.h" + +#ifdef __cplusplus +} +#endif + + +BlenderStrokeRenderer::BlenderStrokeRenderer(Render* re) +:StrokeRenderer(){ + + // TEMPORARY - need a texture manager + _textureManager = new BlenderTextureManager; + _textureManager->load(); + + // Scene.New("FreestyleStrokes") + old_scene = re->scene; + + objects.first = objects.last = NULL; + + ListBase lb; + freestyle_scene = add_scene("freestyle_strokes"); + lb = freestyle_scene->r.layers; + freestyle_scene->r= old_scene->r; + freestyle_scene->r.layers= lb; + set_scene_bg( freestyle_scene ); + + // image dimensions + float ycor = ((float)re->r.yasp) / ((float)re->r.xasp); + float width = freestyle_scene->r.xsch; + float height = freestyle_scene->r.ysch * ycor; + + // Camera + Object* object_camera = add_object(freestyle_scene, OB_CAMERA); + + Camera* camera = (Camera *) object_camera->data; + camera->type = CAM_ORTHO; + camera->ortho_scale = max(width,height); + camera->clipsta = 0.1f; + camera->clipend = 100.0f; + + _z_delta = 0.00001f; + _z = camera->clipsta + _z_delta; + + // test + //_z = 999.90f; _z_delta = 0.01f; + + object_camera->loc[0] = 0.5 * width; + object_camera->loc[1] = 0.5 * height; + object_camera->loc[2] = 1.0; + + freestyle_scene->camera = object_camera; + + store_object(object_camera); + + // Material + material = add_material("stroke_material"); + material->mode |= MA_VERTEXCOLP; + material->mode |= MA_TRANSP; + material->mode |= MA_SHLESS; + material->vcol_alpha = 1; +} + +BlenderStrokeRenderer::~BlenderStrokeRenderer(){ + + if(0 != _textureManager) + { + delete _textureManager; + _textureManager = 0; + } + + // release scene + free_libblock( &G.main->scene, freestyle_scene ); + + // release objects and data blocks + LinkData *link = (LinkData *)objects.first; + while(link) { + Object *ob = (Object *)link->data; + void *data = ob->data; + char name[24]; + strcpy(name, ob->id.name); + //cout << "removing " << name[0] << name[1] << ":" << (name+2) << endl; + switch (ob->type) { + case OB_MESH: + free_libblock( &G.main->object, ob ); + free_libblock( &G.main->mesh, data ); + break; + case OB_CAMERA: + free_libblock( &G.main->object, ob ); + free_libblock( &G.main->camera, data ); + break; + default: + cerr << "Warning: unexpected object in the scene: " << name[0] << name[1] << ":" << (name+2) << endl; + } + link = link->next; + } + BLI_freelistN( &objects ); + + // release material + free_libblock( &G.main->mat, material ); + + set_scene_bg( old_scene ); +} + +void BlenderStrokeRenderer::store_object(Object *ob) const { + + LinkData *link = (LinkData *)MEM_callocN(sizeof(LinkData), "temporary object" ); + link->data = ob; + BLI_addhead(const_cast<ListBase *>(&objects), link); +} + +float BlenderStrokeRenderer::get_stroke_vertex_z(void) const { + float z = _z; + BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this); + if (!(_z < _z_delta * 100000.0f)) + self->_z_delta *= 10.0f; + self->_z += _z_delta; + return -z; +} + +void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const{ + RenderStrokeRepBasic(iStrokeRep); +} + +void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const{ + + //////////////////// + // Build up scene + //////////////////// + + vector<Strip*>& strips = iStrokeRep->getStrips(); + Strip::vertex_container::iterator v[3]; + StrokeVertexRep *svRep[3]; + Vec3r color[3]; + unsigned int vertex_index; + float ycor = ((float)freestyle_scene->r.yasp) / ((float)freestyle_scene->r.xasp); + float width = freestyle_scene->r.xsch; + float height = freestyle_scene->r.ysch * ycor; + Vec2r p; + + for(vector<Strip*>::iterator s=strips.begin(), send=strips.end(); + s!=send; + ++s){ + + Strip::vertex_container& strip_vertices = (*s)->vertices(); + int strip_vertex_count = (*s)->sizeStrip(); + int m, n, visible_faces, visible_segments; + bool visible; + + // iterate over all vertices and count visible faces and strip segments + // (note: a strip segment is a series of visible faces, while two strip + // segments are separated by one or more invisible faces) + v[0] = strip_vertices.begin(); + v[1] = v[0]; ++(v[1]); + v[2] = v[1]; ++(v[2]); + visible_faces = visible_segments = 0; + visible = false; + for (n = 2; n < strip_vertex_count; n++) + { + svRep[0] = *(v[0]); + svRep[1] = *(v[1]); + svRep[2] = *(v[2]); + m = 0; + for (int j = 0; j < 3; j++) { + p = svRep[j]->point2d(); + if (p[0] < 0.0 || p[0] > width || p[1] < 0.0 || p[1] > height) + m++; + } + if (m == 3) { + visible = false; + } else { + visible_faces++; + if (!visible) + visible_segments++; + visible = true; + } + ++v[0]; ++v[1]; ++v[2]; + } + if (visible_faces == 0) + continue; + + // me = Mesh.New() + Object* object_mesh = add_object(freestyle_scene, OB_MESH); + Mesh* mesh = (Mesh *) object_mesh->data; + MEM_freeN(mesh->bb); + mesh->bb= NULL; + mesh->id.us = 0; + + store_object(object_mesh); + +#if 1 + // me.materials = [mat] + mesh->mat = ( Material ** ) MEM_mallocN( 1 * sizeof( Material * ), "MaterialList" ); + mesh->mat[0] = material; + mesh->totcol = 1; + test_object_materials( (ID*) mesh ); +#else + assign_material(object_mesh, material, object_mesh->totcol+1); + object_mesh->actcol= object_mesh->totcol; +#endif + + // vertices allocation + mesh->totvert = visible_faces + visible_segments * 2; + mesh->mvert = (MVert*) CustomData_add_layer( &mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert); + + // faces allocation + mesh->totface = visible_faces; + mesh->mface = (MFace*) CustomData_add_layer( &mesh->fdata, CD_MFACE, CD_CALLOC, NULL, mesh->totface); + + // colors allocation - me.vertexColors = True + mesh->mcol = (MCol *) CustomData_add_layer( &mesh->fdata, CD_MCOL, CD_CALLOC, NULL, mesh->totface ); + + //////////////////// + // Data copy + //////////////////// + + MVert* vertices = mesh->mvert; + MFace* faces = mesh->mface; + MCol* colors = mesh->mcol; + + v[0] = strip_vertices.begin(); + v[1] = v[0]; ++(v[1]); + v[2] = v[1]; ++(v[2]); + + vertex_index = 0; + visible = false; + + for (n = 2; n < strip_vertex_count; n++) + { + svRep[0] = *(v[0]); + svRep[1] = *(v[1]); + svRep[2] = *(v[2]); + m = 0; + for (int j = 0; j < 3; j++) { + p = svRep[j]->point2d(); + if (p[0] < 0.0 || p[0] > width || p[1] < 0.0 || p[1] > height) + m++; + } + if (m == 3) { + visible = false; + } else { + if (!visible) { + vertex_index += 2; + + // first vertex + vertices->co[0] = svRep[0]->point2d()[0]; + vertices->co[1] = svRep[0]->point2d()[1]; + vertices->co[2] = get_stroke_vertex_z(); + ++vertices; + + // second vertex + vertices->co[0] = svRep[1]->point2d()[0]; + vertices->co[1] = svRep[1]->point2d()[1]; + vertices->co[2] = get_stroke_vertex_z(); + ++vertices; + } + visible = true; + + // vertex + vertices->co[0] = svRep[2]->point2d()[0]; + vertices->co[1] = svRep[2]->point2d()[1]; + vertices->co[2] = get_stroke_vertex_z(); + + // faces + faces->v1 = vertex_index - 2; + faces->v2 = vertex_index - 1; + faces->v3 = vertex_index; + faces->v4 = 0; + + // colors + // red and blue are swapped - cf DNA_meshdata_types.h : MCol + color[0] = svRep[0]->color(); + color[1] = svRep[1]->color(); + color[2] = svRep[2]->color(); + + colors->r = (short)(255.0f*(color[0])[2]); + colors->g = (short)(255.0f*(color[0])[1]); + colors->b = (short)(255.0f*(color[0])[0]); + colors->a = (short)(255.0f*svRep[0]->alpha()); + ++colors; + + colors->r = (short)(255.0f*(color[1])[2]); + colors->g = (short)(255.0f*(color[1])[1]); + colors->b = (short)(255.0f*(color[1])[0]); + colors->a = (short)(255.0f*svRep[1]->alpha()); + ++colors; + + colors->r = (short)(255.0f*(color[2])[2]); + colors->g = (short)(255.0f*(color[2])[1]); + colors->b = (short)(255.0f*(color[2])[0]); + colors->a = (short)(255.0f*svRep[2]->alpha()); + ++colors; + + ++faces; ++vertices; ++colors; + ++vertex_index; + } + ++v[0]; ++v[1]; ++v[2]; + + } // loop over strip vertices + + } // loop over strips + +} + +Render* BlenderStrokeRenderer::RenderScene( Render *re ) { + Camera *camera = (Camera *)freestyle_scene->camera->data; + if (camera->clipend < _z) + camera->clipend = _z + _z_delta * 100.0f; + //cout << "clipsta " << camera->clipsta << ", clipend " << camera->clipend << endl; + + freestyle_scene->r.mode &= ~( R_EDGE_FRS | R_SHADOW | R_SSS | R_PANORAMA | R_ENVMAP | R_MBLUR ); + freestyle_scene->r.scemode &= ~( R_SINGLE_LAYER ); + freestyle_scene->r.planes = R_PLANES32; + freestyle_scene->r.imtype = R_PNG; + + Render *freestyle_render = RE_NewRender(freestyle_scene->id.name, RE_SLOT_DEFAULT); + + RE_BlenderFrame( freestyle_render, freestyle_scene, NULL, 1); + return freestyle_render; +} diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h new file mode 100644 index 00000000000..5bee116457d --- /dev/null +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h @@ -0,0 +1,48 @@ +#ifndef BLENDERSTROKERENDERER_H +# define BLENDERSTROKERENDERER_H + +# include "../system/FreestyleConfig.h" +# include "../stroke/StrokeRenderer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "render_types.h" + +#ifdef __cplusplus +} +#endif + + + +class LIB_STROKE_EXPORT BlenderStrokeRenderer : public StrokeRenderer +{ +public: + BlenderStrokeRenderer(Render *re); + virtual ~BlenderStrokeRenderer(); + + /*! Renders a stroke rep */ + virtual void RenderStrokeRep(StrokeRep *iStrokeRep) const; + virtual void RenderStrokeRepBasic(StrokeRep *iStrokeRep) const; + + Render* RenderScene(Render *re); + +protected: + Scene* old_scene; + Scene* freestyle_scene; + Material* material; + ListBase objects; + float _z, _z_delta; + + void store_object(Object *ob) const; + + float get_stroke_vertex_z(void) const; +}; + +#endif // BLENDERSTROKERENDERER_H + diff --git a/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.cpp b/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.cpp new file mode 100644 index 00000000000..d731af42d0e --- /dev/null +++ b/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.cpp @@ -0,0 +1,71 @@ +#include "BlenderTextureManager.h" + + +BlenderTextureManager::BlenderTextureManager () +: TextureManager() +{ + //_brushes_path = Config::getInstance()... +} + +BlenderTextureManager::~BlenderTextureManager () +{ +} + +void BlenderTextureManager::loadStandardBrushes() +{ + // getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/oil.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/oilnoblend.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::DRY_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::DRY_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueDryBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM); + //_defaultTextureId = getBrushTextureIndex("smoothAlpha.bmp", Stroke::OPAQUE_MEDIUM); +} + + +unsigned +BlenderTextureManager::loadBrush(string sname, Stroke::MediumType mediumType) +{ +// GLuint texId; +// glGenTextures(1, &texId); +// bool found = false; +// vector<string> pathnames; +// string path; //soc +// StringUtils::getPathName(TextureManager::Options::getBrushesPath(), +// sname, +// pathnames); +// for (vector<string>::const_iterator j = pathnames.begin(); j != pathnames.end(); j++) { +// path = j->c_str(); +// //soc if(QFile::exists(path)){ +// if( BLI_exists( const_cast<char *>(path.c_str()) ) ) { +// found = true; +// break; +// } +// } +// if(!found) +// return 0; +// // Brush texture +// cout << "Loading brush texture..." << endl; +// switch(mediumType){ +// case Stroke::DRY_MEDIUM: +// //soc prepareTextureLuminance((const char*)path.toAscii(), texId); +// prepareTextureLuminance(StringUtils::toAscii(path), texId); +// break; +// case Stroke::HUMID_MEDIUM: +// case Stroke::OPAQUE_MEDIUM: +// default: +// //soc prepareTextureAlpha((const char*)path.toAscii(), texId); +// prepareTextureAlpha(StringUtils::toAscii(path), texId); +// break; +// } +// cout << "Done." << endl << endl; +// +// return texId; +// + return 0; +} + + + diff --git a/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h b/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h new file mode 100644 index 00000000000..d49ab9cf008 --- /dev/null +++ b/source/blender/freestyle/intern/blender_interface/BlenderTextureManager.h @@ -0,0 +1,23 @@ +#ifndef BLENDERTEXTUREMANAGER_H +#define BLENDERTEXTUREMANAGER_H + +# include "../system/FreestyleConfig.h" +# include "../stroke/StrokeRenderer.h" +# include "../stroke/StrokeRep.h" + +/*! Class to load textures + */ +class LIB_RENDERING_EXPORT BlenderTextureManager : public TextureManager +{ + public: + BlenderTextureManager (); + virtual ~BlenderTextureManager (); +protected: + virtual unsigned loadBrush(string fileName, Stroke::MediumType = Stroke::OPAQUE_MEDIUM); + + protected: + virtual void loadStandardBrushes(); + +}; + +#endif // BLENDERTEXTUREMANAGER_H diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp new file mode 100644 index 00000000000..0ea3280c1bc --- /dev/null +++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp @@ -0,0 +1,340 @@ +#include "../application/AppView.h" +#include "../application/Controller.h" +#include "../application/AppConfig.h" +#include "../application/AppCanvas.h" + +#include <iostream> +#include <map> +#include <set> +using namespace std; + +#ifdef __cplusplus +extern "C" { +#endif + +#include "MEM_guardedalloc.h" + +#include "DNA_camera_types.h" +#include "DNA_freestyle_types.h" + +#include "BKE_main.h" +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BPY_extern.h" + +#include "renderpipeline.h" +#include "pixelblending.h" + +#include "../../FRS_freestyle.h" +#include "../../FRS_freestyle_config.h" + + // Freestyle configuration + static short freestyle_is_initialized = 0; + static Config::Path *pathconfig = NULL; + static Controller *controller = NULL; + static AppView *view = NULL; + + // camera information + float freestyle_viewpoint[3]; + float freestyle_mv[4][4]; + float freestyle_proj[4][4]; + int freestyle_viewport[4]; + + // current scene + Scene *freestyle_scene; + + string default_module_path; + + //======================================================= + // Initialization + //======================================================= + + void FRS_initialize() { + + if( freestyle_is_initialized ) + return; + + pathconfig = new Config::Path; + controller = new Controller(); + view = new AppView; + controller->setView(view); + freestyle_scene = NULL; + + default_module_path = pathconfig->getProjectDir() + Config::DIR_SEP + "style_modules" + Config::DIR_SEP + "contour.py"; + + freestyle_is_initialized = 1; + } + + void FRS_set_context(bContext* C) { + cout << "FRS_set_context: context 0x" << C << " scene 0x" << CTX_data_scene(C) << endl; + controller->setContext(C); + } + + void FRS_exit() { + delete pathconfig; + delete controller; + delete view; + } + + //======================================================= + // Rendering + //======================================================= + + void init_view(Render* re){ + float ycor = ((float)re->r.yasp) / ((float)re->r.xasp); + int width = re->r.xsch; + int height = (int)(((float)re->r.ysch) * ycor); + + freestyle_viewport[0] = freestyle_viewport[1] = 0; + freestyle_viewport[2] = width; + freestyle_viewport[3] = height; + + view->setWidth( width ); + view->setHeight( height ); + } + + void init_camera(Render* re){ + // It is assumed that imported meshes are in the camera coordinate system. + // Therefore, the view point (i.e., camera position) is at the origin, and + // the the model-view matrix is simply the identity matrix. + + freestyle_viewpoint[0] = 0.0; + freestyle_viewpoint[1] = 0.0; + freestyle_viewpoint[2] = 0.0; + + for( int i = 0; i < 4; i++ ) + for( int j = 0; j < 4; j++ ) + freestyle_mv[i][j] = (i == j) ? 1.0 : 0.0; + + for( int i = 0; i < 4; i++ ) + for( int j = 0; j < 4; j++ ) + freestyle_proj[i][j] = re->winmat[i][j]; + + //print_m4("mv", freestyle_mv); + //print_m4("proj", freestyle_proj); + } + + + void prepare(Render* re, SceneRenderLayer* srl ) { + + // clear canvas + controller->Clear(); + + // load mesh + re->i.infostr= "Freestyle: Mesh loading"; + re->stats_draw(re->sdh, &re->i); + re->i.infostr= NULL; + if( controller->LoadMesh(re, srl) ) // returns if scene cannot be loaded or if empty + return; + if( re->test_break(re->tbh) ) + return; + + // add style modules + FreestyleConfig* config = &srl->freestyleConfig; + + cout << "\n=== Rendering options ===" << endl; + cout << "Modules :"<< endl; + int layer_count = 0; + + + for( FreestyleModuleConfig* module_conf = (FreestyleModuleConfig *)config->modules.first; module_conf; module_conf = module_conf->next ) { + if( module_conf->is_displayed ) { + cout << " " << layer_count+1 << ": " << module_conf->module_path << endl; + controller->InsertStyleModule( layer_count, module_conf->module_path ); + controller->toggleLayer(layer_count, true); + layer_count++; + } + } + cout << endl; + + // set parameters + controller->setSphereRadius( config->sphere_radius ); + controller->setComputeRidgesAndValleysFlag( (config->flags & FREESTYLE_RIDGES_AND_VALLEYS_FLAG) ? true : false); + controller->setComputeSuggestiveContoursFlag( (config->flags & FREESTYLE_SUGGESTIVE_CONTOURS_FLAG) ? true : false); + controller->setSuggestiveContourKrDerivativeEpsilon( config->dkr_epsilon ) ; + + cout << "Sphere radius : " << controller->getSphereRadius() << endl; + cout << "Redges and valleys : " << (controller->getComputeRidgesAndValleysFlag() ? "enabled" : "disabled") << endl; + cout << "Suggestive contours : " << (controller->getComputeSuggestiveContoursFlag() ? "enabled" : "disabled") << endl; + cout << "Suggestive contour dkr epsilon : " << controller->getSuggestiveContourKrDerivativeEpsilon() << endl; + cout << endl; + + // set diffuse and z depth passes + RenderLayer *rl = RE_GetRenderLayer(re->result, srl->name); + bool diffuse = false, z = false; + for (RenderPass *rpass = (RenderPass *)rl->passes.first; rpass; rpass = rpass->next) { + switch (rpass->passtype) { + case SCE_PASS_DIFFUSE: + controller->setPassDiffuse(rpass->rect, rpass->rectx, rpass->recty); + diffuse = true; + break; + case SCE_PASS_Z: + controller->setPassZ(rpass->rect, rpass->rectx, rpass->recty); + z = true; + break; + } + } + cout << "Passes :" << endl; + cout << " Diffuse = " << (diffuse ? "enabled" : "disabled") << endl; + cout << " Z = " << (z ? "enabled" : "disabled") << endl; + + // compute view map + re->i.infostr= "Freestyle: View map creation"; + re->stats_draw(re->sdh, &re->i); + re->i.infostr= NULL; + controller->ComputeViewMap(); + } + + void composite_result(Render* re, SceneRenderLayer* srl, Render* freestyle_render) + { + + RenderLayer *rl; + float *src, *dest, *pixSrc, *pixDest; + int x, y, rectx, recty; + + if( freestyle_render == NULL || freestyle_render->result == NULL ) + return; + + rl = render_get_active_layer( freestyle_render, freestyle_render->result ); + if( !rl || rl->rectf == NULL) { cout << "Cannot find Freestyle result image" << endl; return; } + src = rl->rectf; + //cout << "src: " << rl->rectx << " x " << rl->recty << endl; + + rl = RE_GetRenderLayer(re->result, srl->name); + if( !rl || rl->rectf == NULL) { cout << "No layer to composite to" << endl; return; } + dest = rl->rectf; + //cout << "dest: " << rl->rectx << " x " << rl->recty << endl; + + rectx = re->rectx; + recty = re->recty; + + for( y = 0; y < recty; y++) { + for( x = 0; x < rectx; x++) { + + pixSrc = src + 4 * (rectx * y + x); + if( pixSrc[3] > 0.0) { + pixDest = dest + 4 * (rectx * y + x); + addAlphaOverFloat(pixDest, pixSrc); + } + } + } + + } + + int displayed_layer_count( SceneRenderLayer* srl ) { + int count = 0; + + for( FreestyleModuleConfig* module_conf = (FreestyleModuleConfig *)srl->freestyleConfig.modules.first; module_conf; module_conf = module_conf->next ) { + if( module_conf->is_displayed ) + count++; + } + return count; + } + + void FRS_add_Freestyle(Render* re) { + + SceneRenderLayer *srl; + Render* freestyle_render = NULL; + + // init + cout << "\n#===============================================================" << endl; + cout << "# Freestyle" << endl; + cout << "#===============================================================" << endl; + + init_view(re); + init_camera(re); + freestyle_scene = re->scene; + + for(srl= (SceneRenderLayer *)re->scene->r.layers.first; srl; srl= srl->next) { + if( !(srl->layflag & SCE_LAY_DISABLE) && + srl->layflag & SCE_LAY_FRS && + displayed_layer_count(srl) > 0 ) + { + cout << "\n----------------------------------------------------------" << endl; + cout << "| " << (re->scene->id.name+2) << "|" << srl->name << endl; + cout << "----------------------------------------------------------" << endl; + + // prepare Freestyle: + // - clear canvas + // - load mesh + // - add style modules + // - set parameters + // - compute view map + prepare(re, srl); + + if( re->test_break(re->tbh) ) { + controller->CloseFile(); + break; + } + + // render and composite Freestyle result + if( controller->_ViewMap ) { + + // render strokes + re->i.infostr= "Freestyle: Stroke rendering"; + re->stats_draw(re->sdh, &re->i); + re->i.infostr= NULL; + controller->DrawStrokes(); + freestyle_render = controller->RenderStrokes(re); + controller->CloseFile(); + + // composite result + composite_result(re, srl, freestyle_render); + + // free resources + RE_FreeRender(freestyle_render); + } + } + } + + freestyle_scene = NULL; + } + + //======================================================= + // Freestyle Panel Configuration + //======================================================= + + void FRS_add_freestyle_config( SceneRenderLayer* srl ) + { + FreestyleConfig* config = &srl->freestyleConfig; + + config->modules.first = config->modules.last = NULL; + config->flags = 0; + config->sphere_radius = 1.0; + config->dkr_epsilon = 0.001; + } + + void FRS_free_freestyle_config( SceneRenderLayer* srl ) + { + BLI_freelistN( &srl->freestyleConfig.modules ); + } + + void FRS_add_module(FreestyleConfig *config) + { + FreestyleModuleConfig* module_conf = (FreestyleModuleConfig*) MEM_callocN( sizeof(FreestyleModuleConfig), "style module configuration"); + BLI_addtail(&config->modules, (void*) module_conf); + + strcpy( module_conf->module_path, default_module_path.c_str() ); + module_conf->is_displayed = 1; + } + + void FRS_delete_module(FreestyleConfig *config, FreestyleModuleConfig *module_conf) + { + BLI_freelinkN(&config->modules, module_conf); + } + + void FRS_move_up_module(FreestyleConfig *config, FreestyleModuleConfig *module_conf) + { + BLI_remlink(&config->modules, module_conf); + BLI_insertlink(&config->modules, module_conf->prev->prev, module_conf); + } + + void FRS_move_down_module(FreestyleConfig *config, FreestyleModuleConfig *module_conf) + { + BLI_remlink(&config->modules, module_conf); + BLI_insertlink(&config->modules, module_conf->next, module_conf); + } + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/geometry/BBox.h b/source/blender/freestyle/intern/geometry/BBox.h new file mode 100755 index 00000000000..9c46d7918e2 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/BBox.h @@ -0,0 +1,141 @@ +// +// Filename : BBox.h +// Author(s) : Stephane Grabli +// Purpose : A class to hold a bounding box +// Date of creation : 22/05/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BBOX_H +# define BBOX_H + +template <class Point> +class BBox +{ + public: + + inline BBox() { + _empty = true; + } + + template <class T> + inline BBox(const T& min_in, const T& max_in) : _min(min_in), _max(max_in) { + _empty = false; + } + + template <class T> + inline BBox(const BBox<T>& b) : _min(b.getMin()), _max(b.getMax()) { + _empty = false; + } + + template <class T> + inline void extendToContain(const T& p) { + if (_empty) { + _min = p; + _max = p; + _empty = false; + return; + } + for (unsigned i = 0; i < Point::dim(); i++) { + if (p[i] < _min[i]) + _min[i] = p[i]; + else if (p[i] > _max[i]) + _max[i] = p[i]; + } + _empty = false; + } + + inline void clear() { + _empty = true; + } + + inline bool empty() const { + return _empty; + } + + inline const Point& getMin() const { + return _min; + } + + inline const Point& getMax() const { + return _max; + } + + inline BBox<Point>& operator=(const BBox<Point>& b) { + _min = b.getMin(); + _max = b.getMax(); + _empty = false; + return *this; + } + + inline BBox<Point>& operator+=(const BBox<Point>& b) { + if (_empty) { + _min = b.getMin(); + _max = b.getMax(); + _empty = false; + } + else { + for (unsigned i = 0; i < Point::dim(); i++) { + if (b.getMin()[i] < _min[i]) + _min[i] = b.getMin()[i]; + if (b.getMax()[i] > _max[i]) + _max[i] = b.getMax()[i]; + } + } + return *this; + } + + inline bool inside(const Point& p){ + if(empty()) + return false; + for (unsigned i = 0; i < Point::dim(); i++) { + if((_min[i]>p[i]) || (_max[i]<p[i])) + return false; + } + return true; + + } + +private: + + Point _min; + Point _max; + bool _empty; +}; + +template <class Point> +BBox<Point>& operator+(const BBox<Point> &b1, const BBox<Point> &b2) +{ + Point new_min; + Point new_max; + + for (unsigned i = 0; i < Point::dim(); i++) { + new_min[i] = b1.getMin()[i] < b2.getMin()[i] ? b1.getMin()[i] : b2.getMin()[i]; + new_max[i] = b1.getMax()[i] > b2.getMax()[i] ? b1.getMax()[i] : b2.getMax()[i]; + } + + return BBox<Point>(new_min, new_max); +} + +#endif // BBOX_H diff --git a/source/blender/freestyle/intern/geometry/Bezier.cpp b/source/blender/freestyle/intern/geometry/Bezier.cpp new file mode 100755 index 00000000000..8f9771f29d3 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/Bezier.cpp @@ -0,0 +1,118 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "Bezier.h" +#include "FitCurve.h" + +using namespace std; + +BezierCurveSegment::BezierCurveSegment() +{ +} + +BezierCurveSegment::~BezierCurveSegment() +{ +} + +void BezierCurveSegment::AddControlPoint(const Vec2d& iPoint) +{ + _ControlPolygon.push_back(iPoint); + if(_ControlPolygon.size() == 4) + Build(); +} + +void BezierCurveSegment::Build() +{ + if(_ControlPolygon.size() != 4) + return; + + // Compute the rightmost part of the matrix: + vector<Vec2d>::const_iterator p0,p1,p2,p3; + p0 = _ControlPolygon.begin(); + p1 = p0;++p1; + p2 = p1;++p2; + p3 = p2;++p3; + float x[4], y[4]; + + x[0] = -p0->x()+3*p1->x()-3*p2->x()+p3->x(); + x[1] = 3*p0->x()-6*p1->x()+3*p2->x(); + x[2] = -3*p0->x()+3*p1->x(); + x[3] = p0->x(); + + y[0] = -p0->y()+3*p1->y()-3*p2->y()+p3->y(); + y[1] = 3*p0->y()-6*p1->y()+3*p2->y(); + y[2] = -3*p0->y()+3*p1->y(); + y[3] = p0->y(); + + int nvertices = 12; + float increment = 1.0/(float)nvertices; + float t = 0.f; + for(int i=0; i<=nvertices; ++i) + { + _Vertices.push_back(Vec2d((x[3] + t*(x[2] + t*(x[1] + t*x[0]))), + (y[3] + t*(y[2] + t*(y[1] + t*y[0]))))); + t+=increment; + } +} + +BezierCurve::BezierCurve() +{ + _currentSegment = new BezierCurveSegment; +} + +BezierCurve::BezierCurve(vector<Vec2d>& iPoints, double error) +{ + FitCurveWrapper fitcurve; + _currentSegment = new BezierCurveSegment; + vector<Vec2d> curve; + + fitcurve.FitCurve(iPoints, curve, error); + int i=0; + vector<Vec2d>::iterator v,vend; + for(v=curve.begin(),vend=curve.end(); + v!=vend; + ++v) + { + if((i == 0) || (i%4 != 0)) + AddControlPoint(*v); + ++i; + } +} + +BezierCurve::~BezierCurve() +{ + if(_currentSegment) + delete _currentSegment; +} + +void BezierCurve::AddControlPoint(const Vec2d& iPoint) +{ + _ControlPolygon.push_back(iPoint); + _currentSegment->AddControlPoint(iPoint); + if(_currentSegment->size() == 4) + { + _Segments.push_back(_currentSegment); + _currentSegment = new BezierCurveSegment; + _currentSegment->AddControlPoint(iPoint); + } +} + + diff --git a/source/blender/freestyle/intern/geometry/Bezier.h b/source/blender/freestyle/intern/geometry/Bezier.h new file mode 100755 index 00000000000..acae71bbb2c --- /dev/null +++ b/source/blender/freestyle/intern/geometry/Bezier.h @@ -0,0 +1,73 @@ +// +// Filename : Bezier.h +// Author(s) : Stephane Grabli +// Purpose : Class to define a Bezier curve of order 4. +// Date of creation : 04/06/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BEZIER_H +# define BEZIER_H + +#include <vector> +#include "../system/FreestyleConfig.h" +#include "Geom.h" + +using namespace Geometry; + +class LIB_GEOMETRY_EXPORT BezierCurveSegment +{ +private: + std::vector<Vec2d> _ControlPolygon; + std::vector<Vec2d> _Vertices; + +public: + BezierCurveSegment(); + virtual ~BezierCurveSegment(); + + void AddControlPoint(const Vec2d& iPoint); + void Build(); + inline int size() const {return _ControlPolygon.size();} + inline std::vector<Vec2d>& vertices() {return _Vertices;} +}; + + +class LIB_GEOMETRY_EXPORT BezierCurve +{ +private: + std::vector<Vec2d> _ControlPolygon; + std::vector<BezierCurveSegment*> _Segments; + BezierCurveSegment *_currentSegment; + +public: + BezierCurve(); + BezierCurve(std::vector<Vec2d>& iPoints, double error=4.0); + virtual ~BezierCurve(); + + void AddControlPoint(const Vec2d& iPoint); + std::vector<Vec2d>& controlPolygon() {return _ControlPolygon;} + std::vector<BezierCurveSegment*>& segments() {return _Segments;} +}; + +#endif // BEZIER_H diff --git a/source/blender/freestyle/intern/geometry/FastGrid.cpp b/source/blender/freestyle/intern/geometry/FastGrid.cpp new file mode 100755 index 00000000000..325126b4b96 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/FastGrid.cpp @@ -0,0 +1,62 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "FastGrid.h" + +void FastGrid::clear() { + if(!_cells) + return; + + for(unsigned i = 0; i < _cells_size; i++) + if (_cells[i]) + delete _cells[i]; + delete[] _cells; + _cells = NULL; + _cells_size = 0; + + Grid::clear(); +} + +void FastGrid::configure(const Vec3r& orig, const Vec3r& size, unsigned nb) { + Grid::configure(orig, size, nb); + _cells_size = _cells_nb[0] * _cells_nb[1] * _cells_nb[2]; + _cells = new Cell*[_cells_size]; + memset(_cells, 0, _cells_size * sizeof(*_cells)); +} + +Cell* FastGrid::getCell(const Vec3u& p) { + //cout << _cells<< " "<< p << " " <<_cells_nb[0]<<"-"<< _cells_nb[1]<<"-"<< _cells_nb[2]<< " "<<_cells_size<< endl; + assert(_cells||("_cells is a null pointer")); + assert((_cells_nb[0] * (p[2] * _cells_nb[1] + p[1]) + p[0])<_cells_size); + assert(p[0]<_cells_nb[0]); + assert(p[1]<_cells_nb[1]); + assert(p[2]<_cells_nb[2]); + return _cells[_cells_nb[0] * (p[2] * _cells_nb[1] + p[1]) + p[0]]; +} + +void FastGrid::fillCell(const Vec3u& p, Cell& cell) { + assert(_cells||("_cells is a null pointer")); + assert((_cells_nb[0] * (p[2] * _cells_nb[1] + p[1]) + p[0])<_cells_size); + assert(p[0]<_cells_nb[0]); + assert(p[1]<_cells_nb[1]); + assert(p[2]<_cells_nb[2]); + _cells[_cells_nb[0] * (p[2] * _cells_nb[1] + p[1]) + p[0]] = &cell; +} diff --git a/source/blender/freestyle/intern/geometry/FastGrid.h b/source/blender/freestyle/intern/geometry/FastGrid.h new file mode 100755 index 00000000000..e620ff24385 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/FastGrid.h @@ -0,0 +1,85 @@ +// +// Filename : FastGrid.h +// Author(s) : Stephane Grabli +// Purpose : Class to define a cell grid surrounding the +// bounding box of the scene +// Date of creation : 30/07/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef FASTGRID_H +# define FASTGRID_H + +# include "Grid.h" +# include <cassert> +/*! Class to define a regular grid used for ray + * casting computations + * We don't use a hashtable here. The grid is + * explicitly stored for faster computations. + * However, this might result in significant + * increase in memory usage (compared to the regular grid) + */ + +class LIB_GEOMETRY_EXPORT FastGrid : public Grid +{ + public: + + FastGrid() : Grid() { + _cells = NULL; + _cells_size = 0; + } + + virtual ~FastGrid() { + clear(); + } + + /*! clears the grid + * Deletes all the cells, clears the hashtable, + * resets size, size of cell, number of cells. + */ + virtual void clear(); + + /*! Sets the different parameters of the grid + * orig + * The grid origin + * size + * The grid's dimensions + * nb + * The number of cells of the grid + */ + virtual void configure(const Vec3r& orig, const Vec3r& size, unsigned nb); + + /*! returns the cell whose coordinates are pased as argument */ + Cell* getCell(const Vec3u& p) ; + + /*! Fills the case p with the cell iCell */ + virtual void fillCell(const Vec3u& p, Cell& cell); + +protected: + + Cell** _cells; + unsigned _cells_size; +}; + +#endif // FASTGRID_H diff --git a/source/blender/freestyle/intern/geometry/FitCurve.cpp b/source/blender/freestyle/intern/geometry/FitCurve.cpp new file mode 100755 index 00000000000..7754fcda32b --- /dev/null +++ b/source/blender/freestyle/intern/geometry/FitCurve.cpp @@ -0,0 +1,603 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <cstdlib> // for malloc and free +#include <stdio.h> +#include <math.h> +#include "FitCurve.h" + +using namespace std; + +typedef Vector2 *BezierCurve; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Forward declarations */ +static double *Reparameterize(Vector2 *d, int first, int last, double *u, BezierCurve bezCurve); +static double NewtonRaphsonRootFind(BezierCurve Q, Vector2 P, double u); +static Vector2 BezierII(int degree, Vector2 *V, double t); +static double B0(double u); +static double B1(double u); +static double B2(double u); +static double B3(double u); +static Vector2 ComputeLeftTangent(Vector2 *d, int end); +static Vector2 ComputeLeftTangent(Vector2 *d, int end); +static Vector2 ComputeLeftTangent(Vector2 *d, int end); +static double ComputeMaxError(Vector2 *d, int first, int last, BezierCurve bezCurve, double *u, int *splitPoint); +static double *ChordLengthParameterize(Vector2 *d, int first, int last); +static BezierCurve GenerateBezier(Vector2 *d, int first, int last, double *uPrime, Vector2 tHat1, Vector2 tHat2); +static Vector2 V2AddII(Vector2 a, Vector2 b); +static Vector2 V2ScaleIII(Vector2 v, double s); +static Vector2 V2SubII(Vector2 a, Vector2 b); + + +#define MAXPOINTS 1000 /* The most points you can have */ + +/* returns squared length of input vector */ +double V2SquaredLength(Vector2 *a) +{ return(((*a)[0] * (*a)[0])+((*a)[1] * (*a)[1])); +} + +/* returns length of input vector */ +double V2Length(Vector2 *a) +{ + return(sqrt(V2SquaredLength(a))); +} + +Vector2 *V2Scale(Vector2 *v, double newlen) +{ + double len = V2Length(v); + if (len != 0.0) { (*v)[0] *= newlen/len; (*v)[1] *= newlen/len; } + return(v); +} + +/* return the dot product of vectors a and b */ +double V2Dot(Vector2 *a, Vector2 *b) +{ + return(((*a)[0]*(*b)[0])+((*a)[1]*(*b)[1])); +} + +/* return the distance between two points */ +double V2DistanceBetween2Points(Vector2 *a, Vector2 *b) +{ +double dx = (*a)[0] - (*b)[0]; +double dy = (*a)[1] - (*b)[1]; + return(sqrt((dx*dx)+(dy*dy))); +} + +/* return vector sum c = a+b */ +Vector2 *V2Add(Vector2 *a, Vector2 *b, Vector2 *c) +{ + (*c)[0] = (*a)[0]+(*b)[0]; (*c)[1] = (*a)[1]+(*b)[1]; + return(c); +} + +/* normalizes the input vector and returns it */ +Vector2 *V2Normalize(Vector2 *v) +{ +double len = V2Length(v); + if (len != 0.0) { (*v)[0] /= len; (*v)[1] /= len; } + return(v); +} + +/* negates the input vector and returns it */ +Vector2 *V2Negate(Vector2 *v) +{ + (*v)[0] = -(*v)[0]; (*v)[1] = -(*v)[1]; + return(v); +} + + +/* + * GenerateBezier : + * Use least-squares method to find Bezier control points for region. + * + */ +static BezierCurve GenerateBezier(Vector2 *d, int first, int last, double *uPrime, Vector2 tHat1, Vector2 tHat2) +// Vector2 *d; /* Array of digitized points */ +// int first, last; /* Indices defining region */ +// double *uPrime; /* Parameter values for region */ +// Vector2 tHat1, tHat2; /* Unit tangents at endpoints */ +{ + int i; + Vector2 A[MAXPOINTS][2]; /* Precomputed rhs for eqn */ + int nPts; /* Number of pts in sub-curve */ + double C[2][2]; /* Matrix C */ + double X[2]; /* Matrix X */ + double det_C0_C1, /* Determinants of matrices */ + det_C0_X, + det_X_C1; + double alpha_l, /* Alpha values, left and right */ + alpha_r; + Vector2 tmp; /* Utility variable */ + BezierCurve bezCurve; /* RETURN bezier curve ctl pts */ + + bezCurve = (Vector2 *)malloc(4 * sizeof(Vector2)); + nPts = last - first + 1; + + + /* Compute the A's */ + for (i = 0; i < nPts; i++) { + Vector2 v1, v2; + v1 = tHat1; + v2 = tHat2; + V2Scale(&v1, B1(uPrime[i])); + V2Scale(&v2, B2(uPrime[i])); + A[i][0] = v1; + A[i][1] = v2; + } + + /* Create the C and X matrices */ + C[0][0] = 0.0; + C[0][1] = 0.0; + C[1][0] = 0.0; + C[1][1] = 0.0; + X[0] = 0.0; + X[1] = 0.0; + + for (i = 0; i < nPts; i++) { + C[0][0] += V2Dot(&A[i][0], &A[i][0]); + C[0][1] += V2Dot(&A[i][0], &A[i][1]); +/* C[1][0] += V2Dot(&A[i][0], &A[i][1]);*/ + C[1][0] = C[0][1]; + C[1][1] += V2Dot(&A[i][1], &A[i][1]); + + tmp = V2SubII(d[first + i], + V2AddII( + V2ScaleIII(d[first], B0(uPrime[i])), + V2AddII( + V2ScaleIII(d[first], B1(uPrime[i])), + V2AddII( + V2ScaleIII(d[last], B2(uPrime[i])), + V2ScaleIII(d[last], B3(uPrime[i])))))); + + + X[0] += V2Dot(&((A[i])[0]), &tmp); + X[1] += V2Dot(&((A[i])[1]), &tmp); + } + + /* Compute the determinants of C and X */ + det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1]; + det_C0_X = C[0][0] * X[1] - C[0][1] * X[0]; + det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1]; + + /* Finally, derive alpha values */ + if (det_C0_C1 == 0.0) { + det_C0_C1 = (C[0][0] * C[1][1]) * 10e-12; + } + alpha_l = det_X_C1 / det_C0_C1; + alpha_r = det_C0_X / det_C0_C1; + + + /* If alpha negative, use the Wu/Barsky heuristic (see text) */ + /* (if alpha is 0, you get coincident control points that lead to + * divide by zero in any subsequent NewtonRaphsonRootFind() call. */ + if (alpha_l < 1.0e-6 || alpha_r < 1.0e-6) { + double dist = V2DistanceBetween2Points(&d[last], &d[first]) / + 3.0; + + bezCurve[0] = d[first]; + bezCurve[3] = d[last]; + V2Add(&(bezCurve[0]), V2Scale(&(tHat1), dist), &(bezCurve[1])); + V2Add(&(bezCurve[3]), V2Scale(&(tHat2), dist), &(bezCurve[2])); + return (bezCurve); + } + + /* First and last control points of the Bezier curve are */ + /* positioned exactly at the first and last data points */ + /* Control points 1 and 2 are positioned an alpha distance out */ + /* on the tangent vectors, left and right, respectively */ + bezCurve[0] = d[first]; + bezCurve[3] = d[last]; + V2Add(&bezCurve[0], V2Scale(&tHat1, alpha_l), &bezCurve[1]); + V2Add(&bezCurve[3], V2Scale(&tHat2, alpha_r), &bezCurve[2]); + return (bezCurve); +} + + +/* + * Reparameterize: + * Given set of points and their parameterization, try to find + * a better parameterization. + * + */ +static double *Reparameterize(Vector2 *d, int first, int last, double *u, BezierCurve bezCurve) +// Vector2 *d; /* Array of digitized points */ +// int first, last; /* Indices defining region */ +// double *u; /* Current parameter values */ +// BezierCurve bezCurve; /* Current fitted curve */ +{ + int nPts = last-first+1; + int i; + double *uPrime; /* New parameter values */ + + uPrime = (double *)malloc(nPts * sizeof(double)); + for (i = first; i <= last; i++) { + uPrime[i-first] = NewtonRaphsonRootFind(bezCurve, d[i], u[i- + first]); + } + return (uPrime); +} + + + +/* + * NewtonRaphsonRootFind : + * Use Newton-Raphson iteration to find better root. + */ +static double NewtonRaphsonRootFind(BezierCurve Q, Vector2 P, double u) +// BezierCurve Q; /* Current fitted curve */ +// Vector2 P; /* Digitized point */ +// double u; /* Parameter value for "P" */ +{ + double numerator, denominator; + Vector2 Q1[3], Q2[2]; /* Q' and Q'' */ + Vector2 Q_u, Q1_u, Q2_u; /*u evaluated at Q, Q', & Q'' */ + double uPrime; /* Improved u */ + int i; + + /* Compute Q(u) */ + Q_u = BezierII(3, Q, u); + + /* Generate control vertices for Q' */ + for (i = 0; i <= 2; i++) { + Q1[i][0] = (Q[i+1][0] - Q[i][0]) * 3.0; + Q1[i][1] = (Q[i+1][1] - Q[i][1]) * 3.0; + } + + /* Generate control vertices for Q'' */ + for (i = 0; i <= 1; i++) { + Q2[i][0] = (Q1[i+1][0] - Q1[i][0]) * 2.0; + Q2[i][1] = (Q1[i+1][1] - Q1[i][1]) * 2.0; + } + + /* Compute Q'(u) and Q''(u) */ + Q1_u = BezierII(2, Q1, u); + Q2_u = BezierII(1, Q2, u); + + /* Compute f(u)/f'(u) */ + numerator = (Q_u[0] - P[0]) * (Q1_u[0]) + (Q_u[1] - P[1]) * (Q1_u[1]); + denominator = (Q1_u[0]) * (Q1_u[0]) + (Q1_u[1]) * (Q1_u[1]) + + (Q_u[0] - P[0]) * (Q2_u[0]) + (Q_u[1] - P[1]) * (Q2_u[1]); + + /* u = u - f(u)/f'(u) */ + if(denominator == 0) // FIXME + return u; + uPrime = u - (numerator/denominator); + return (uPrime); +} + + + +/* + * Bezier : + * Evaluate a Bezier curve at a particular parameter value + * + */ +static Vector2 BezierII(int degree, Vector2 *V, double t) +// int degree; /* The degree of the bezier curve */ +// Vector2 *V; /* Array of control points */ +// double t; /* Parametric value to find point for */ +{ + int i, j; + Vector2 Q; /* Point on curve at parameter t */ + Vector2 *Vtemp; /* Local copy of control points */ + + /* Copy array */ + Vtemp = (Vector2 *)malloc((unsigned)((degree+1) + * sizeof (Vector2))); + for (i = 0; i <= degree; i++) { + Vtemp[i] = V[i]; + } + + /* Triangle computation */ + for (i = 1; i <= degree; i++) { + for (j = 0; j <= degree-i; j++) { + Vtemp[j][0] = (1.0 - t) * Vtemp[j][0] + t * Vtemp[j+1][0]; + Vtemp[j][1] = (1.0 - t) * Vtemp[j][1] + t * Vtemp[j+1][1]; + } + } + + Q = Vtemp[0]; + free((void *)Vtemp); + return Q; +} + + +/* + * B0, B1, B2, B3 : + * Bezier multipliers + */ +static double B0(double u) +{ + double tmp = 1.0 - u; + return (tmp * tmp * tmp); +} + + +static double B1(double u) +{ + double tmp = 1.0 - u; + return (3 * u * (tmp * tmp)); +} + +static double B2(double u) +{ + double tmp = 1.0 - u; + return (3 * u * u * tmp); +} + +static double B3(double u) +{ + return (u * u * u); +} + + + +/* + * ComputeLeftTangent, ComputeRightTangent, ComputeCenterTangent : + *Approximate unit tangents at endpoints and "center" of digitized curve + */ +static Vector2 ComputeLeftTangent(Vector2 *d, int end) +// Vector2 *d; /* Digitized points*/ +// int end; /* Index to "left" end of region */ +{ + Vector2 tHat1; + tHat1 = V2SubII(d[end+1], d[end]); + tHat1 = *V2Normalize(&tHat1); + return tHat1; +} + +static Vector2 ComputeRightTangent(Vector2 *d, int end) +// Vector2 *d; /* Digitized points */ +// int end; /* Index to "right" end of region */ +{ + Vector2 tHat2; + tHat2 = V2SubII(d[end-1], d[end]); + tHat2 = *V2Normalize(&tHat2); + return tHat2; +} + +static Vector2 ComputeCenterTangent(Vector2 *d, int center) +// Vector2 *d; /* Digitized points */ +// int center; /* Index to point inside region */ +{ + Vector2 V1, V2, tHatCenter; + + V1 = V2SubII(d[center-1], d[center]); + V2 = V2SubII(d[center], d[center+1]); + tHatCenter[0] = (V1[0] + V2[0])/2.0; + tHatCenter[1] = (V1[1] + V2[1])/2.0; + tHatCenter = *V2Normalize(&tHatCenter); + return tHatCenter; +} + + +/* + * ChordLengthParameterize : + * Assign parameter values to digitized points + * using relative distances between points. + */ +static double *ChordLengthParameterize(Vector2 *d, int first, int last) +// Vector2 *d; /* Array of digitized points */ +// int first, last; /* Indices defining region */ +{ + int i; + double *u; /* Parameterization */ + + u = (double *)malloc((unsigned)(last-first+1) * sizeof(double)); + + u[0] = 0.0; + for (i = first+1; i <= last; i++) { + u[i-first] = u[i-first-1] + + V2DistanceBetween2Points(&d[i], &d[i-1]); + } + + for (i = first + 1; i <= last; i++) { + u[i-first] = u[i-first] / u[last-first]; + } + + return(u); +} + + + + +/* + * ComputeMaxError : + * Find the maximum squared distance of digitized points + * to fitted curve. +*/ +static double ComputeMaxError(Vector2 *d, int first, int last, BezierCurve bezCurve, double *u, int *splitPoint) +// Vector2 *d; /* Array of digitized points */ +// int first, last; /* Indices defining region */ +// BezierCurve bezCurve; /* Fitted Bezier curve */ +// double *u; /* Parameterization of points */ +// int *splitPoint; /* Point of maximum error */ +{ + int i; + double maxDist; /* Maximum error */ + double dist; /* Current error */ + Vector2 P; /* Point on curve */ + Vector2 v; /* Vector from point to curve */ + + *splitPoint = (last - first + 1)/2; + maxDist = 0.0; + for (i = first + 1; i < last; i++) { + P = BezierII(3, bezCurve, u[i-first]); + v = V2SubII(P, d[i]); + dist = V2SquaredLength(&v); + if (dist >= maxDist) { + maxDist = dist; + *splitPoint = i; + } + } + return (maxDist); +} +static Vector2 V2AddII(Vector2 a, Vector2 b) +{ + Vector2 c; + c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; + return (c); +} +static Vector2 V2ScaleIII(Vector2 v, double s) +{ + Vector2 result; + result[0] = v[0] * s; result[1] = v[1] * s; + return (result); +} + +static Vector2 V2SubII(Vector2 a, Vector2 b) +{ + Vector2 c; + c[0] = a[0] - b[0]; c[1] = a[1] - b[1]; + return (c); +} + +#ifdef __cplusplus +} +#endif + + +//------------------------- WRAPPER -----------------------------// + +FitCurveWrapper::FitCurveWrapper() +{ +} + +FitCurveWrapper::~FitCurveWrapper() +{ + _vertices.clear(); +} + +void FitCurveWrapper::DrawBezierCurve(int n, Vector2 *curve ) +{ + for(int i=0; i<n+1; ++i) + _vertices.push_back(curve[i]); +} + +void FitCurveWrapper::FitCurve(vector<Vec2d>& data, vector<Vec2d>& oCurve, double error) +{ + int size = data.size(); + Vector2 *d = new Vector2[size]; + for(int i=0; i<size; ++i) + { + d[i][0] = data[i][0]; + d[i][1] = data[i][1]; + } + + FitCurve(d,size,error); + + // copy results + for(vector<Vector2>::iterator v=_vertices.begin(), vend=_vertices.end(); + v!=vend; + ++v) + { + oCurve.push_back(Vec2d(v->x(), v->y())) ; + } + +} + +void FitCurveWrapper::FitCurve(Vector2 *d, int nPts, double error) +{ + Vector2 tHat1, tHat2; /* Unit tangent vectors at endpoints */ + + tHat1 = ComputeLeftTangent(d, 0); + tHat2 = ComputeRightTangent(d, nPts - 1); + FitCubic(d, 0, nPts - 1, tHat1, tHat2, error); +} + +void FitCurveWrapper::FitCubic(Vector2 *d, int first, int last, Vector2 tHat1, Vector2 tHat2, double error) +{ + BezierCurve bezCurve; /*Control points of fitted Bezier curve*/ + double *u; /* Parameter values for point */ + double *uPrime; /* Improved parameter values */ + double maxError; /* Maximum fitting error */ + int splitPoint; /* Point to split point set at */ + int nPts; /* Number of points in subset */ + double iterationError; /*Error below which you try iterating */ + int maxIterations = 4; /* Max times to try iterating */ + Vector2 tHatCenter; /* Unit tangent vector at splitPoint */ + int i; + + iterationError = error * error; + nPts = last - first + 1; + + /* Use heuristic if region only has two points in it */ + if (nPts == 2) { + double dist = V2DistanceBetween2Points(&d[last], &d[first]) / 3.0; + + bezCurve = (Vector2 *)malloc(4 * sizeof(Vector2)); + bezCurve[0] = d[first]; + bezCurve[3] = d[last]; + V2Add(&bezCurve[0], V2Scale(&tHat1, dist), &bezCurve[1]); + V2Add(&bezCurve[3], V2Scale(&tHat2, dist), &bezCurve[2]); + DrawBezierCurve(3, bezCurve); + free((void *)bezCurve); + return; + } + + /* Parameterize points, and attempt to fit curve */ + u = ChordLengthParameterize(d, first, last); + bezCurve = GenerateBezier(d, first, last, u, tHat1, tHat2); + + /* Find max deviation of points to fitted curve */ + maxError = ComputeMaxError(d, first, last, bezCurve, u, &splitPoint); + if (maxError < error) { + DrawBezierCurve(3, bezCurve); + free((void *)u); + free((void *)bezCurve); + return; + } + + + /* If error not too large, try some reparameterization */ + /* and iteration */ + if (maxError < iterationError) { + for (i = 0; i < maxIterations; i++) { + uPrime = Reparameterize(d, first, last, u, bezCurve); + bezCurve = GenerateBezier(d, first, last, uPrime, tHat1, tHat2); + maxError = ComputeMaxError(d, first, last, + bezCurve, uPrime, &splitPoint); + if (maxError < error) { + DrawBezierCurve(3, bezCurve); + free((void *)u); + free((void *)bezCurve); + return; + } + free((void *)u); + u = uPrime; + } + } + + /* Fitting failed -- split at max error point and fit recursively */ + free((void *)u); + free((void *)bezCurve); + tHatCenter = ComputeCenterTangent(d, splitPoint); + FitCubic(d, first, splitPoint, tHat1, tHatCenter, error); + V2Negate(&tHatCenter); + FitCubic(d, splitPoint, last, tHatCenter, tHat2, error); + +} + diff --git a/source/blender/freestyle/intern/geometry/FitCurve.h b/source/blender/freestyle/intern/geometry/FitCurve.h new file mode 100755 index 00000000000..ed7cbe34780 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/FitCurve.h @@ -0,0 +1,101 @@ +// +// Filename : FitCurve.h +// Author(s) : Stephane Grabli +// Purpose : An Algorithm for Automatically Fitting Digitized Curves +// by Philip J. Schneider +// from "Graphics Gems", Academic Press, 1990 +// Date of creation : 06/06/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef FITCURVE_H +# define FITCURVE_H + +#include <vector> +#include "../system/FreestyleConfig.h" +#include "Geom.h" + +using namespace Geometry; + +typedef struct Point2Struct { /* 2d point */ + double coordinates[2]; + Point2Struct() {coordinates[0]=0;coordinates[1]=0;} + inline double operator[](const int i) const + { + return coordinates[i]; + } + inline double& operator[](const int i) + { + return coordinates[i]; + } + inline double x() const {return coordinates[0];} + inline double y() const {return coordinates[1];} + } Point2; + +typedef Point2 Vector2; + + + +class LIB_GEOMETRY_EXPORT FitCurveWrapper +{ +private: + std::vector<Vector2> _vertices; + +public: + FitCurveWrapper(); + ~FitCurveWrapper(); + + /*! Fits a set of 2D data points to a set of Bezier Curve segments + * data + * Input data points + * oCurve + * Control points of the sets of bezier curve segments. + * Each segment is made of 4 points (polynomial degree of curve = 3) + * error + * max error tolerance between resulting curve and input data + */ + void FitCurve(std::vector<Vec2d>& data, std::vector<Vec2d>& oCurve, double error); +protected: + /* Vec2d *d; Array of digitized points */ + /* int nPts; Number of digitized points */ + /* double error; User-defined error squared */ + void FitCurve(Vector2 *d, int nPts, double error); + + /*! Draws a Bezier curve segment + * n + * degree of curve (=3) + * curve + * bezier segments control points + */ + void DrawBezierCurve(int n, Vector2 *curve); + + /* Vec2d *d; Array of digitized points */ + /* int first, last; Indices of first and last pts in region */ + /* Vec2d tHat1, tHat2; Unit tangent vectors at endpoints */ + /* double error; User-defined error squared */ + void FitCubic(Vector2 *d, int first, int last, Vector2 tHat1, Vector2 tHat2, double error); + +}; + +#endif // FITCURVE_H diff --git a/source/blender/freestyle/intern/geometry/Geom.h b/source/blender/freestyle/intern/geometry/Geom.h new file mode 100755 index 00000000000..ac94213fe98 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/Geom.h @@ -0,0 +1,78 @@ +// +// Filename : Geom.h +// Author(s) : Sylvain Paris +// Emmanuel Turquin +// Stephane Grabli +// Purpose : Vectors and Matrices (useful type definitions) +// Date of creation : 20/05/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GEOM_H +# define GEOM_H + +# include "VecMat.h" +# include "../system/Precision.h" + +namespace Geometry { + + typedef VecMat::Vec2<unsigned> Vec2u; + typedef VecMat::Vec2<int> Vec2i; + typedef VecMat::Vec2<float> Vec2f; + typedef VecMat::Vec2<double> Vec2d; + typedef VecMat::Vec2<real> Vec2r; + + typedef VecMat::Vec3<unsigned> Vec3u; + typedef VecMat::Vec3<int> Vec3i; + typedef VecMat::Vec3<float> Vec3f; + typedef VecMat::Vec3<double> Vec3d; + typedef VecMat::Vec3<real> Vec3r; + + typedef VecMat::HVec3<unsigned> HVec3u; + typedef VecMat::HVec3<int> HVec3i; + typedef VecMat::HVec3<float> HVec3f; + typedef VecMat::HVec3<double> HVec3d; + typedef VecMat::HVec3<real> HVec3r; + + typedef VecMat::SquareMatrix<unsigned, 2> Matrix22u; + typedef VecMat::SquareMatrix<int, 2> Matrix22i; + typedef VecMat::SquareMatrix<float, 2> Matrix22f; + typedef VecMat::SquareMatrix<double, 2> Matrix22d; + typedef VecMat::SquareMatrix<real, 2> Matrix22r; + + typedef VecMat::SquareMatrix<unsigned, 3> Matrix33u; + typedef VecMat::SquareMatrix<int, 3> Matrix33i; + typedef VecMat::SquareMatrix<float, 3> Matrix33f; + typedef VecMat::SquareMatrix<double, 3> Matrix33d; + typedef VecMat::SquareMatrix<real, 3> Matrix33r; + + typedef VecMat::SquareMatrix<unsigned, 4> Matrix44u; + typedef VecMat::SquareMatrix<int, 4> Matrix44i; + typedef VecMat::SquareMatrix<float, 4> Matrix44f; + typedef VecMat::SquareMatrix<double, 4> Matrix44d; + typedef VecMat::SquareMatrix<real, 4> Matrix44r; + +} // end of namespace Geometry + +#endif // GEOM_H diff --git a/source/blender/freestyle/intern/geometry/GeomCleaner.cpp b/source/blender/freestyle/intern/geometry/GeomCleaner.cpp new file mode 100755 index 00000000000..c148c521a46 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/GeomCleaner.cpp @@ -0,0 +1,240 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +//#if defined(__GNUC__) && (__GNUC__ >= 3) +//// hash_map is not part of the C++ standard anymore; +//// hash_map.h has been kept though for backward compatibility +//# include <hash_map.h> +//#else +//# include <hash_map> +//#endif + +#include <stdio.h> +#include <list> +#include <map> +#include "../system/TimeUtils.h" +#include "GeomCleaner.h" + +using namespace std; + + +void GeomCleaner::SortIndexedVertexArray( const float *iVertices, unsigned iVSize, + const unsigned *iIndices, unsigned iISize, + real **oVertices, + unsigned **oIndices) +{ + // First, we build a list of IndexVertex: + list<IndexedVertex> indexedVertices; + unsigned i; + for(i=0; i<iVSize; i+= 3) + { + indexedVertices.push_back(IndexedVertex(Vec3r(iVertices[i], iVertices[i+1], iVertices[i+2]), i/3)); + } + + // q-sort + indexedVertices.sort(); + + // build the indices mapping array: + unsigned *mapIndices = new unsigned[iVSize/3]; + *oVertices = new real[iVSize]; + list<IndexedVertex>::iterator iv; + unsigned newIndex = 0; + unsigned vIndex = 0; + for(iv=indexedVertices.begin(); iv!=indexedVertices.end(); iv++) + { + // Build the final results: + (*oVertices)[vIndex] = iv->x(); + (*oVertices)[vIndex+1] = iv->y(); + (*oVertices)[vIndex+2] = iv->z(); + + mapIndices[iv->index()] = newIndex; + newIndex++; + vIndex+=3; + } + + + // Build the final index array: + *oIndices = new unsigned[iISize]; + for(i=0; i<iISize; i++) + { + (*oIndices)[i] = 3*mapIndices[iIndices[i]/3]; + } + + delete [] mapIndices; +} + +void GeomCleaner::CompressIndexedVertexArray(const real *iVertices, unsigned iVSize, + const unsigned *iIndices, unsigned iISize, + real **oVertices, unsigned *oVSize, + unsigned **oIndices) +{ + // First, we build a list of IndexVertex: + vector<Vec3r> vertices; + unsigned i; + for(i=0; i<iVSize; i+= 3) + { + vertices.push_back(Vec3r(iVertices[i], iVertices[i+1], iVertices[i+2])); + } + + unsigned *mapVertex = new unsigned[iVSize]; + vector<Vec3r>::iterator v = vertices.begin(); + + vector<Vec3r> compressedVertices; + Vec3r previous = *v; + mapVertex[0] = 0; + compressedVertices.push_back(vertices.front()); + + v++; + Vec3r current; + i=1; + for(; v!=vertices.end(); v++) + { + current = *v; + if(current == previous) + mapVertex[i] = compressedVertices.size()-1; + else + { + compressedVertices.push_back(current); + mapVertex[i] = compressedVertices.size()-1; + } + previous = current; + i++; + } + + // Builds the resulting vertex array: + *oVSize = 3*compressedVertices.size(); + *oVertices = new real [*oVSize]; + i=0; + for(v=compressedVertices.begin(); v!=compressedVertices.end(); v++) + { + (*oVertices)[i] = (*v)[0]; + (*oVertices)[i+1] = (*v)[1]; + (*oVertices)[i+2] = (*v)[2]; + i += 3; + } + + // Map the index array: + *oIndices = new unsigned[iISize]; + for(i=0; i<iISize; i++) + { + (*oIndices)[i] = 3*mapVertex[iIndices[i]/3]; + } + + delete [] mapVertex; +} + +void GeomCleaner::SortAndCompressIndexedVertexArray(const float *iVertices, unsigned iVSize, + const unsigned *iIndices, unsigned iISize, + real **oVertices, unsigned *oVSize, + unsigned **oIndices) +{ + + // tmp arrays used to store the sorted data: + real *tmpVertices; + unsigned *tmpIndices; + + Chronometer chrono; + // Sort data + chrono.start(); + GeomCleaner::SortIndexedVertexArray(iVertices, iVSize, + iIndices, iISize, + &tmpVertices, &tmpIndices + ); + printf("Sorting: %lf\n", chrono.stop()); + + // compress data + chrono.start(); + GeomCleaner::CompressIndexedVertexArray(tmpVertices, iVSize, + tmpIndices, iISize, + oVertices, oVSize, + oIndices); + printf("Merging: %lf\n", chrono.stop()); + + // deallocates memory: + delete [] tmpVertices; + delete [] tmpIndices; +} + +/*! Defines a hash table used for searching the Cells */ +struct GeomCleanerHasher{ +#define _MUL 950706376UL +#define _MOD 2147483647UL + inline size_t operator() (const Vec3r& p) const { + size_t res = ((unsigned long) (p[0] * _MUL)) % _MOD; + res = ((res + (unsigned long) (p[1]) * _MUL)) % _MOD; + return ((res +(unsigned long) (p[2]) * _MUL)) % _MOD; + } +}; + +void GeomCleaner::CleanIndexedVertexArray(const float *iVertices, unsigned iVSize, + const unsigned *iIndices, unsigned iISize, + real **oVertices, unsigned *oVSize, + unsigned **oIndices) +{ + typedef map<Vec3r, unsigned> cleanHashTable; + vector<Vec3r> vertices; + unsigned i; + for(i=0; i<iVSize; i+= 3) + vertices.push_back(Vec3r(iVertices[i], iVertices[i+1], iVertices[i+2])); + + cleanHashTable ht; + vector<unsigned> newIndices; + vector<Vec3r> newVertices; + + // elimination of needless points + unsigned currentIndex = 0; + vector<Vec3r>::const_iterator v = vertices.begin(); + vector<Vec3r>::const_iterator end = vertices.end(); + cleanHashTable::const_iterator found; + for(; v!=end; v++) + { + found = ht.find(*v); + if(found != ht.end()) + { + // The vertex is already in the new array. + newIndices.push_back((*found).second); + } + else + { + newVertices.push_back(*v); + newIndices.push_back(currentIndex); + ht[*v] = currentIndex; + currentIndex++; + } + } + + // creation of oVertices array: + *oVSize = 3*newVertices.size(); + *oVertices = new real[*oVSize]; + currentIndex = 0; + end = newVertices.end(); + for(v=newVertices.begin(); v!=end ; v++) + { + (*oVertices)[currentIndex++] = (*v)[0]; + (*oVertices)[currentIndex++] = (*v)[1]; + (*oVertices)[currentIndex++] = (*v)[2]; + } + + // map new indices: + *oIndices = new unsigned[iISize]; + for(i=0; i<iISize; i++) + (*oIndices)[i] = 3*newIndices[iIndices[i]/3]; +} diff --git a/source/blender/freestyle/intern/geometry/GeomCleaner.h b/source/blender/freestyle/intern/geometry/GeomCleaner.h new file mode 100755 index 00000000000..5fdfda0162a --- /dev/null +++ b/source/blender/freestyle/intern/geometry/GeomCleaner.h @@ -0,0 +1,219 @@ +// +// Filename : GeomCleaner.h +// Author : Stephane Grabli +// Purpose : Class to define a cleaner of geometry providing +// a set of useful tools +// Date of creation : 04/03/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GEOMCLEANER_H +# define GEOMCLEANER_H + +# include "../system/FreestyleConfig.h" +# include "Geom.h" + +using namespace Geometry; + +class LIB_GEOMETRY_EXPORT GeomCleaner +{ +public: + + inline GeomCleaner() {} + inline ~GeomCleaner() {} + + /*! Sorts an array of Indexed vertices + * iVertices + * Array of vertices to sort. It is organized as a + * float series of vertex coordinates: XYZXYZXYZ... + * iVSize + * The size of iVertices array. + * iIndices + * The array containing the vertex indices (used to refer + * to the vertex coordinates in an indexed face). Each + * element is an unsignedeger multiple of 3. + * iISize + * The size of iIndices array + * oVertices + * Output of sorted vertices. A vertex v1 precedes another one + * v2 in this array if v1.x<v2.x, or v1.x=v2.x && v1.y < v2.y + * or v1.x=v2.y && v1.y=v2.y && v1.z < v2.z. + * The array is organized as a 3-float serie giving + * the vertices coordinates: XYZXYZXYZ... + * oIndices + * Output corresponding to the iIndices array but + * reorganized in order to match the sorted vertex array. + */ + + static void SortIndexedVertexArray(const float *iVertices, unsigned iVSize, + const unsigned *iIndices, unsigned iISize, + real **oVertices, + unsigned **oIndices); + + /*! Compress a SORTED indexed vertex array by eliminating + * multiple appearing occurences of a single vertex. + * iVertices + * The SORTED vertex array to compress. It is organized as a + * float series of vertex coordinates: XYZXYZXYZ... + * iVSize + * The size of iVertices array. + * iIndices + * The array containing the vertex indices (used to refer + * to the vertex coordinates in an indexed face). Each + * element is an unsignedeger multiple of 3. + * iISize + * The size of iIndices array + * oVertices + * The vertex array, result of the compression. + * The array is organized as a 3-float serie giving + * the vertices coordinates: XYZXYZXYZ... + * oVSize + * The size of oVertices. + * oIndices + * The indices array, reorganized to match the compressed + * oVertices array. + */ + + static void CompressIndexedVertexArray(const real *iVertices, unsigned iVSize, + const unsigned *iIndices, unsigned iISize, + real **oVertices, unsigned *oVSize, + unsigned **oIndices); + + /*! Sorts and compress an array of indexed vertices. + * iVertices + * The vertex array to sort then compress. It is organized as a + * float series of vertex coordinates: XYZXYZXYZ... + * iVSize + * The size of iVertices array. + * iIndices + * The array containing the vertex indices (used to refer + * to the vertex coordinates in an indexed face). Each + * element is an unsignedeger multiple of 3. + * iISize + * The size of iIndices array + * oVertices + * The vertex array, result of the sorting-compression. + * The array is organized as a 3-float serie giving + * the vertices coordinates: XYZXYZXYZ... + * oVSize + * The size of oVertices. + * oIndices + * The indices array, reorganized to match the sorted and compressed + * oVertices array. + */ + + static void SortAndCompressIndexedVertexArray(const float *iVertices, unsigned iVSize, + const unsigned *iIndices, unsigned iISize, + real **oVertices, unsigned *oVSize, + unsigned **oIndices); + + /*! Cleans an indexed vertex array. (Identical to + * SortAndCompress except that we use here a hash + * table to create the new array.) + * iVertices + * The vertex array to sort then compress. It is organized as a + * float series of vertex coordinates: XYZXYZXYZ... + * iVSize + * The size of iVertices array. + * iIndices + * The array containing the vertex indices (used to refer + * to the vertex coordinates in an indexed face). Each + * element is an unsignedeger multiple of 3. + * iISize + * The size of iIndices array + * oVertices + * The vertex array, result of the sorting-compression. + * The array is organized as a 3-float serie giving + * the vertices coordinates: XYZXYZXYZ... + * oVSize + * The size of oVertices. + * oIndices + * The indices array, reorganized to match the sorted and compressed + * oVertices array. + */ + + static void CleanIndexedVertexArray(const float *iVertices, unsigned iVSize, + const unsigned *iIndices, unsigned iISize, + real **oVertices, unsigned *oVSize, + unsigned **oIndices); +}; + + +/*! Binary operators */ +//inline bool operator<(const IndexedVertex& iv1, const IndexedVertex& iv2); + +/*! Class Indexed Vertex. Used to represent + * an indexed vertex by storing the vertex + * coordinates as well as its index + */ +class IndexedVertex +{ +public: + +private: + Vec3r _Vector; + unsigned _index; +public: + inline IndexedVertex() {} + inline IndexedVertex(Vec3r iVector, unsigned iIndex) + { + _Vector = iVector; + _index = iIndex; + } + /*! accessors */ + inline const Vec3r& vector() const {return _Vector;} + inline unsigned index() {return _index;} + inline real x() {return _Vector[0];} + inline real y() {return _Vector[1];} + inline real z() {return _Vector[2];} + + /*! modifiers */ + inline void setVector(const Vec3r& iVector) {_Vector = iVector;} + inline void setIndex(unsigned iIndex) {_index = iIndex;} + + /*! operators */ + IndexedVertex& operator=(const IndexedVertex& iv) + { + _Vector = iv._Vector; + _index = iv._index; + return *this; + } + inline real operator[](const unsigned i) {return _Vector[i];} + //friend inline bool operator<(const IndexedVertex& iv1, const IndexedVertex& iv2); + inline bool operator<(const IndexedVertex& v) const + { + return (_Vector < v._Vector); + } + inline bool operator==(const IndexedVertex& v) + { + return (_Vector == v._Vector); + } +}; + +//bool operator<(const IndexedVertex& iv1, const IndexedVertex& iv2) +//{ +// return iv1.operator<(iv2); +//} + +#endif // GEOMCLEANER_H diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.cpp b/source/blender/freestyle/intern/geometry/GeomUtils.cpp new file mode 100755 index 00000000000..2169bce0364 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/GeomUtils.cpp @@ -0,0 +1,753 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "GeomUtils.h" + +namespace GeomUtils { + + // This internal procedure is defined below. + bool intersect2dSegPoly(Vec2r* seg, + Vec2r* poly, + unsigned n); + + bool intersect2dSeg2dArea(const Vec2r& min, + const Vec2r& max, + const Vec2r& A, + const Vec2r& B) { + Vec2r seg[2]; + seg[0] = A; + seg[1] = B; + + Vec2r poly[5]; + poly[0][0] = min[0]; + poly[0][1] = min[1]; + poly[1][0] = max[0]; + poly[1][1] = min[1]; + poly[2][0] = max[0]; + poly[2][1] = max[1]; + poly[3][0] = min[0]; + poly[3][1] = max[1]; + poly[4][0] = min[0]; + poly[4][1] = min[1]; + + return intersect2dSegPoly(seg, poly, 4); + } + + bool include2dSeg2dArea(const Vec2r& min, + const Vec2r& max, + const Vec2r& A, + const Vec2r& B) { + if((((max[0] > A[0])&&(A[0] > min[0]))&&((max[0] > B[0])&&(B[0] > min[0]))) + && (((max[1] > A[1])&&(A[1] > min[1]))&&((max[1] > B[1])&&(B[1] > min[1])))) + return true; + return false; + } + + intersection_test intersect2dSeg2dSeg(const Vec2r& p1, + const Vec2r& p2, + const Vec2r& p3, + const Vec2r& p4, + Vec2r& res) { + real a1, a2, b1, b2, c1, c2; // Coefficients of line eqns + real r1, r2, r3, r4; // 'Sign' values + real denom, num; // Intermediate values + + // Compute a1, b1, c1, where line joining points p1 and p2 + // is "a1 x + b1 y + c1 = 0". + a1 = p2[1] - p1[1]; + b1 = p1[0] - p2[0]; + c1 = p2[0] * p1[1] - p1[0] * p2[1]; + + // Compute r3 and r4. + r3 = a1 * p3[0] + b1 * p3[1] + c1; + r4 = a1 * p4[0] + b1 * p4[1] + c1; + + // Check signs of r3 and r4. If both point 3 and point 4 lie on + // same side of line 1, the line segments do not intersect. + if ( r3 != 0 && r4 != 0 && r3 * r4 > 0.0) + return (DONT_INTERSECT); + + // Compute a2, b2, c2 + a2 = p4[1] - p3[1]; + b2 = p3[0] - p4[0]; + c2 = p4[0] * p3[1] - p3[0] * p4[1]; + + // Compute r1 and r2 + r1 = a2 * p1[0] + b2 * p1[1] + c2; + r2 = a2 * p2[0] + b2 * p2[1] + c2; + + // Check signs of r1 and r2. If both point 1 and point 2 lie + // on same side of second line segment, the line segments do + // not intersect. + if ( r1 != 0 && r2 != 0 && r1 * r2 > 0.0) + return (DONT_INTERSECT); + + // Line segments intersect: compute intersection point. + denom = a1 * b2 - a2 * b1; + if (fabs(denom) < M_EPSILON) + return (COLINEAR); + + num = b1 * c2 - b2 * c1; + res[0] = num / denom; + + num = a2 * c1 - a1 * c2; + res[1] = num / denom; + + return (DO_INTERSECT); + } + + intersection_test intersect2dLine2dLine(const Vec2r& p1, + const Vec2r& p2, + const Vec2r& p3, + const Vec2r& p4, + Vec2r& res) { + real a1, a2, b1, b2, c1, c2; // Coefficients of line eqns + real denom, num; // Intermediate values + + // Compute a1, b1, c1, where line joining points p1 and p2 + // is "a1 x + b1 y + c1 = 0". + a1 = p2[1] - p1[1]; + b1 = p1[0] - p2[0]; + c1 = p2[0] * p1[1] - p1[0] * p2[1]; + + // Compute a2, b2, c2 + a2 = p4[1] - p3[1]; + b2 = p3[0] - p4[0]; + c2 = p4[0] * p3[1] - p3[0] * p4[1]; + + // Line segments intersect: compute intersection point. + denom = a1 * b2 - a2 * b1; + if (fabs(denom) < M_EPSILON) + return (COLINEAR); + + num = b1 * c2 - b2 * c1; + res[0] = num / denom; + + num = a2 * c1 - a1 * c2; + res[1] = num / denom; + + return (DO_INTERSECT); + } + + intersection_test intersect2dSeg2dSegParametric(const Vec2r& p1, + const Vec2r& p2, + const Vec2r& p3, + const Vec2r& p4, + real& t, + real& u, + real epsilon) { + real a1, a2, b1, b2, c1, c2; // Coefficients of line eqns + real r1, r2, r3, r4; // 'Sign' values + real denom, num; // Intermediate values + + // Compute a1, b1, c1, where line joining points p1 and p2 + // is "a1 x + b1 y + c1 = 0". + a1 = p2[1] - p1[1]; + b1 = p1[0] - p2[0]; + c1 = p2[0] * p1[1] - p1[0] * p2[1]; + + // Compute r3 and r4. + r3 = a1 * p3[0] + b1 * p3[1] + c1; + r4 = a1 * p4[0] + b1 * p4[1] + c1; + + // Check signs of r3 and r4. If both point 3 and point 4 lie on + // same side of line 1, the line segments do not intersect. + if ( r3 != 0 && r4 != 0 && r3 * r4 > 0.0) + return (DONT_INTERSECT); + + // Compute a2, b2, c2 + a2 = p4[1] - p3[1]; + b2 = p3[0] - p4[0]; + c2 = p4[0] * p3[1] - p3[0] * p4[1]; + + // Compute r1 and r2 + r1 = a2 * p1[0] + b2 * p1[1] + c2; + r2 = a2 * p2[0] + b2 * p2[1] + c2; + + // Check signs of r1 and r2. If both point 1 and point 2 lie + // on same side of second line segment, the line segments do + // not intersect. + if ( r1 != 0 && r2 != 0 && r1 * r2 > 0.0) + return (DONT_INTERSECT); + + // Line segments intersect: compute intersection point. + denom = a1 * b2 - a2 * b1; + if (fabs(denom) < epsilon) + return (COLINEAR); + + real d1, d2, e1; + + d1 = p1[1] - p3[1]; + d2 = p2[1] - p1[1]; + e1 = p1[0] - p3[0]; + + num = -b2 * d1 - a2 * e1; + t = num / denom; + + num = -b1 * d1 - a1 * e1; + u = num / denom; + + return (DO_INTERSECT); + } + + // AABB-triangle overlap test code + // by Tomas Akenine-Möller + // Function: int triBoxOverlap(real boxcenter[3], + // real boxhalfsize[3],real triverts[3][3]); + // History: + // 2001-03-05: released the code in its first version + // 2001-06-18: changed the order of the tests, faster + // + // Acknowledgement: Many thanks to Pierre Terdiman for + // suggestions and discussions on how to optimize code. + // Thanks to David Hunt for finding a ">="-bug! + +#define X 0 +#define Y 1 +#define Z 2 + +#define FINDMINMAX(x0, x1, x2, min, max) \ + min = max = x0; \ + if(x1<min) min=x1; \ + if(x1>max) max=x1; \ + if(x2<min) min=x2; \ + if(x2>max) max=x2; + + //======================== X-tests ========================// +#define AXISTEST_X01(a, b, fa, fb) \ + p0 = a*v0[Y] - b*v0[Z]; \ + p2 = a*v2[Y] - b*v2[Z]; \ + if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \ + rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ + if(min>rad || max<-rad) return 0; + +#define AXISTEST_X2(a, b, fa, fb) \ + p0 = a*v0[Y] - b*v0[Z]; \ + p1 = a*v1[Y] - b*v1[Z]; \ + if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ + rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ + if(min>rad || max<-rad) return 0; + + //======================== Y-tests ========================// +#define AXISTEST_Y02(a, b, fa, fb) \ + p0 = -a*v0[X] + b*v0[Z]; \ + p2 = -a*v2[X] + b*v2[Z]; \ + if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ + if(min>rad || max<-rad) return 0; + +#define AXISTEST_Y1(a, b, fa, fb) \ + p0 = -a*v0[X] + b*v0[Z]; \ + p1 = -a*v1[X] + b*v1[Z]; \ + if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ + if(min>rad || max<-rad) return 0; + + //======================== Z-tests ========================// +#define AXISTEST_Z12(a, b, fa, fb) \ + p1 = a*v1[X] - b*v1[Y]; \ + p2 = a*v2[X] - b*v2[Y]; \ + if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;} \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ + if(min>rad || max<-rad) return 0; + +#define AXISTEST_Z0(a, b, fa, fb) \ + p0 = a*v0[X] - b*v0[Y]; \ + p1 = a*v1[X] - b*v1[Y]; \ + if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ + if(min>rad || max<-rad) return 0; + + // This internal procedure is defined below. + bool overlapPlaneBox(Vec3r& normal, real d, Vec3r& maxbox); + + // Use separating axis theorem to test overlap between triangle and box + // need to test for overlap in these directions: + // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle + // we do not even need to test these) + // 2) normal of the triangle + // 3) crossproduct(edge from tri, {x,y,z}-directin) + // this gives 3x3=9 more tests + bool overlapTriangleBox(Vec3r& boxcenter, + Vec3r& boxhalfsize, + Vec3r triverts[3]) { + Vec3r v0, v1, v2, normal, e0, e1, e2; + real min, max, d, p0, p1, p2, rad, fex, fey, fez; + + // This is the fastest branch on Sun + // move everything so that the boxcenter is in (0, 0, 0) + v0 = triverts[0] - boxcenter; + v1 = triverts[1] - boxcenter; + v2 = triverts[2] - boxcenter; + + // compute triangle edges + e0 = v1 - v0; + e1 = v2 - v1; + e2 = v0 - v2; + + // Bullet 3: + // Do the 9 tests first (this was faster) + fex = fabs(e0[X]); + fey = fabs(e0[Y]); + fez = fabs(e0[Z]); + AXISTEST_X01(e0[Z], e0[Y], fez, fey); + AXISTEST_Y02(e0[Z], e0[X], fez, fex); + AXISTEST_Z12(e0[Y], e0[X], fey, fex); + + fex = fabs(e1[X]); + fey = fabs(e1[Y]); + fez = fabs(e1[Z]); + AXISTEST_X01(e1[Z], e1[Y], fez, fey); + AXISTEST_Y02(e1[Z], e1[X], fez, fex); + AXISTEST_Z0(e1[Y], e1[X], fey, fex); + + fex = fabs(e2[X]); + fey = fabs(e2[Y]); + fez = fabs(e2[Z]); + AXISTEST_X2(e2[Z], e2[Y], fez, fey); + AXISTEST_Y1(e2[Z], e2[X], fez, fex); + AXISTEST_Z12(e2[Y], e2[X], fey, fex); + + // Bullet 1: + // first test overlap in the {x,y,z}-directions + // find min, max of the triangle each direction, and test for overlap in + // that direction -- this is equivalent to testing a minimal AABB around + // the triangle against the AABB + + // test in X-direction + FINDMINMAX(v0[X], v1[X], v2[X], min, max); + if (min > boxhalfsize[X] || max < -boxhalfsize[X]) + return false; + + // test in Y-direction + FINDMINMAX(v0[Y], v1[Y], v2[Y], min, max); + if (min > boxhalfsize[Y] || max < -boxhalfsize[Y]) + return false; + + // test in Z-direction + FINDMINMAX(v0[Z], v1[Z], v2[Z], min, max); + if(min > boxhalfsize[Z] || max < -boxhalfsize[Z]) + return false; + + // Bullet 2: + // test if the box intersects the plane of the triangle + // compute plane equation of triangle: normal * x + d = 0 + normal = e0 ^ e1; + d = -(normal * v0); // plane eq: normal.x + d = 0 + if (!overlapPlaneBox(normal, d, boxhalfsize)) + return false; + + return true; // box and triangle overlaps + } + + // Fast, Minimum Storage Ray-Triangle Intersection + // + // Tomas Möller + // Prosolvia Clarus AB + // Sweden + // tompa@clarus.se + // + // Ben Trumbore + // Cornell University + // Ithaca, New York + // wbt@graphics.cornell.edu + + bool intersectRayTriangle(Vec3r& orig, Vec3r& dir, + Vec3r& v0, Vec3r& v1, Vec3r& v2, + real& t, real& u, real& v, real epsilon) { + Vec3r edge1, edge2, tvec, pvec, qvec; + real det, inv_det; + + // find vectors for two edges sharing v0 + edge1 = v1 - v0; + edge2 = v2 - v0; + + // begin calculating determinant - also used to calculate U parameter + pvec = dir ^ edge2; + + // if determinant is near zero, ray lies in plane of triangle + det = edge1 * pvec; + + // calculate distance from v0 to ray origin + tvec = orig - v0; + inv_det = 1.0 / det; + + qvec = tvec ^ edge1; + + if (det > epsilon) { + u = tvec * pvec; + if (u < 0.0 || u > det) + return false; + + // calculate V parameter and test bounds + v = dir * qvec; + if (v < 0.0 || u + v > det) + return false; + } + else if(det < -epsilon) { + // calculate U parameter and test bounds + u = tvec * pvec; + if (u > 0.0 || u < det) + return false; + + // calculate V parameter and test bounds + v = dir * qvec; + if (v > 0.0 || u + v < det) + return false; + } + else + return false; // ray is parallell to the plane of the triangle + + u *= inv_det; + v *= inv_det; + t = (edge2 * qvec) * inv_det; + + return true; + } + + // Intersection between plane and ray, adapted from Graphics Gems, Didier Badouel + intersection_test intersectRayPlane(Vec3r& orig, Vec3r& dir, + Vec3r& norm, real d, + real& t, + real epsilon) { + real denom = norm * dir; + + if(fabs(denom) <= epsilon) { // plane and ray are parallel + if(fabs((norm * orig) + d) <= epsilon) + return COINCIDENT; // plane and ray are coincident + else + return COLINEAR; + } + + t = -(d + (norm * orig)) / denom; + + if (t < 0.0f) + return DONT_INTERSECT; + + return DO_INTERSECT; + } + + bool intersectRayBBox(const Vec3r& orig, const Vec3r& dir, // ray origin and direction + const Vec3r& boxMin, const Vec3r& boxMax, // the bbox + real t0, real t1, + real& tmin, real& tmax, // I0=orig+tmin*dir is the first intersection, I1=orig+tmax*dir is the second intersection + real epsilon){ + + float tymin, tymax, tzmin, tzmax; + Vec3r inv_direction(1.0/dir[0], 1.0/dir[1], 1.0/dir[2]); + int sign[3]; + sign[0] = (inv_direction.x() < 0); + sign[1] = (inv_direction.y() < 0); + sign[2] = (inv_direction.z() < 0); + + Vec3r bounds[2]; + bounds[0] = boxMin; + bounds[1] = boxMax; + + tmin = (bounds[sign[0]].x() - orig.x()) * inv_direction.x(); + tmax = (bounds[1-sign[0]].x() - orig.x()) * inv_direction.x(); + tymin = (bounds[sign[1]].y() - orig.y()) * inv_direction.y(); + tymax = (bounds[1-sign[1]].y() - orig.y()) * inv_direction.y(); + if ( (tmin > tymax) || (tymin > tmax) ) + return false; + if (tymin > tmin) + tmin = tymin; + if (tymax < tmax) + tmax = tymax; + tzmin = (bounds[sign[2]].z() - orig.z()) * inv_direction.z(); + tzmax = (bounds[1-sign[2]].z() - orig.z()) * inv_direction.z(); + if ( (tmin > tzmax) || (tzmin > tmax) ) + return false; + if (tzmin > tmin) + tmin = tzmin; + if (tzmax < tmax) + tmax = tzmax; + return ( (tmin < t1) && (tmax > t0) ); + } + + // Checks whether 3D points p lies inside or outside of the triangle ABC + bool includePointTriangle(Vec3r& P, + Vec3r& A, + Vec3r& B, + Vec3r& C) { + Vec3r AB(B - A); + Vec3r BC(C - B); + Vec3r CA(A - C); + Vec3r AP(P - A); + Vec3r BP(P - B); + Vec3r CP(P - C); + + Vec3r N(AB ^ BC); // triangle's normal + + N.normalize(); + + Vec3r J(AB ^ AP), K(BC ^ BP), L(CA ^ CP); + J.normalize(); + K.normalize(); + L.normalize(); + + if(J * N < 0) + return false; // on the right of AB + + if(K * N < 0) + return false; // on the right of BC + + if(L * N < 0) + return false; // on the right of CA + + return true; + } + + void transformVertex(const Vec3r& vert, + const Matrix44r& matrix, + Vec3r& res) { + HVec3r hvert(vert), res_tmp; + real scale; + for (unsigned j = 0; j < 4; j++) { + scale = hvert[j]; + for (unsigned i = 0; i < 4; i++) + res_tmp[i] += matrix(i, j) * scale; + } + + res[0] = res_tmp.x(); + res[1] = res_tmp.y(); + res[2] = res_tmp.z(); + } + + void transformVertices(const vector<Vec3r>& vertices, + const Matrix44r& trans, + vector<Vec3r>& res) { + for (vector<Vec3r>::const_iterator v = vertices.begin(); + v != vertices.end(); + v++) { + Vec3r *res_tmp = new Vec3r; + transformVertex(*v, trans, *res_tmp); + res.push_back(*res_tmp); + } + } + + Vec3r rotateVector(const Matrix44r& mat, const Vec3r& v) { + Vec3r res; + for (unsigned i = 0; i < 3; i++) { + res[i] = 0; + for (unsigned j = 0; j < 3; j++) + res[i] += mat(i, j) * v[j]; + } + res.normalize(); + return res; + } + + // This internal procedure is defined below. + void fromCoordAToCoordB(const Vec3r& p, + Vec3r& q, + const real transform[4][4]); + + void fromWorldToCamera(const Vec3r& p, + Vec3r& q, + const real model_view_matrix[4][4]) { + fromCoordAToCoordB(p, q, model_view_matrix); + } + + void fromCameraToRetina(const Vec3r& p, + Vec3r& q, + const real projection_matrix[4][4]) { + fromCoordAToCoordB(p, q, projection_matrix); + } + + void fromRetinaToImage(const Vec3r& p, + Vec3r& q, + const int viewport[4]) { + // winX: + q[0] = viewport[0] + viewport[2] * (p[0] + 1.0) / 2.0; + + // winY: + q[1] = viewport[1] + viewport[3] * (p[1] + 1.0) / 2.0; + + // winZ: + q[2] = (p[2] + 1.0) / 2.0; + } + + void fromWorldToImage(const Vec3r& p, + Vec3r& q, + const real model_view_matrix[4][4], + const real projection_matrix[4][4], + const int viewport[4]) { + Vec3r p1, p2; + fromWorldToCamera(p, p1, model_view_matrix); + fromCameraToRetina(p1, p2, projection_matrix); + fromRetinaToImage(p2, q, viewport); + q[2] = p1[2]; + } + + void fromWorldToImage(const Vec3r& p, + Vec3r& q, + const real transform[4][4], + const int viewport[4]) { + fromCoordAToCoordB(p, q, transform); + + // winX: + q[0] = viewport[0] + viewport[2] * (q[0] + 1.0) / 2.0; + + //winY: + q[1] = viewport[1] + viewport[3] * (q[1] + 1.0) / 2.0; + } + + void fromImageToRetina(const Vec3r& p, + Vec3r& q, + const int viewport[4]) { + q = p; + q[0] = 2.0 * (q[0] - viewport[0]) / viewport[2] - 1; + q[1] = 2.0 * (q[1] - viewport[1]) / viewport[3] - 1; + } + + void fromRetinaToCamera(const Vec3r& p, + Vec3r& q, + real focal, + const real projection_matrix[4][4]) { + + if( projection_matrix[3][3] == 0.0 ) // perspective + { + q[0] = (-p[0] * focal) / projection_matrix[0][0]; + q[1] = (-p[1] * focal) / projection_matrix[1][1]; + q[2] = focal; + } + else // orthogonal + { + q[0] = p[0] / projection_matrix[0][0]; + q[1] = p[1] / projection_matrix[1][1]; + q[2] = focal; + } + } + + void fromCameraToWorld(const Vec3r& p, + Vec3r& q, + const real model_view_matrix[4][4]) { + + real translation[3] = { model_view_matrix[0][3], + model_view_matrix[1][3], + model_view_matrix[2][3] }; + for (unsigned i = 0; i < 3; i++) { + q[i] = 0.0; + for (unsigned short j = 0; j < 3; j++) + q[i] += model_view_matrix[j][i] * (p[j] - translation[j]); + } + } + + + // + // Internal code + // + ///////////////////////////////////////////////////////////////////////////// + + // Copyright 2001, softSurfer (www.softsurfer.com) + // This code may be freely used and modified for any purpose + // providing that this copyright notice is included with it. + // SoftSurfer makes no warranty for this code, and cannot be held + // liable for any real or imagined damage resulting from its use. + // Users of this code must verify correctness for their application. + +#define perp(u,v) ((u)[0] * (v)[1] - (u)[1] * (v)[0]) // 2D perp product + + inline bool intersect2dSegPoly(Vec2r* seg, + Vec2r* poly, + unsigned n) { + if (seg[0] == seg[1]) + return false; + + real tE = 0; // the maximum entering segment parameter + real tL = 1; // the minimum leaving segment parameter + real t, N, D; // intersect parameter t = N / D + Vec2r dseg; // the segment direction vector + dseg = seg[1] - seg[0]; + Vec2r e; // edge vector + + for (unsigned i = 0; i < n; i++) { // process polygon edge poly[i]poly[i+1] + e = poly[i+1] - poly[i]; + N = perp(e, seg[0] - poly[i]); + D = -perp(e, dseg); + if (fabs(D) < M_EPSILON) { + if (N < 0) + return false; + else + continue; + } + + t = N / D; + if (D < 0) { // segment seg is entering across this edge + if (t > tE) { // new max tE + tE = t; + if (tE > tL) // seg enters after leaving polygon + return false; + } + } + else { // segment seg is leaving across this edge + if (t < tL) { // new min tL + tL = t; + if (tL < tE) // seg leaves before entering polygon + return false; + } + } + } + + // tE <= tL implies that there is a valid intersection subsegment + return true; + } + + inline bool overlapPlaneBox(Vec3r& normal, real d, Vec3r& maxbox) { + Vec3r vmin, vmax; + + for(unsigned q = X; q <= Z; q++) { + if(normal[q] > 0.0f) { + vmin[q] = -maxbox[q]; + vmax[q] = maxbox[q]; + } + else { + vmin[q] = maxbox[q]; + vmax[q] = -maxbox[q]; + } + } + if((normal * vmin) + d > 0.0f) + return false; + if((normal * vmax) + d >= 0.0f) + return true; + return false; + } + + inline void fromCoordAToCoordB(const Vec3r&p, + Vec3r& q, + const real transform[4][4]) { + HVec3r hp(p); + HVec3r hq(0, 0, 0, 0); + + for (unsigned i = 0; i < 4; i++) + for (unsigned j = 0; j < 4; j++) + hq[i] += transform[i][j] * hp[j]; + + if(hq[3] == 0) { + q = p; + return; + } + + for (unsigned k = 0; k < 3; k++) + q[k] = hq[k] / hq[3]; + } + +} // end of namespace GeomUtils diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.h b/source/blender/freestyle/intern/geometry/GeomUtils.h new file mode 100755 index 00000000000..787376108e1 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/GeomUtils.h @@ -0,0 +1,310 @@ +// +// Filename : GeomUtils.h +// Author(s) : Stephane Grabli +// Purpose : Various tools for geometry +// Date of creation : 12/04/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GEOMUTILS_H +# define GEOMUTILS_H + +# include <vector> +# include "../system/FreestyleConfig.h" +# include "Geom.h" + +using namespace std; +using namespace Geometry; + +namespace GeomUtils { + + // + // Templated procedures + // + ///////////////////////////////////////////////////////////////////////////// + + /*! Computes the distance from a point P to a segment AB */ + template<class T> + real distPointSegment( const T& P, const T& A , const T& B) { + T AB, AP, BP; + AB = B - A; + AP = P - A; + BP = P - B; + + real c1(AB * AP); + if (c1 <= 0) + return AP.norm(); + + real c2(AB * AB); + if (c2 <= c1) + return BP.norm(); + + real b = c1 / c2; + T Pb, PPb; + Pb = A + b * AB; + PPb = P - Pb; + + return PPb.norm(); + } + + // + // Non-templated procedures + // + ///////////////////////////////////////////////////////////////////////////// + + typedef enum { + DONT_INTERSECT, + DO_INTERSECT, + COLINEAR, + COINCIDENT + } intersection_test; + + LIB_GEOMETRY_EXPORT + intersection_test intersect2dSeg2dSeg(const Vec2r& p1, const Vec2r& p2, // first segment + const Vec2r& p3, const Vec2r& p4, // second segment + Vec2r& res); // found intersection point + + LIB_GEOMETRY_EXPORT + intersection_test intersect2dLine2dLine(const Vec2r& p1, const Vec2r& p2, // first segment + const Vec2r& p3, const Vec2r& p4, // second segment + Vec2r& res); // found intersection point + + LIB_GEOMETRY_EXPORT + intersection_test intersect2dSeg2dSegParametric(const Vec2r& p1, const Vec2r& p2, // first segment + const Vec2r& p3, const Vec2r& p4, // second segment + real& t, // I = P1 + t * P1P2) + real& u, // I = P3 + u * P3P4 + real epsilon = M_EPSILON); + + /*! check whether a 2D segment intersect a 2D region or not */ + LIB_GEOMETRY_EXPORT + bool intersect2dSeg2dArea(const Vec2r& min, + const Vec2r& max, + const Vec2r& A, + const Vec2r& B); + + /*! check whether a 2D segment is included in a 2D region or not */ + LIB_GEOMETRY_EXPORT + bool include2dSeg2dArea(const Vec2r& min, + const Vec2r& max, + const Vec2r& A, + const Vec2r& B); + + /*! Box-triangle overlap test, adapted from Tomas Akenine-Möller code */ + LIB_GEOMETRY_EXPORT + bool overlapTriangleBox(Vec3r& boxcenter, + Vec3r& boxhalfsize, + Vec3r triverts[3]); + + /*! Fast, Minimum Storage Ray-Triangle Intersection, + * adapted from Tomas Möller and Ben Trumbore code. + */ + LIB_GEOMETRY_EXPORT + bool intersectRayTriangle(Vec3r& orig, Vec3r& dir, + Vec3r& v0, Vec3r& v1, Vec3r& v2, + real& t, // I = orig + t * dir + real& u, real& v, // I = (1-u-v)*v0+u*v1+v*v2 + real epsilon = M_EPSILON); // the epsilon to use + + /*! Intersection between plane and ray + * adapted from Graphics Gems, Didier Badouel + */ + LIB_GEOMETRY_EXPORT + intersection_test intersectRayPlane(Vec3r& orig, Vec3r& dir, // ray origin and direction + Vec3r& norm, real d, // plane's normal and offset (plane = { P / P.N + d = 0 }) + real& t, // I = orig + t * dir + real epsilon = M_EPSILON); // the epsilon to use + + /*! Intersection Ray-Bounding box (axis aligned). + * Adapted from Williams et al, "An Efficient Robust Ray-Box Intersection Algorithm", + * JGT 10:1 (2005), pp. 49-54. + * Returns + */ + LIB_GEOMETRY_EXPORT + bool intersectRayBBox(const Vec3r& orig, const Vec3r& dir, // ray origin and direction + const Vec3r& boxMin, const Vec3r& boxMax, // the bbox + real t0, real t1, // the interval in which at least on of the intersections must happen + real& tmin, real& tmax, // Imin=orig+tmin*dir is the first intersection, Imax=orig+tmax*dir is the second intersection + real epsilon = M_EPSILON); // the epsilon to use + + + /*! Checks whether 3D point P lies inside or outside of the triangle ABC */ + LIB_GEOMETRY_EXPORT + bool includePointTriangle(Vec3r& P, + Vec3r& A, + Vec3r& B, + Vec3r& C); + + LIB_GEOMETRY_EXPORT + void transformVertex(const Vec3r& vert, + const Matrix44r& matrix, + Vec3r& res); + + LIB_GEOMETRY_EXPORT + void transformVertices(const vector<Vec3r>& vertices, + const Matrix44r& trans, + vector<Vec3r>& res); + + LIB_GEOMETRY_EXPORT + Vec3r rotateVector(const Matrix44r& mat, const Vec3r& v); + + // + // Coordinates systems changing procedures + // + ///////////////////////////////////////////////////////////////////////////// + + /*! From world to image + * p + * point's coordinates expressed in world coordinates system + * q + * vector in which the result will be stored + * model_view_matrix + * The model view matrix expressed in line major order (OpenGL + * matrices are column major ordered) + * projection_matrix + * The projection matrix expressed in line major order (OpenGL + * matrices are column major ordered) + * viewport + * The viewport: x,y coordinates followed by width and height (OpenGL like viewport) + */ + LIB_GEOMETRY_EXPORT + void fromWorldToImage(const Vec3r& p, + Vec3r& q, + const real model_view_matrix[4][4], + const real projection_matrix[4][4], + const int viewport[4]); + + /*! From world to image + * p + * point's coordinates expressed in world coordinates system + * q + * vector in which the result will be stored + * transform + * The transformation matrix (gathering model view and projection), + * expressed in line major order (OpenGL matrices are column major ordered) + * viewport + * The viewport: x,y coordinates followed by width and height (OpenGL like viewport) + */ + LIB_GEOMETRY_EXPORT + void fromWorldToImage(const Vec3r& p, + Vec3r& q, + const real transform[4][4], + const int viewport[4]); + + /*! Projects from world coordinates to camera coordinates + * Returns the point's coordinates expressed in the camera's + * coordinates system. + * p + * point's coordinates expressed in world coordinates system + * q + * vector in which the result will be stored + * model_view_matrix + * The model view matrix expressed in line major order (OpenGL + * matrices are column major ordered) + */ + LIB_GEOMETRY_EXPORT + void fromWorldToCamera(const Vec3r& p, + Vec3r& q, + const real model_view_matrix[4][4]); + + /*! Projects from World Coordinates to retina coordinates + * Returns the point's coordinates expressed in Retina system. + * p + * point's coordinates expressed in camera system + * q + * vector in which the result will be stored + * projection_matrix + * The projection matrix expressed in line major order (OpenGL + * matrices are column major ordered) + */ + LIB_GEOMETRY_EXPORT + void fromCameraToRetina(const Vec3r& p, + Vec3r& q, + const real projection_matrix[4][4]); + + /*! From retina to image. + * Returns the coordinates expressed in Image coorinates system. + * p + * point's coordinates expressed in retina system + * q + * vector in which the result will be stored + * viewport + * The viewport: x,y coordinates followed by width and height (OpenGL like viewport). + */ + LIB_GEOMETRY_EXPORT + void fromRetinaToImage(const Vec3r& p, + Vec3r& q, + const int viewport[4]); + + /*! From image to retina + * p + * point's coordinates expressed in image system + * q + * vector in which the result will be stored + * viewport + * The viewport: x,y coordinates followed by width and height (OpenGL like viewport). + */ + LIB_GEOMETRY_EXPORT + void fromImageToRetina(const Vec3r& p, + Vec3r& q, + const int viewport[4]); + + /*! computes the coordinates of q in the camera coordinates system, + * using the known z coordinates of the 3D point. + * That means that this method does not inverse any matrices, + * it only computes X and Y from x,y and Z) + * p + * point's coordinates expressed in retina system + * q + * vector in which the result will be stored + * projection_matrix + * The projection matrix expressed in line major order (OpenGL + * matrices are column major ordered) + + */ + LIB_GEOMETRY_EXPORT + void fromRetinaToCamera(const Vec3r& p, + Vec3r& q, + real z, + const real projection_matrix[4][4]); + + /*! Projects from camera coordinates to world coordinates + * Returns the point's coordinates expressed in the world's + * coordinates system. + * p + * point's coordinates expressed in the camera coordinates system + * q + * vector in which the result will be stored + * model_view_matrix + * The model view matrix expressed in line major order (OpenGL + * matrices are column major ordered) + */ + LIB_GEOMETRY_EXPORT + void fromCameraToWorld(const Vec3r& p, + Vec3r& q, + const real model_view_matrix[4][4]); + +} // end of namespace GeomUtils + +#endif // GEOMUTILS_H diff --git a/source/blender/freestyle/intern/geometry/Grid.cpp b/source/blender/freestyle/intern/geometry/Grid.cpp new file mode 100755 index 00000000000..2477227c410 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/Grid.cpp @@ -0,0 +1,388 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "Grid.h" +#include "BBox.h" +#include <cassert> +#include <stdexcept> + +// Grid Visitors +///////////////// +void allOccludersGridVisitor::examineOccluder(Polygon3r *occ){ + occluders_.push_back(occ); +} + +bool inBox(const Vec3r& inter, const Vec3r& box_min, const Vec3r& box_max){ + if(((inter.x()>=box_min.x()) && (inter.x() <box_max.x())) + && ((inter.y()>=box_min.y()) && (inter.y() <box_max.y())) + && ((inter.z()>=box_min.z()) && (inter.z() <box_max.z())) + ){ + return true; + } + return false; +} +void firstIntersectionGridVisitor::examineOccluder(Polygon3r *occ){ + + // check whether the edge and the polygon plane are coincident: + //------------------------------------------------------------- + //first let us compute the plane equation. + Vec3r v1(((occ)->getVertices())[0]); + Vec3d normal((occ)->getNormal()); + //soc unused - double d = -(v1 * normal); + + double tmp_u, tmp_v, tmp_t; + if((occ)->rayIntersect(ray_org_, ray_dir_, tmp_t, tmp_u, tmp_v)){ + if (fabs(ray_dir_ * normal) > 0.0001){ + // Check whether the intersection is in the cell: + if(inBox(ray_org_+tmp_t*ray_dir_/ray_dir_.norm(), current_cell_->getOrigin(), current_cell_->getOrigin()+cell_size_)){ + + //Vec3d bboxdiag(_scene3d->bbox().getMax()-_scene3d->bbox().getMin()); + //if ((t>1.0E-06*(min(min(bboxdiag.x(),bboxdiag.y()),bboxdiag.z()))) && (t<raylength)){ + if(tmp_t < t_){ + occluder_ = occ; + u_ = tmp_u; + v_ = tmp_v; + t_ = tmp_t; + } + }else{ + occ->userdata2 = 0; + } + } + } +} + +bool firstIntersectionGridVisitor::stop(){ + if(occluder_) + return true; + return false; +} + +// Grid +///////////////// + +void Grid::clear() { + if (_occluders.size() != 0) { + for(OccludersSet::iterator it = _occluders.begin(); + it != _occluders.end(); + it++) { + delete (*it); + } + _occluders.clear(); + } + + _size = Vec3r(0, 0, 0); + _cell_size = Vec3r(0, 0, 0); + _orig = Vec3r(0, 0, 0); + _cells_nb = Vec3u(0, 0, 0); + //_ray_occluders.clear(); +} + +void Grid::configure(const Vec3r& orig, + const Vec3r& size, + unsigned nb) { + + _orig = orig; + Vec3r tmpSize=size; + // Compute the volume of the desired grid + real grid_vol = size[0] * size[1] * size[2]; + + if(grid_vol == 0){ + double min=DBL_MAX; + int index=0; + int nzeros=0; + for(int i=0;i<3;++i){ + if(size[i] == 0){ + ++nzeros; + index=i; + } + if((size[i]!=0) && (min>size[i])){ + min=size[i]; + } + } + if(nzeros>1){ + throw std::runtime_error("Warning: the 3D grid has more than one null dimension"); + } + tmpSize[index]=min; + _orig[index] = _orig[index]-min/2; + } + // Compute the desired volume of a single cell + real cell_vol = grid_vol / nb; + // The edge of such a cubic cell is cubic root of cellVolume + real edge = pow(cell_vol, 1.0 / 3.0); + + // We compute the number of cells par edge + // such as we cover at least the whole box. + unsigned i; + for (i = 0; i < 3; i++) + _cells_nb[i] = (unsigned)floor(tmpSize[i] / edge) + 1; + + _size = tmpSize; + + for(i = 0; i < 3; i++) + _cell_size[i] = _size[i] / _cells_nb[i]; +} + +void Grid::insertOccluder(Polygon3r* occluder) { + const vector<Vec3r> vertices = occluder->getVertices(); + if (vertices.size() == 0) + return; + + // add this occluder to the grid's occluders list + addOccluder(occluder); + + // find the bbox associated to this polygon + Vec3r min, max; + occluder->getBBox(min, max); + + // Retrieve the cell x, y, z cordinates associated with these min and max + Vec3u imax, imin; + getCellCoordinates(max, imax); + getCellCoordinates(min, imin); + + // We are now going to fill in the cells overlapping with the + // polygon bbox. + // If the polygon is a triangle (most of cases), we also + // check for each of these cells if it is overlapping with + // the triangle in order to only fill in the ones really overlapping + // the triangle. + + unsigned i, x, y, z; + vector<Vec3r>::const_iterator it; + Vec3u coord; + + if (vertices.size() == 3) { // Triangle case + Vec3r triverts[3]; + i = 0; + for(it = vertices.begin(); + it != vertices.end(); + it++) { + triverts[i] = Vec3r(*it); + i++; + } + + Vec3r boxmin, boxmax; + + for (z = imin[2]; z <= imax[2]; z++) + for (y = imin[1]; y <= imax[1]; y++) + for (x = imin[0]; x <= imax[0]; x++) { + coord[0] = x; + coord[1] = y; + coord[2] = z; + // We retrieve the box coordinates of the current cell + getCellBox(coord, boxmin, boxmax); + // We check whether the triangle and the box ovewrlap: + Vec3r boxcenter((boxmin + boxmax) / 2.0); + Vec3r boxhalfsize(_cell_size / 2.0); + if (GeomUtils::overlapTriangleBox(boxcenter, boxhalfsize, triverts)) { + // We must then create the Cell and add it to the cells list + // if it does not exist yet. + // We must then add the occluder to the occluders list of this cell. + Cell* cell = getCell(coord); + if (!cell) { + cell = new Cell(boxmin); + fillCell(coord, *cell); + } + cell->addOccluder(occluder); + } + } + } + else { // The polygon is not a triangle, we add all the cells overlapping the polygon bbox. + for (z = imin[2]; z <= imax[2]; z++) + for (y = imin[1]; y <= imax[1]; y++) + for (x = imin[0]; x <= imax[0]; x++) { + coord[0] = x; + coord[1] = y; + coord[2] = z; + Cell* cell = getCell(coord); + if (!cell) { + Vec3r orig; + getCellOrigin(coord, orig); + cell = new Cell(orig); + fillCell(coord, *cell); + } + cell->addOccluder(occluder); + } + } +} + +bool Grid::nextRayCell(Vec3u& current_cell, Vec3u& next_cell) { + next_cell = current_cell; + real t_min, t; + unsigned i; + + t_min = FLT_MAX; // init tmin with handle of the case where one or 2 _u[i] = 0. + unsigned coord = 0; // predominant coord(0=x, 1=y, 2=z) + + + // using a parametric equation of + // a line : B = A + t u, we find + // the tx, ty and tz respectively coresponding + // to the intersections with the plans: + // x = _cell_size[0], y = _cell_size[1], z = _cell_size[2] + for (i = 0; i < 3; i++) { + if (_ray_dir[i] == 0) + continue; + if (_ray_dir[i] > 0) + t = (_cell_size[i] - _pt[i]) / _ray_dir[i]; + else + t = -_pt[i] / _ray_dir[i]; + if (t < t_min) { + t_min = t; + coord = i; + } + } + + // We use the parametric line equation and + // the found t (tamx) to compute the + // B coordinates: + Vec3r pt_tmp(_pt); + _pt = pt_tmp + t_min * _ray_dir; + + // We express B coordinates in the next cell + // coordinates system. We just have to + // set the coordinate coord of B to 0 + // of _CellSize[coord] depending on the sign + // of _u[coord] + if (_ray_dir[coord] > 0) { + next_cell[coord]++; + _pt[coord] -= _cell_size[coord]; + // if we are out of the grid, we must stop + if (next_cell[coord] >= _cells_nb[coord]) + return false; + } + else { + int tmp = next_cell[coord] - 1; + _pt[coord] = _cell_size[coord]; + if (tmp < 0) + return false; + next_cell[coord]--; + } + + _t += t_min; + if (_t >= _t_end) + return false; + + return true; +} + +void Grid::castRay(const Vec3r& orig, + const Vec3r& end, + OccludersSet& occluders, + unsigned timestamp) { + initRay(orig, end, timestamp); + allOccludersGridVisitor visitor(occluders); + castRayInternal(visitor); +} + +void Grid::castInfiniteRay(const Vec3r& orig, + const Vec3r& dir, + OccludersSet& occluders, + unsigned timestamp) { + Vec3r end = Vec3r(orig + FLT_MAX * dir / dir.norm()); + bool inter = initInfiniteRay(orig, dir, timestamp); + if(!inter) + return; + allOccludersGridVisitor visitor(occluders); + castRayInternal(visitor); +} + +Polygon3r* Grid::castRayToFindFirstIntersection(const Vec3r& orig, + const Vec3r& dir, + double& t, + double& u, + double& v, + unsigned timestamp){ + Polygon3r *occluder = 0; + Vec3r end = Vec3r(orig + FLT_MAX * dir / dir.norm()); + bool inter = initInfiniteRay(orig, dir, timestamp); + if(!inter){ + return 0; + } + firstIntersectionGridVisitor visitor(orig,dir,_cell_size); + castRayInternal(visitor); + occluder = visitor.occluder(); + t = visitor.t_; + u = visitor.u_; + v = visitor.v_; + return occluder; +} + +void Grid::initRay (const Vec3r &orig, + const Vec3r& end, + unsigned timestamp) { + _ray_dir = end - orig; + _t_end = _ray_dir.norm(); + _t = 0; + _ray_dir.normalize(); + _timestamp = timestamp; + + for(unsigned i = 0; i < 3; i++) { + _current_cell[i] = (unsigned)floor((orig[i] - _orig[i]) / _cell_size[i]); + //soc unused - unsigned u = _current_cell[i]; + _pt[i] = orig[i] - _orig[i] - _current_cell[i] * _cell_size[i]; + } + //_ray_occluders.clear(); + +} + +bool Grid::initInfiniteRay (const Vec3r &orig, + const Vec3r& dir, + unsigned timestamp) { + _ray_dir = dir; + _t_end = FLT_MAX; + _t = 0; + _ray_dir.normalize(); + _timestamp = timestamp; + + // check whether the origin is in or out the box: + Vec3r boxMin(_orig); + Vec3r boxMax(_orig+_size); + BBox<Vec3r> box(boxMin, boxMax); + if(box.inside(orig)){ + for(unsigned i = 0; i < 3; i++) { + _current_cell[i] = (unsigned)floor((orig[i] - _orig[i]) / _cell_size[i]); + //soc unused - unsigned u = _current_cell[i]; + _pt[i] = orig[i] - _orig[i] - _current_cell[i] * _cell_size[i]; + } + }else{ + // is the ray intersecting the box? + real tmin(-1.0), tmax(-1.0); + if(GeomUtils::intersectRayBBox(orig, _ray_dir, boxMin, boxMax, 0, _t_end, tmin, tmax)){ + assert(tmin != -1.0); + Vec3r newOrig = orig + tmin*_ray_dir; + for(unsigned i = 0; i < 3; i++) { + _current_cell[i] = (unsigned)floor((newOrig[i] - _orig[i]) / _cell_size[i]); + if(_current_cell[i] == _cells_nb[i]) + _current_cell[i] = _cells_nb[i] - 1; + //soc unused - unsigned u = _current_cell[i]; + _pt[i] = newOrig[i] - _orig[i] - _current_cell[i] * _cell_size[i]; + } + + }else{ + return false; + } + } + //_ray_occluders.clear(); + + return true; + +} + diff --git a/source/blender/freestyle/intern/geometry/Grid.h b/source/blender/freestyle/intern/geometry/Grid.h new file mode 100755 index 00000000000..e54b7b4d381 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/Grid.h @@ -0,0 +1,363 @@ +// +// Filename : Grid.h +// Author(s) : Stephane Grabli +// Purpose : Base class to define a cell grid surrounding +// the bounding box of the scene +// Date of creation : 30/07/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GRID_H +# define GRID_H + +# include <cstring> // for memset +# include <float.h> +# include <vector> +# include "../system/FreestyleConfig.h" +# include "GeomUtils.h" +# include "Geom.h" +# include "Polygon.h" + +using namespace std; +using namespace Geometry; + +typedef vector<Polygon3r*> OccludersSet; + + +// +// Class to define cells used by the regular grid +// +/////////////////////////////////////////////////////////////////////////////// + +class LIB_GEOMETRY_EXPORT Cell +{ + public: + + Cell(Vec3r& orig) { + _orig = orig; + } + + virtual ~Cell() {} + + inline void addOccluder(Polygon3r* o) { + if (o) + _occluders.push_back(o); + } + + inline const Vec3r& getOrigin() { + return _orig; + } + + inline OccludersSet& getOccluders() { + return _occluders; + } + + private: + + Vec3r _orig; + OccludersSet _occluders; +}; + + +class GridVisitor{ +public: + virtual ~GridVisitor() {}; //soc + virtual void discoverCell(Cell *cell) {} + virtual void examineOccluder(Polygon3r *occ) {} + virtual void finishCell(Cell *cell) {} + virtual bool stop() {return false;} +}; + +/*! Gathers all the occluders belonging to the cells + * traversed by the ray */ +class allOccludersGridVisitor : public GridVisitor{ +public: + allOccludersGridVisitor(OccludersSet& occluders) + :GridVisitor(), occluders_(occluders){} + virtual void examineOccluder(Polygon3r *occ); + + OccludersSet& occluders() {return occluders_;} + void clear() {occluders_.clear();} + +private: + OccludersSet& occluders_; +}; + +/*! Finds the first intersection and breaks. The occluder and + * the intersection information are stored and accessible. + */ +class firstIntersectionGridVisitor : public GridVisitor { + +//soc - changed order to remove warnings +public: + double u_, v_, t_; +private: + Polygon3r *occluder_; + Vec3r ray_org_, ray_dir_, cell_size_; + Cell * current_cell_; + +public: + firstIntersectionGridVisitor(const Vec3r& ray_org, const Vec3r& ray_dir, const Vec3r& cell_size) : + GridVisitor(), u_(0),v_(0),t_(DBL_MAX), + occluder_(0), + ray_org_(ray_org), ray_dir_(ray_dir), cell_size_(cell_size), + current_cell_(0) {} + virtual ~firstIntersectionGridVisitor() {} + + virtual void discoverCell(Cell *cell) {current_cell_=cell;} + virtual void examineOccluder(Polygon3r *occ); + virtual bool stop(); + + Polygon3r * occluder() {return occluder_;} +}; + +// +// Class to define a regular grid used for ray casting computations +// +/////////////////////////////////////////////////////////////////////////////// + +class LIB_GEOMETRY_EXPORT Grid +{ +public: + + /*! Builds a Grid + * Must be followed by a call to configure() + */ + Grid() {} + + virtual ~Grid() { + clear(); + } + + /*! clears the grid + * Deletes all the cells, clears the hashtable, + * resets size, size of cell, number of cells. + */ + virtual void clear(); + + /*! Sets the different parameters of the grid + * orig + * The grid origin + * size + * The grid's dimensions + * nb + * The number of cells of the grid + */ + virtual void configure(const Vec3r& orig, const Vec3r& size, unsigned nb); + + /*! returns a vector of integer containing the + * coordinates of the cell containing the point + * passed as argument + * p + * The point for which we're looking the cell + */ + inline void getCellCoordinates(const Vec3r& p, Vec3u& res) { + int tmp; + for (int i = 0; i < 3; i++) { + tmp = (int)((p[i] - _orig[i]) / _cell_size[i]); + if (tmp < 0) + res[i] = 0; + else if ((unsigned)tmp >= _cells_nb[i]) + res[i] = _cells_nb[i] - 1; + else + res[i] = tmp; + } + } + + /*! Fills the case corresponding to coord with the cell */ + virtual void fillCell(const Vec3u& coord, Cell& cell) = 0; + + /*! returns the cell whose coordinates + * are pased as argument + */ + virtual Cell* getCell(const Vec3u& coord) = 0; + + /*! returns the cell containing the point + * passed as argument. If the cell is empty + * (contains no occluder), NULL is returned + * p + * The point for which we're looking the cell + */ + inline Cell* getCell(const Vec3r& p) { + Vec3u coord; + getCellCoordinates(p, coord); + return getCell(coord); + } + + /*! Retrieves the x,y,z coordinates of the origin of the cell whose coordinates (i,j,k) + * is passed as argument + * cell_coord + * i,j,k integer coordinates for the cell + * orig + * x,y,x vector to be filled in with the cell origin's coordinates + */ + inline void getCellOrigin(const Vec3u& cell_coord, Vec3r& orig) { + for (unsigned i = 0; i < 3; i++) + orig[i] = _orig[i] + cell_coord[i] * _cell_size[i]; + } + + /*! Retrieves the box corresponding to the cell whose coordinates + * are passed as argument. + * cell_coord + * i,j,k integer coordinates for the cell + * min_out + * The min x,y,x vector of the box. Filled in by the method. + * max_out + * The max x,y,z coordinates of the box. Filled in by the method. + */ + inline void getCellBox(const Vec3u& cell_coord, Vec3r& min_out, Vec3r& max_out) { + getCellOrigin(cell_coord, min_out); + max_out = min_out + _cell_size; + } + + /*! inserts a convex polygon occluder + * This method is quite coarse insofar as it + * adds all cells intersecting the polygon bounding box + * convex_poly + * The list of 3D points constituing a convex polygon + */ + void insertOccluder(Polygon3r * convex_poly); + + /*! Adds an occluder to the list of occluders */ + void addOccluder(Polygon3r* occluder) { + _occluders.push_back(occluder); + } + + /*! Casts a ray between a starting point and an ending point + * Returns the list of occluders contained + * in the cells intersected by this ray + * Starts with a call to InitRay. + */ + void castRay(const Vec3r& orig, + const Vec3r& end, + OccludersSet& occluders, + unsigned timestamp); + + /*! Casts an infinite ray (still finishing at the end of the grid) from a starting point and in a given direction. + * Returns the list of occluders contained + * in the cells intersected by this ray + * Starts with a call to InitRay. + */ + void castInfiniteRay(const Vec3r& orig, + const Vec3r& dir, + OccludersSet& occluders, + unsigned timestamp); + + /*! Casts an infinite ray (still finishing at the end of the grid) from a starting point and in a given direction. + * Returns the first intersection (occluder,t,u,v) or null. + * Starts with a call to InitRay. + */ + Polygon3r * castRayToFindFirstIntersection(const Vec3r& orig, + const Vec3r& dir, + double& t, + double& u, + double& v, + unsigned timestamp); + + + /*! Init all structures and values for computing + * the cells intersected by this new ray + */ + void initRay (const Vec3r &orig, + const Vec3r& end, + unsigned timestamp); + + /*! Init all structures and values for computing + * the cells intersected by this infinite ray. + * Returns false if the ray doesn't intersect the + * grid. + */ + bool initInfiniteRay (const Vec3r &orig, + const Vec3r& dir, + unsigned timestamp); + + + /*! Accessors */ + inline const Vec3r& getOrigin() const { + return _orig; + } + inline Vec3r gridSize() const { + return _size; + } + inline Vec3r getCellSize() const { + return _cell_size; + } + + void displayDebug() { + cerr << "Cells nb : " << _cells_nb << endl; + cerr << "Cell size : " << _cell_size << endl; + cerr << "Origin : " << _orig << endl; + cerr << "Occluders nb : " << _occluders.size() << endl; + } + + protected: + + /*! Core of castRay and castInfiniteRay, find occluders + * along the given ray + */ + inline void castRayInternal(GridVisitor& visitor) { + Cell* current_cell = NULL; + do { + current_cell = getCell(_current_cell); + if (current_cell){ + visitor.discoverCell(current_cell); + OccludersSet& occluders = current_cell->getOccluders(); // FIXME: I had forgotten the ref & + for (OccludersSet::iterator it = occluders.begin(); + it != occluders.end(); + it++) { + if ((unsigned long)(*it)->userdata2 != _timestamp) { + (*it)->userdata2 = (void*)_timestamp; + visitor.examineOccluder(*it); + } + } + visitor.finishCell(current_cell); + } + } while ((!visitor.stop()) && (nextRayCell(_current_cell, _current_cell))); + } + + + /*! returns the cell next to the cell + * passed as argument. + */ + bool nextRayCell(Vec3u& current_cell, Vec3u& next_cell); + + unsigned _timestamp; + + Vec3u _cells_nb; // number of cells for x,y,z axis + Vec3r _cell_size; // cell x,y,z dimensions + Vec3r _size; // grid x,y,x dimensions + Vec3r _orig; // grid origin + + Vec3r _ray_dir; // direction vector for the ray + Vec3u _current_cell; // The current cell being processed (designated by its 3 coordinates) + Vec3r _pt; // Points corresponding to the incoming and outgoing intersections + // of one cell with the ray + real _t_end; // To know when we are at the end of the ray + real _t; + + //OccludersSet _ray_occluders; // Set storing the occluders contained in the cells traversed by a ray + OccludersSet _occluders; // List of all occluders inserted in the grid +}; + +#endif // GRID_H diff --git a/source/blender/freestyle/intern/geometry/HashGrid.cpp b/source/blender/freestyle/intern/geometry/HashGrid.cpp new file mode 100755 index 00000000000..3cf845d57ef --- /dev/null +++ b/source/blender/freestyle/intern/geometry/HashGrid.cpp @@ -0,0 +1,41 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "HashGrid.h" + +void HashGrid::clear() +{ + if(!_cells.empty()) { + for(GridHashTable::iterator it = _cells.begin(); + it !=_cells.end(); + it++) { + Cell* cell = (*it).second; + delete cell; + } + _cells.clear(); + } + + Grid::clear(); +} + +void HashGrid::configure(const Vec3r& orig, const Vec3r& size, unsigned nb) { + Grid::configure(orig, size, nb); +} diff --git a/source/blender/freestyle/intern/geometry/HashGrid.h b/source/blender/freestyle/intern/geometry/HashGrid.h new file mode 100755 index 00000000000..f6605957676 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/HashGrid.h @@ -0,0 +1,109 @@ +// +// Filename : HashGrid.h +// Author(s) : Stephane Grabli +// Purpose : Class to define a cell grid surrounding the +// bounding box of the scene +// Date of creation : 30/07/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef HASHGRID_H +# define HASHGRID_H + +//# if defined(__GNUC__) && (__GNUC__ >= 3) +// hash_map is not part of the C++ standard anymore; +// hash_map.h has been kept though for backward compatibility +//# include <hash_map.h> +//# else +//# include <hash_map> +//# endif + +# include "Grid.h" +# include <map> +/*! Defines a hash table used for searching the Cells */ +struct GridHasher{ +#define _MUL 950706376UL +#define _MOD 2147483647UL + inline size_t operator() (const Vec3u& p) const + { + size_t res = ((unsigned long) (p[0] * _MUL)) % _MOD; + res = ((res + (unsigned long) (p[1]) * _MUL)) % _MOD; + return ((res +(unsigned long) (p[2]) * _MUL)) % _MOD; + } +}; + +/*! Class to define a regular grid used for ray + casting computations */ + +class LIB_GEOMETRY_EXPORT HashGrid : public Grid +{ + public: + + typedef map<Vec3u, Cell*> GridHashTable; + + HashGrid() : Grid() {} + + virtual ~HashGrid() { + clear(); + } + + /*! clears the grid + * Deletes all the cells, clears the hashtable, + * resets size, size of cell, number of cells. + */ + virtual void clear(); + + /*! Sets the different parameters of the grid + * orig + * The grid origin + * size + * The grid's dimensions + * nb + * The number of cells of the grid + */ + virtual void configure(const Vec3r& orig, const Vec3r& size, unsigned nb); + + /*! returns the cell whose coordinates + * are pased as argument + */ + virtual Cell* getCell(const Vec3u& p) { + Cell* found_cell = NULL; + + GridHashTable::const_iterator found = _cells.find(p); + if (found != _cells.end()) + found_cell = (*found).second; + return found_cell; + } + + /*! Fills the case p with the cell iCell */ + virtual void fillCell(const Vec3u& p, Cell& cell) { + _cells[p] = &cell; + } + +protected: + + GridHashTable _cells; +}; + +#endif // HASHGRID_H diff --git a/source/blender/freestyle/intern/geometry/Noise.cpp b/source/blender/freestyle/intern/geometry/Noise.cpp new file mode 100755 index 00000000000..396fc3bbb47 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/Noise.cpp @@ -0,0 +1,264 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "Noise.h" +# include <stdlib.h> +# include <stdio.h> +# include <math.h> +#include <time.h> + +#define MINX -1000000 +#define MINY MINX +#define MINZ MINX +#define SCURVE(a) ((a)*(a)*(3.0-2.0*(a))) +#define REALSCALE ( 2.0 / 65536.0 ) +#define NREALSCALE ( 2.0 / 4096.0 ) +#define HASH3D(a,b,c) hashTable[hashTable[hashTable[(a) & 0xfff] ^ ((b) & 0xfff)] ^ ((c) & 0xfff)] +#define HASH(a,b,c) (xtab[(xtab[(xtab[(a) & 0xff] ^ (b)) & 0xff] ^ (c)) & 0xff] & 0xff) +#define INCRSUM(m,s,x,y,z) ((s)*(RTable[m]*0.5 \ + + RTable[m+1]*(x) \ + + RTable[m+2]*(y) \ + + RTable[m+3]*(z))) +#define MAXSIZE 500 +#define nrand() ((float)rand()/(float)RAND_MAX) +#define seednrand(x) srand(x*RAND_MAX) + +#define BM 0xff + +#define N 0x1000 +#define NP 12 /* 2^N */ +#define NM 0xfff + +#define s_curve(t) ( t * t * (3. - 2. * t) ) + +#define lerp(t, a, b) ( a + t * (b - a) ) + +#define setup(i,b0,b1,r0,r1)\ + t = i + N;\ + b0 = ((int)t) & BM;\ + b1 = (b0+1) & BM;\ + r0 = t - (int)t;\ + r1 = r0 - 1.; + +void normalize2(float v[2]) +{ + float s; + + s = sqrt(v[0] * v[0] + v[1] * v[1]); + v[0] = v[0] / s; + v[1] = v[1] / s; +} + +void normalize3(float v[3]) +{ + float s; + + s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + v[0] = v[0] / s; + v[1] = v[1] / s; + v[2] = v[2] / s; +} + +float Noise::turbulence1(float arg, float freq, float amp, unsigned oct) +{ + float t; + float vec; + + for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) + { + vec = freq * arg; + t += smoothNoise1(vec) * amp; + } + return t; +} + +float Noise::turbulence2(Vec2f& v, float freq, float amp, unsigned oct) +{ + float t; + Vec2f vec; + + for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) + { + vec.x() = freq * v.x(); + vec.y() = freq * v.y(); + t += smoothNoise2(vec) * amp; + } + return t; +} + +float Noise::turbulence3(Vec3f& v, float freq, float amp, unsigned oct) +{ + float t; + Vec3f vec; + + for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) + { + vec.x() = freq * v.x(); + vec.y() = freq * v.y(); + vec.z() = freq * v.z(); + t += smoothNoise3(vec) * amp; + } + return t; +} + +// Noise functions over 1, 2, and 3 dimensions + +float Noise::smoothNoise1(float arg) +{ + int bx0, bx1; + float rx0, rx1, sx, t, u, v, vec; + + vec = arg; + setup(vec, bx0,bx1, rx0,rx1); + + sx = s_curve(rx0); + + u = rx0 * g1[ p[ bx0 ] ]; + v = rx1 * g1[ p[ bx1 ] ]; + + return lerp(sx, u, v); +} + +float Noise::smoothNoise2(Vec2f& vec) +{ + int bx0, bx1, by0, by1, b00, b10, b01, b11; + float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v; + register int i, j; + + setup(vec.x(), bx0,bx1, rx0,rx1); + setup(vec.y(), by0,by1, ry0,ry1); + + i = p[ bx0 ]; + j = p[ bx1 ]; + + b00 = p[ i + by0 ]; + b10 = p[ j + by0 ]; + b01 = p[ i + by1 ]; + b11 = p[ j + by1 ]; + + sx = s_curve(rx0); + sy = s_curve(ry0); + +#define at2(rx,ry) ( rx * q[0] + ry * q[1] ) + + q = g2[ b00 ] ; u = at2(rx0,ry0); + q = g2[ b10 ] ; v = at2(rx1,ry0); + a = lerp(sx, u, v); + + q = g2[ b01 ] ; u = at2(rx0,ry1); + q = g2[ b11 ] ; v = at2(rx1,ry1); + b = lerp(sx, u, v); + + return lerp(sy, a, b); +} + +float Noise::smoothNoise3(Vec3f& vec) +{ + int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; + float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; + register int i, j; + + setup(vec.x(), bx0,bx1, rx0,rx1); + setup(vec.y(), by0,by1, ry0,ry1); + setup(vec.z(), bz0,bz1, rz0,rz1); + + i = p[ bx0 ]; + j = p[ bx1 ]; + + b00 = p[ i + by0 ]; + b10 = p[ j + by0 ]; + b01 = p[ i + by1 ]; + b11 = p[ j + by1 ]; + + t = s_curve(rx0); + sy = s_curve(ry0); + sz = s_curve(rz0); + +#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] ) + + q = g3[ b00 + bz0 ] ; + u = at3(rx0,ry0,rz0); + q = g3[ b10 + bz0 ] ; + v = at3(rx1,ry0,rz0); + a = lerp(t, u, v); + + q = g3[ b01 + bz0 ] ; + u = at3(rx0,ry1,rz0); + q = g3[ b11 + bz0 ] ; + v = at3(rx1,ry1,rz0); + b = lerp(t, u, v); + + c = lerp(sy, a, b); + + q = g3[ b00 + bz1 ] ; + u = at3(rx0,ry0,rz1); + q = g3[ b10 + bz1 ] ; + v = at3(rx1,ry0,rz1); + a = lerp(t, u, v); + + q = g3[ b01 + bz1 ] ; + u = at3(rx0,ry1,rz1); + q = g3[ b11 + bz1 ] ; + v = at3(rx1,ry1,rz1); + b = lerp(t, u, v); + + d = lerp(sy, a, b); + + return lerp(sz, c, d); +} + +Noise::Noise() +{ + int i, j, k; + + seednrand(time(NULL)); + for (i = 0 ; i < _Noise_B_ ; i++) + { + p[i] = i; + + g1[i] = (float)((rand() % (_Noise_B_ + _Noise_B_)) - _Noise_B_) / _Noise_B_; + + for (j = 0 ; j < 2 ; j++) + g2[i][j] = (float)((rand() % (_Noise_B_ + _Noise_B_)) - _Noise_B_) / _Noise_B_; + normalize2(g2[i]); + + for (j = 0 ; j < 3 ; j++) + g3[i][j] = (float)((rand() % (_Noise_B_ + _Noise_B_)) - _Noise_B_) / _Noise_B_; + normalize3(g3[i]); + } + + while (--i) + { + k = p[i]; + p[i] = p[j = rand() % _Noise_B_]; + p[j] = k; + } + + for (i = 0 ; i < _Noise_B_ + 2 ; i++) + { + p[_Noise_B_ + i] = p[i]; + g1[_Noise_B_ + i] = g1[i]; + for (j = 0 ; j < 2 ; j++) + g2[_Noise_B_ + i][j] = g2[i][j]; + for (j = 0 ; j < 3 ; j++) + g3[_Noise_B_ + i][j] = g3[i][j]; + } +} diff --git a/source/blender/freestyle/intern/geometry/Noise.h b/source/blender/freestyle/intern/geometry/Noise.h new file mode 100755 index 00000000000..00cebbb451e --- /dev/null +++ b/source/blender/freestyle/intern/geometry/Noise.h @@ -0,0 +1,77 @@ +// +// Filename : Noise.h +// Author(s) : Emmanuel Turquin +// Purpose : Class to define Perlin noise +// Date of creation : 12/01/2004 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NOISE_H +# define NOISE_H + + +# include "../system/FreestyleConfig.h" +# include "Geom.h" + +#define _Noise_B_ 0x100 + +using namespace Geometry; +using namespace std; + +/*! Class to provide Perlin Noise functionalities */ +class LIB_GEOMETRY_EXPORT Noise +{ + public: + + /*! Builds a Noise object */ + Noise(); + /*! Destructor */ + ~Noise() {} + + /*! Returns a noise value for a 1D element */ + float turbulence1(float arg, float freq, float amp, unsigned oct = 4); + + /*! Returns a noise value for a 2D element */ + float turbulence2(Vec2f& v, float freq, float amp, unsigned oct = 4); + + /*! Returns a noise value for a 3D element */ + float turbulence3(Vec3f& v, float freq, float amp, unsigned oct = 4); + + /*! Returns a smooth noise value for a 1D element */ + float smoothNoise1(float arg); + /*! Returns a smooth noise value for a 2D element */ + float smoothNoise2(Vec2f& vec); + /*! Returns a smooth noise value for a 3D element */ + float smoothNoise3(Vec3f& vec); + + private: + + int p[ _Noise_B_ + _Noise_B_ + 2]; + float g3[ _Noise_B_ + _Noise_B_ + 2][3]; + float g2[ _Noise_B_ + _Noise_B_ + 2][2]; + float g1[ _Noise_B_ + _Noise_B_ + 2]; + int start; +}; + +#endif // NOISE_H diff --git a/source/blender/freestyle/intern/geometry/Polygon.h b/source/blender/freestyle/intern/geometry/Polygon.h new file mode 100755 index 00000000000..f9c4c78d424 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/Polygon.h @@ -0,0 +1,215 @@ +// +// Filename : Polygon.h +// Author(s) : Stephane Grabli +// Purpose : Class to define a polygon +// Date of creation : 30/07/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef POLYGON_H +# define POLYGON_H + +# include <vector> +# include "Geom.h" +# include "GeomUtils.h" + +using namespace std; + +namespace Geometry { + +template <class Point> +class Polygon +{ + public: + + inline Polygon() { + _id = 0; + userdata = 0; + userdata2 = 0; + } + + inline Polygon(const vector<Point>& vertices) { + _vertices = vertices; + computeBBox(); + _id = 0; + userdata = 0; + userdata2 = 0; + } + + inline Polygon(const Polygon<Point>& poly) { + Point p; + for(typename vector<Point>::const_iterator it = poly.getVertices().begin(); + it != poly.getVertices().end(); + it++) { + p = *it; + _vertices.push_back(p); + } + + _id = poly.getId(); + poly.getBBox(_min, _max); + userdata = 0; + userdata2 = 0; + } + + virtual ~Polygon() {} + + // + // Accessors + // + ///////////////////////////////////////////////////////////////////////////// + + inline const vector<Point>& getVertices() const { + return _vertices; + } + + inline void getBBox(Point& min, Point& max) const { + min = _min; + max = _max; + } + + inline Point& getBBoxCenter() + { + Point result; + result = (_min + _max) / 2; + return result; + } + + inline Point& getCenter() { + Point result; + for (typename vector<Point>::iterator it = _vertices.begin(); + it != _vertices.end(); + it++) + result += *it; + result /= _vertices.size(); + return result; + } + + inline unsigned getId() const { + return _id; + } + + // + // Modifiers + // + ///////////////////////////////////////////////////////////////////////////// + + inline void setVertices(const vector<Point>& vertices) { + _vertices.clear(); + Point p; + for (typename vector<Point>::const_iterator it = vertices.begin(); + it != vertices.end(); + it++) { + p = *it; + _vertices.push_back(p); + } + computeBBox(); + } + + inline void setId(unsigned id) { + _id = id; + } + + // + // Other methods + // + ///////////////////////////////////////////////////////////////////////////// + + inline void computeBBox() { + if(_vertices.empty()) + return; + + _max = _vertices[0]; + _min = _vertices[0]; + + for(typename vector<Point>::iterator it = _vertices.begin(); + it != _vertices.end(); + it++) { + for(unsigned i = 0; i < Point::dim(); i++) { + if((*it)[i] > _max[i]) + _max[i] = (*it)[i]; + if((*it)[i] < _min[i]) + _min[i] = (*it)[i]; + } + } + } + + // FIXME Is it possible to get rid of userdatas ? + void* userdata; + void* userdata2; // Used during ray casting + + protected: + + vector<Point> _vertices; + Point _min; + Point _max; + unsigned _id; +}; + + +// +// Polygon3r class +// +/////////////////////////////////////////////////////////////////////////////// + +class Polygon3r : public Polygon<Vec3r> +{ + public: + + inline Polygon3r() : Polygon<Vec3r>() {} + + inline Polygon3r(const vector<Vec3r>& vertices, + const Vec3r& normal) : Polygon<Vec3r>(vertices) { + setNormal(normal); + } + + inline Polygon3r(const Polygon3r& poly) : Polygon<Vec3r>(poly) {} + + virtual ~Polygon3r() {} + + void setNormal(const Vec3r& normal) { + _normal = normal; + } + + Vec3r getNormal() const { + return _normal; + } + + /*! Check whether the Polygon intersects with the ray or not */ + inline bool rayIntersect(Vec3r& orig, Vec3r& dir, + real& t, real& u, real& v, real epsilon = M_EPSILON) { + // if (_vertices.size() < 3) + // return false; + return GeomUtils::intersectRayTriangle(orig, dir, + _vertices[0], _vertices[1], _vertices[2], + t, u, v, epsilon); + } + + private: + + Vec3r _normal; +}; + +} // end of namespace Geometry + +#endif // POLYGON_H diff --git a/source/blender/freestyle/intern/geometry/SweepLine.h b/source/blender/freestyle/intern/geometry/SweepLine.h new file mode 100755 index 00000000000..cf4c86d006d --- /dev/null +++ b/source/blender/freestyle/intern/geometry/SweepLine.h @@ -0,0 +1,336 @@ +// +// Filename : SweepLine.h +// Author(s) : Stephane Grabli +// Purpose : Class to define a Sweep Line +// Date of creation : 29/08/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef SWEEPLINE_H +# define SWEEPLINE_H + +# include <list> +# include <vector> + +/*! Class to define the intersection berween two segments*/ +template<class Edge> +class Intersection +{ +public: + + template<class EdgeClass> + Intersection(EdgeClass* eA, real ta, EdgeClass* eB, real tb) + { + EdgeA = eA; + EdgeB = eB; + tA = ta; + tB = tb; + userdata = 0; + } + + Intersection(const Intersection& iBrother) + { + EdgeA = iBrother.EdgeA; + EdgeB = iBrother.EdgeB; + tA = iBrother.tA; + tB = iBrother.tB; + userdata = 0; + } + + /*! returns the parameter giving the + * intersection, for the edge iEdge + */ + real getParameter(Edge *iEdge) + { + if(iEdge == EdgeA) + return tA; + if(iEdge == EdgeB) + return tB; + return 0; + } + +public: + void * userdata; // FIXME + + Edge *EdgeA; // first segment + Edge *EdgeB; // second segment + real tA; // parameter defining the intersection point with respect to the segment EdgeA. + real tB; // parameter defining the intersection point with respect to the segment EdgeB. +}; + + + + + + + + +template<class T, class Point> +class Segment +{ + public: + Segment() + { + } + Segment(T& s, const Point& iA, const Point& iB) + { + _edge = s; + if(iA < iB) + { + A = iA; + B = iB; + _order = true; + } + else + { + A = iB; + B = iA; + _order = false; + } + } + + Segment(Segment<T,Point>& iBrother) + { + _edge = iBrother.edge(); + A = iBrother.A; + B = iBrother.B; + _Intersections = iBrother._Intersections; + _order = iBrother._order; + } + + Segment(const Segment<T,Point>& iBrother) + { + _edge = iBrother._edge; + A = iBrother.A; + B = iBrother.B; + _Intersections = iBrother._Intersections; + _order = iBrother._order; + } + + ~Segment() { + _Intersections.clear(); + } + + inline Point operator[](const unsigned short int& i) const + { + return i%2==0 ? A : B; + } + + inline bool operator==(const Segment<T,Point>& iBrother) + { + if(_edge == iBrother._edge) + return true; + + return false; + } + + /* Adds an intersection for this segment */ + inline void AddIntersection(Intersection<Segment<T,Point> > *i) {_Intersections.push_back(i);} + + /*! Checks for a common vertex with another edge */ + inline bool CommonVertex(const Segment<T,Point>& S, Point& CP) + { + if((A == S[0]) || (A == S[1])) + { + CP = A; + return true; + } + if((B == S[0]) || (B == S[1])) + { + CP = B; + return true; + } + + return false; + } + + inline vector<Intersection<Segment<T,Point> >*>& intersections() {return _Intersections;} + inline bool order() {return _order;} + inline T& edge() {return _edge;} + + private: + T _edge; + Point A; + Point B; + std::vector<Intersection<Segment<T,Point> >*> _Intersections; // list of intersections parameters + bool _order; // true if A and B are in the same order than _edge.A and _edge.B. false otherwise. +}; + +/*! defines a binary function that can be overload + * by the user to specify at each condition + * the intersection between 2 edges must be computed + */ +template<class T1, class T2> +struct binary_rule +{ + binary_rule() {} + template<class T3,class T4> + binary_rule(const binary_rule<T3,T4>& brother) {} + virtual ~binary_rule() {} + + virtual bool operator()(T1&, T2&) + { + return true; + } +}; + + +template<class T,class Point> +class SweepLine +{ +public: + + SweepLine() {} + ~SweepLine() + { + for(typename vector<Intersection<Segment<T,Point> >*>::iterator i=_Intersections.begin(),iend=_Intersections.end(); + i!=iend; + i++) + { + delete (*i); + } + _Intersections.clear(); + + for(typename vector<Segment<T,Point>* >::iterator ie=_IntersectedEdges.begin(),ieend=_IntersectedEdges.end(); + ie!=ieend; + ie++) + { + delete (*ie); + } + _IntersectedEdges.clear(); + + _set.clear(); + } + + + inline void process(Point& p, + vector<Segment<T,Point>*>& segments, + binary_rule<Segment<T,Point>,Segment<T,Point> >& binrule, + //binary_rule<Segment<T,Point>,Segment<T,Point> >& binrule = binary_rule<Segment<T,Point>,Segment<T,Point> >(), + real epsilon = M_EPSILON + ) + { + // first we remove the segments that need to be removed and then + // we add the segments to add + vector<Segment<T,Point>*> toadd; + typename vector<Segment<T,Point>*>::iterator s, send; + for(s=segments.begin(), send=segments.end(); + s!=send; + s++) + { + if(p == (*(*s))[0]) + toadd.push_back((*s)); + else + remove((*s)); + } + for(s=toadd.begin(), send=toadd.end(); + s!=send; + s++) + { + add((*s), binrule, epsilon); + } + } + + inline void add(Segment<T,Point>* S, + binary_rule<Segment<T,Point>,Segment<T,Point> >& binrule, + //binary_rule<Segment<T,Point>,Segment<T,Point> >& binrule = binary_rule<Segment<T,Point>, Segment<T,Point> >(), + real epsilon + ) + { + real t,u; + Point CP; + Vec2r v0, v1, v2, v3; + if(true == S->order()) + { + v0[0] = ((*S)[0])[0]; + v0[1] = ((*S)[0])[1]; + v1[0] = ((*S)[1])[0]; + v1[1] = ((*S)[1])[1]; + } + else + { + v1[0] = ((*S)[0])[0]; + v1[1] = ((*S)[0])[1]; + v0[0] = ((*S)[1])[0]; + v0[1] = ((*S)[1])[1]; + } + for(typename std::list<Segment<T,Point>* >::iterator s=_set.begin(), send=_set.end(); + s!=send; + s++) + { + Segment<T,Point>* currentS = (*s); + if(true != binrule(*S, *currentS)) + continue; + + if(true == currentS->order()) + { + v2[0] = ((*currentS)[0])[0]; + v2[1] = ((*currentS)[0])[1]; + v3[0] = ((*currentS)[1])[0]; + v3[1] = ((*currentS)[1])[1]; + } + else + { + v3[0] = ((*currentS)[0])[0]; + v3[1] = ((*currentS)[0])[1]; + v2[0] = ((*currentS)[1])[0]; + v2[1] = ((*currentS)[1])[1]; + } + if(S->CommonVertex(*currentS, CP)) + continue; // the two edges have a common vertex->no need to check + + if(GeomUtils::intersect2dSeg2dSegParametric(v0, v1, v2, v3, t, u, epsilon) == GeomUtils::DO_INTERSECT) + { + // create the intersection + Intersection<Segment<T,Point> > * inter = new Intersection<Segment<T,Point> >(S,t,currentS,u); + // add it to the intersections list + _Intersections.push_back(inter); + // add this intersection to the first edge intersections list + S->AddIntersection(inter); + // add this intersection to the second edge intersections list + currentS->AddIntersection(inter); + } + } + // add the added segment to the list of active segments + _set.push_back(S); + } + + inline void remove(Segment<T,Point>* s) + { + if(s->intersections().size() > 0) + _IntersectedEdges.push_back(s); + _set.remove(s); + } + + vector<Segment<T,Point>* >& intersectedEdges() {return _IntersectedEdges;} + vector<Intersection<Segment<T,Point> >*>& intersections() {return _Intersections;} + + +private: + std::list<Segment<T,Point>* > _set; // set of active edges for a given position of the sweep line + std::vector<Segment<T,Point>* > _IntersectedEdges; // the list of intersected edges + std::vector<Intersection<Segment<T,Point> >*> _Intersections; // the list of all intersections. +}; + +#endif // SWEEPLINE_H diff --git a/source/blender/freestyle/intern/geometry/VecMat.h b/source/blender/freestyle/intern/geometry/VecMat.h new file mode 100755 index 00000000000..9bbec3b1349 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/VecMat.h @@ -0,0 +1,899 @@ +// +// Filename : VecMat.h +// Author(s) : Sylvain Paris +// Emmanuel Turquin +// Stephane Grabli +// Purpose : Vectors and Matrices definition and manipulation +// Date of creation : 12/06/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef VECMAT_H +# define VECMAT_H + +# include <math.h> +# include <vector> +# include <iostream> + +namespace VecMat { + + namespace Internal { + + template <bool B> + struct is_false {}; + + template <> + struct is_false<false> { + static inline void ensure() {} + }; + + } // end of namespace Internal + + // + // Vector class + // - T: value type + // - N: dimension + // + ///////////////////////////////////////////////////////////////////////////// + + template <class T, unsigned N> + class Vec + { + public: + + typedef T value_type; + + // constructors + + inline Vec() { + for (unsigned i = 0; i < N; i++) + this->_coord[i] = 0; + } + + ~Vec() { + Internal::is_false<(N == 0)>::ensure(); + } + + template <class U> + explicit inline Vec(const U tab[N]) { + for (unsigned i = 0; i < N; i++) + this->_coord[i] = (T)tab[i]; + } + + template <class U> + explicit inline Vec(const std::vector<U>& tab) { + for (unsigned i = 0; i < N; i++) + this->_coord[i] = (T)tab[i]; + } + + template <class U> + explicit inline Vec(const Vec<U, N>& v) { + for (unsigned i = 0; i < N; i++) + this->_coord[i] = (T)v[i]; + } + + // accessors + + inline value_type operator[](const unsigned i) const { + return this->_coord[i]; + } + + inline value_type& operator[](const unsigned i) { + return this->_coord[i]; + } + + static inline unsigned dim() { + return N; + } + + // various useful methods + + inline value_type norm() const { + return (T)sqrt((float)squareNorm()); + } + + inline value_type squareNorm() const { + return (*this) * (*this); + } + + inline Vec<T, N>& normalize() { + value_type n = norm(); + for (unsigned i = 0; i < N; i++) + this->_coord[i] /= n; + return *this; + } + + inline Vec<T, N>& normalizeSafe() { + value_type n = norm(); + if (n) + for (unsigned i=0; i < N; i++) + this->_coord[i] /= n; + return *this; + } + + // classical operators + inline Vec<T, N> operator+(const Vec<T, N>& v) const{ + Vec<T, N> res(v); + res += *this; + return res; + } + + inline Vec<T, N> operator-(const Vec<T,N>& v) const{ + Vec<T, N> res(*this); + res -= v; + return res; + } + + inline Vec<T, N> operator*(const typename Vec<T,N>::value_type r) const{ + Vec<T, N> res(*this); + res *= r; + return res; + } + + inline Vec<T, N> operator/(const typename Vec<T,N>::value_type r) const{ + Vec<T, N> res(*this); + if (r) + res /= r; + return res; + } + + // dot product + inline value_type operator*(const Vec<T, N>& v) const{ + value_type sum = 0; + for (unsigned i = 0; i < N; i++) + sum += (*this)[i] * v[i]; + return sum; + } + + template <class U> + inline Vec<T, N>& operator=(const Vec<U, N>& v) { + if (this != &v) + for (unsigned i = 0; i < N; i++) + this->_coord[i] = (T)v[i]; + return *this; + } + + template <class U> + inline Vec<T, N>& operator+=(const Vec<U, N>& v) { + for (unsigned i = 0 ; i < N; i++) + this->_coord[i] += (T)v[i]; + return *this; + } + + template <class U> + inline Vec<T, N>& operator-=(const Vec<U, N>& v) { + for (unsigned i = 0 ; i < N; i++) + this->_coord[i] -= (T)v[i]; + return *this; + } + + template <class U> + inline Vec<T, N>& operator*=(const U r) { + for (unsigned i = 0 ; i < N; i++) + this->_coord[i] *= r; + return *this; + } + + template <class U> + inline Vec<T, N>& operator/=(const U r) { + if (r) + for (unsigned i = 0 ; i < N; i++) + this->_coord[i] /= r; + return *this; + } + + + inline bool operator==(const Vec<T, N>& v) const { + for(unsigned i = 0; i < N; i++) + if (this->_coord[i] != v[i]) + return false; + return true; + } + + inline bool operator!=(const Vec<T, N>& v) const { + for(unsigned i = 0; i < N; i++) + if (this->_coord[i] != v[i]) + return true; + return false; + } + + inline bool operator<(const Vec<T, N>& v) const { + for (unsigned i = 0; i<N; i++) { + if (this->_coord[i] < v[i]) + return true; + if (this->_coord[i] > v[i]) + return false; + if (this->_coord[i] == v[i]) + continue; + } + return false; + } + + inline bool operator>(const Vec<T, N>& v) const { + for (unsigned i=0; i<N; i++) { + if(this->_coord[i] > v[i]) + return true; + if(this->_coord[i] < v[i]) + return false; + if(this->_coord[i] == v[i]) + continue; + } + return false; + } + + protected: + + value_type _coord[N]; + enum { + _dim = N, + }; + }; + + + // + // Vec2 class (2D Vector) + // - T: value type + // + ///////////////////////////////////////////////////////////////////////////// + + template <class T> + class Vec2 : public Vec<T, 2> + { + public: + + typedef typename Vec<T, 2>::value_type value_type; + + inline Vec2() : Vec<T, 2>() {} + + template <class U> + explicit inline Vec2(const U tab[2]) : Vec<T, 2>(tab) {} + + template <class U> + explicit inline Vec2(const std::vector<U>& tab) : Vec<T, 2>(tab) {} + + template <class U> + inline Vec2(const Vec<U, 2>& v) : Vec<T, 2>(v) {} + + inline Vec2(const value_type x, + const value_type y = 0) : Vec<T, 2>() { + this->_coord[0] = (T)x; + this->_coord[1] = (T)y; + } + + inline value_type x() const { + return this->_coord[0]; + } + + inline value_type& x() { + return this->_coord[0]; + } + + inline value_type y() const { + return this->_coord[1]; + } + + inline value_type& y() { + return this->_coord[1]; + } + + inline void setX(const value_type v) { + this->_coord[0] = v; + } + + inline void setY(const value_type v) { + this->_coord[1] = v; + } + + // FIXME: hack swig -- no choice + inline Vec2<T> operator+(const Vec2<T>& v) const{ + Vec2<T> res(v); + res += *this; + return res; + } + + inline Vec2<T> operator-(const Vec2<T>& v) const{ + Vec2<T> res(*this); + res -= v; + return res; + } + + inline Vec2<T> operator*(const value_type r) const{ + Vec2<T> res(*this); + res *= r; + return res; + } + + inline Vec2<T> operator/(const value_type r) const{ + Vec2<T> res(*this); + if (r) + res /= r; + return res; + } + + // dot product + inline value_type operator*(const Vec2<T>& v) const{ + value_type sum = 0; + for (unsigned i = 0; i < 2; i++) + sum += (*this)[i] * v[i]; + return sum; + } + }; + + + // + // HVec3 class (3D Vector in homogeneous coordinates) + // - T: value type + // + ///////////////////////////////////////////////////////////////////////////// + + template <class T> + class HVec3 : public Vec<T, 4> + { + public: + + typedef typename Vec<T, 4>::value_type value_type; + + inline HVec3() : Vec<T, 4>() {} + + template <class U> + explicit inline HVec3(const U tab[4]) : Vec<T, 4>(tab) {} + + template <class U> + explicit inline HVec3(const std::vector<U>& tab) : Vec<T, 4>(tab) {} + + template<class U> + inline HVec3(const Vec<U, 4>& v) : Vec<T, 4>(v) {} + + inline HVec3(const value_type sx, + const value_type sy = 0, + const value_type sz = 0, + const value_type s = 1) { + this->_coord[0] = sx; + this->_coord[1] = sy; + this->_coord[2] = sz; + this->_coord[3] = s; + } + + template <class U> + inline HVec3(const Vec<U, 3>& sv, + const U s = 1) { + this->_coord[0] = (T)sv[0]; + this->_coord[1] = (T)sv[1]; + this->_coord[2] = (T)sv[2]; + this->_coord[3] = (T)s; + } + + inline value_type sx() const { + return this->_coord[0]; + } + + inline value_type& sx() { + return this->_coord[0]; + } + + inline value_type sy() const { + return this->_coord[1]; + } + + inline value_type& sy() { + return this->_coord[1]; + } + + inline value_type sz() const { + return this->_coord[2]; + } + + inline value_type& sz() { + return this->_coord[2]; + } + + inline value_type s() const { + return this->_coord[3]; + } + + inline value_type& s() { + return this->_coord[3]; + } + + // Acces to non-homogeneous coordinates in 3D + + inline value_type x() const { + return this->_coord[0] / this->_coord[3]; + } + + inline value_type y() const { + return this->_coord[1] / this->_coord[3]; + } + + inline value_type z() const { + return this->_coord[2] / this->_coord[3]; + } + }; + + + // + // Vec3 class (3D Vec) + // - T: value type + // + ///////////////////////////////////////////////////////////////////////////// + + template <class T> + class Vec3 : public Vec<T, 3> + { + public: + + typedef typename Vec<T, 3>::value_type value_type; + + inline Vec3() : Vec<T, 3>() {} + + template <class U> + explicit inline Vec3(const U tab[3]) : Vec<T, 3>(tab) {} + + template <class U> + explicit inline Vec3(const std::vector<U>& tab) : Vec<T, 3>(tab) {} + + template<class U> + inline Vec3(const Vec<U, 3>& v) : Vec<T, 3>(v) {} + + template<class U> + inline Vec3(const HVec3<U>& v) { + this->_coord[0] = (T)v.x(); + this->_coord[1] = (T)v.y(); + this->_coord[2] = (T)v.z(); + } + + inline Vec3(const value_type x, + const value_type y = 0, + const value_type z = 0) : Vec<T, 3>() { + this->_coord[0] = x; + this->_coord[1] = y; + this->_coord[2] = z; + } + + inline value_type x() const { + return this->_coord[0]; + } + + inline value_type& x() { + return this->_coord[0]; + } + + inline value_type y() const { + return this->_coord[1]; + } + + inline value_type& y() { + return this->_coord[1]; + } + + inline value_type z() const { + return this->_coord[2]; + } + + inline value_type& z() { + return this->_coord[2]; + } + + inline void setX(const value_type v) { + this->_coord[0] = v; + } + + inline void setY(const value_type v) { + this->_coord[1] = v; + } + + inline void setZ(const value_type v) { + this->_coord[2] = v; + } + + // classical operators + // FIXME: hack swig -- no choice + inline Vec3<T> operator+(const Vec3<T>& v) const{ + Vec3<T> res(v); + res += *this; + return res; + } + + inline Vec3<T> operator-(const Vec3<T>& v) const{ + Vec3<T> res(*this); + res -= v; + return res; + } + + inline Vec3<T> operator*(const value_type r) const{ + Vec3<T> res(*this); + res *= r; + return res; + } + + inline Vec3<T> operator/(const value_type r) const{ + Vec3<T> res(*this); + if (r) + res /= r; + return res; + } + + // dot product + inline value_type operator*(const Vec3<T>& v) const{ + value_type sum = 0; + for (unsigned i = 0; i < 3; i++) + sum += (*this)[i] * v[i]; + return sum; + } + + // cross product for 3D Vectors + // FIXME: hack swig -- no choice + inline Vec3<T> operator^(const Vec3<T>& v) const{ + Vec3<T> res((*this)[1] * v[2] - (*this)[2] * v[1], + (*this)[2] * v[0] - (*this)[0] * v[2], + (*this)[0] * v[1] - (*this)[1] * v[0]); + return res; + } + + // cross product for 3D Vectors + template <typename U> + inline Vec3<T> operator^(const Vec<U, 3>& v) const{ + Vec3<T> res((*this)[1] * v[2] - (*this)[2] * v[1], + (*this)[2] * v[0] - (*this)[0] * v[2], + (*this)[0] * v[1] - (*this)[1] * v[0]); + return res; + } + }; + + + // + // Matrix class + // - T: value type + // - M: rows + // - N: cols + // + ///////////////////////////////////////////////////////////////////////////// + + // Dirty, but icc under Windows needs this +# define _SIZE (M * N) + + template <class T, unsigned M, unsigned N> + class Matrix + { + public: + + typedef T value_type; + + inline Matrix() { + for (unsigned i = 0; i < _SIZE; i++) + this->_coord[i] = 0; + } + + ~Matrix() { + Internal::is_false<(M == 0)>::ensure(); + Internal::is_false<(N == 0)>::ensure(); + } + + template <class U> + explicit inline Matrix(const U tab[_SIZE]) { + for (unsigned i = 0; i < _SIZE; i++) + this->_coord[i] = tab[i]; + } + + template <class U> + explicit inline Matrix(const std::vector<U>& tab) { + for (unsigned i = 0; i < _SIZE; i++) + this->_coord[i] = tab[i]; + } + + template <class U> + inline Matrix(const Matrix<U, M, N>& m) { + for (unsigned i = 0; i < M; i++) + for (unsigned j = 0; j < N; j++) + this->_coord[i * N + j] = (T)m(i, j); + } + + inline value_type operator()(const unsigned i, const unsigned j) const { + return this->_coord[i * N + j]; + } + + inline value_type& operator()(const unsigned i, const unsigned j) { + return this->_coord[i * N + j]; + } + + static inline unsigned rows() { + return M; + } + + static inline unsigned cols() { + return N; + } + + inline Matrix<T, M, N>& transpose() const { + Matrix<T, N, M> res; + for (unsigned i = 0; i < M; i++) + for (unsigned j = 0; j < N; j++) + res(j,i) = this->_coord[i * N + j]; + return res; + } + + template <class U> + inline Matrix<T, M, N>& operator=(const Matrix<U, M, N>& m) { + if (this != &m) + for (unsigned i = 0; i < M; i++) + for (unsigned j = 0; j < N; j++) + this->_coord[i * N + j] = (T)m(i, j); + return *this; + } + + template <class U> + inline Matrix<T, M, N>& operator+=(const Matrix<U, M, N>& m) { + for (unsigned i = 0; i < M; i++) + for (unsigned j = 0; j < N; j++) + this->_coord[i * N + j] += (T)m(i, j); + return *this; + } + + template <class U> + inline Matrix<T, M, N>& operator-=(const Matrix<U, M, N>& m) { + for (unsigned i = 0; i < M; i++) + for (unsigned j = 0; j < N; j++) + this->_coord[i * N + j] -= (T)m(i, j); + return *this; + } + + template <class U> + inline Matrix<T, M, N>& operator*=(const U lambda) { + for (unsigned i = 0; i < M; i++) + for (unsigned j = 0; j < N; j++) + this->_coord[i * N + j] *= lambda; + return *this; + } + + template <class U> + inline Matrix<T, M, N>& operator/=(const U lambda) { + if (lambda) + for (unsigned i = 0; i < M; i++) + for (unsigned j = 0; j < N; j++) + this->_coord[i * N + j] /= lambda; + return *this; + } + + protected: + + value_type _coord[_SIZE]; + }; + + + // + // SquareMatrix class + // - T: value type + // - N: rows & cols + // + ///////////////////////////////////////////////////////////////////////////// + + // Dirty, but icc under Windows needs this +# define __SIZE (N * N) + + template <class T, unsigned N> + class SquareMatrix : public Matrix<T, N, N> + { + public: + + typedef T value_type; + + inline SquareMatrix() : Matrix<T, N, N>() {} + + template <class U> + explicit inline SquareMatrix(const U tab[__SIZE]) : Matrix<T, N, N>(tab) {} + + template <class U> + explicit inline SquareMatrix(const std::vector<U>& tab) : Matrix<T, N, N>(tab) {} + + template <class U> + inline SquareMatrix(const Matrix<U, N, N>& m) : Matrix<T, N, N>(m) {} + + static inline SquareMatrix<T, N> identity() { + SquareMatrix<T, N> res; + for (unsigned i = 0; i < N; i++) + res(i, i) = 1; + return res; + } + }; + + + // + // Vector external functions + // + ///////////////////////////////////////////////////////////////////////////// + + // template <class T, unsigned N> + // inline Vec<T, N> operator+(const Vec<T, N>& v1, + // const Vec<T, N>& v2) { + // Vec<T, N> res(v1); + // res += v2; + // return res; + // } + // + // template <class T, unsigned N> + // inline Vec<T, N> operator-(const Vec<T, N>& v1, + // const Vec<T, N>& v2) { + // Vec<T, N> res(v1); + // res -= v2; + // return res; + // } + // template <class T, unsigned N> + // inline Vec<T, N> operator*(const Vec<T, N>& v, + // const typename Vec<T, N>::value_type r) { + // Vec<T, N> res(v); + // res *= r; + // return res; + // } + + template <class T, unsigned N> + inline Vec<T, N> operator*(const typename Vec<T, N>::value_type r, + const Vec<T, N>& v) { + Vec<T, N> res(v); + res *= r; + return res; + } + // + // template <class T, unsigned N> + // inline Vec<T, N> operator/(const Vec<T, N>& v, + // const typename Vec<T, N>::value_type r) { + // Vec<T, N> res(v); + // if (r) + // res /= r; + // return res; + // } + // + // dot product + // template <class T, unsigned N> + // inline typename Vec<T, N>::value_type operator*(const Vec<T, N>& v1, + // const Vec<T, N>& v2) { + // typename Vec<T, N>::value_type sum = 0; + // for (unsigned i = 0; i < N; i++) + // sum += v1[i] * v2[i]; + // return sum; + // } + // + // // cross product for 3D Vectors + // template <typename T> + // inline Vec3<T> operator^(const Vec<T, 3>& v1, + // const Vec<T, 3>& v2) { + // Vec3<T> res(v1[1] * v2[2] - v1[2] * v2[1], + // v1[2] * v2[0] - v1[0] * v2[2], + // v1[0] * v2[1] - v1[1] * v2[0]); + // return res; + // } + + // stream operator + template <class T, unsigned N> + inline std::ostream& operator<<(std::ostream& s, + const Vec<T, N>& v) { + unsigned i; + s << "["; + for (i = 0; i < N - 1; i++) + s << v[i] << ", "; + s << v[i] << "]"; + return s; + } + + + // + // Matrix external functions + // + ///////////////////////////////////////////////////////////////////////////// + + template <class T, unsigned M, unsigned N> + inline Matrix<T, M, N> + operator+(const Matrix<T, M, N>& m1, + const Matrix<T, M, N>& m2) { + Matrix<T, M, N> res(m1); + res += m2; + return res; + } + + template <class T, unsigned M, unsigned N> + inline Matrix<T, M, N> + operator-(const Matrix<T, M, N>& m1, + const Matrix<T, M, N>& m2) { + Matrix<T, M, N> res(m1); + res -= m2; + return res; + } + + template <class T, unsigned M, unsigned N> + inline Matrix<T, M, N> + operator*(const Matrix<T, M, N>& m1, + const typename Matrix<T, M, N>::value_type lambda) { + Matrix<T, M, N> res(m1); + res *= lambda; + return res; + } + + template <class T, unsigned M, unsigned N> + inline Matrix<T, M, N> + operator*(const typename Matrix<T, M, N>::value_type lambda, + const Matrix<T, M, N>& m1) { + Matrix<T, M, N> res(m1); + res *= lambda; + return res; + } + + template <class T, unsigned M, unsigned N> + inline Matrix<T, M, N> + operator/(const Matrix<T, M, N>& m1, + const typename Matrix<T, M, N>::value_type lambda) { + Matrix<T, M, N> res(m1); + res /= lambda; + return res; + } + + template <class T, unsigned M, unsigned N, unsigned P> + inline Matrix<T, M, P> + operator*(const Matrix<T, M, N>& m1, + const Matrix<T, N, P>& m2) { + unsigned i, j, k; + Matrix<T, M, P> res; + typename Matrix<T, N, P>::value_type scale; + + for (j = 0; j < P; j++) { + for (k = 0; k < N; k++) { + scale = m2(k, j); + for (i = 0; i < N; i++) + res(i, j) += m1(i, k) * scale; + } + } + return res; + } + + template <class T, unsigned M, unsigned N> + inline Vec<T, M> + operator*(const Matrix<T, M, N>& m, + const Vec<T, N>& v) { + + Vec<T, M> res; + typename Matrix<T, M, N>::value_type scale; + + for (unsigned j = 0; j < M; j++) { + scale = v[j]; + for (unsigned i = 0; i < N; i++) + res[i] += m(i, j) * scale; + } + return res; + } + + // stream operator + template <class T, unsigned M, unsigned N> + inline std::ostream& operator<<(std::ostream& s, + const Matrix<T, M, N>& m) { + unsigned i, j; + for (i = 0; i < M; i++) { + s << "["; + for (j = 0; j < N - 1; j++) + s << m(i, j) << ", "; + s << m(i, j) << "]" << std::endl; + } + return s; + } + +} // end of namespace VecMat + +#endif // VECMAT_H diff --git a/source/blender/freestyle/intern/geometry/matrix_util.cpp b/source/blender/freestyle/intern/geometry/matrix_util.cpp new file mode 100755 index 00000000000..2117b06e62f --- /dev/null +++ b/source/blender/freestyle/intern/geometry/matrix_util.cpp @@ -0,0 +1,265 @@ +/* + * GXML/Graphite: Geometry and Graphics Programming Library + Utilities + * Copyright (C) 2000 Bruno Levy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * If you modify this software, you should include a notice giving the + * name of the person performing the modification, the date of modification, + * and the reason for such modification. + * + * Contact: Bruno Levy + * + * levy@loria.fr + * + * ISA Project + * LORIA, INRIA Lorraine, + * Campus Scientifique, BP 239 + * 54506 VANDOEUVRE LES NANCY CEDEX + * FRANCE + * + * Note that the GNU General Public License does not permit incorporating + * the Software into proprietary programs. + */ + + +#include "matrix_util.h" +#include <math.h> + + + +namespace OGF { + + namespace MatrixUtil { + + static const double EPS = 0.00001 ; + static int MAX_ITER = 100 ; + + void semi_definite_symmetric_eigen( + const double *mat, int n, double *eigen_vec, double *eigen_val + ) { + double *a,*v; + double a_norm,a_normEPS,thr,thr_nn; + int nb_iter = 0; + int jj; + int i,j,k,ij,ik,l,m,lm,mq,lq,ll,mm,imv,im,iq,ilv,il,nn; + int *index; + double a_ij,a_lm,a_ll,a_mm,a_im,a_il; + double a_lm_2; + double v_ilv,v_imv; + double x; + double sinx,sinx_2,cosx,cosx_2,sincos; + double delta; + + // Number of entries in mat + + nn = (n*(n+1))/2; + + // Step 1: Copy mat to a + + a = new double[nn]; + + for( ij=0; ij<nn; ij++ ) { + a[ij] = mat[ij]; + } + + // Ugly Fortran-porting trick: indices for a are between 1 and n + a--; + + // Step 2 : Init diagonalization matrix as the unit matrix + v = new double[n*n]; + + ij = 0; + for( i=0; i<n; i++ ) { + for( j=0; j<n; j++ ) { + if( i==j ) { + v[ij++] = 1.0; + } else { + v[ij++] = 0.0; + } + } + } + + // Ugly Fortran-porting trick: indices for v are between 1 and n + v--; + + // Step 3 : compute the weight of the non diagonal terms + ij = 1 ; + a_norm = 0.0; + for( i=1; i<=n; i++ ) { + for( j=1; j<=i; j++ ) { + if( i!=j ) { + a_ij = a[ij]; + a_norm += a_ij*a_ij; + } + ij++; + } + } + + if( a_norm != 0.0 ) { + + a_normEPS = a_norm*EPS; + thr = a_norm ; + + // Step 4 : rotations + while( thr > a_normEPS && nb_iter < MAX_ITER ) { + + nb_iter++; + thr_nn = thr / nn; + + for( l=1 ; l< n; l++ ) { + for( m=l+1; m<=n; m++ ) { + + // compute sinx and cosx + + lq = (l*l-l)/2; + mq = (m*m-m)/2; + + lm = l+mq; + a_lm = a[lm]; + a_lm_2 = a_lm*a_lm; + + if( a_lm_2 < thr_nn ) { + continue ; + } + + ll = l+lq; + mm = m+mq; + a_ll = a[ll]; + a_mm = a[mm]; + + delta = a_ll - a_mm; + + if( delta == 0.0 ) { + x = - M_PI/4 ; + } else { + x = - atan( (a_lm+a_lm) / delta ) / 2.0 ; + } + + sinx = sin(x) ; + cosx = cos(x) ; + sinx_2 = sinx*sinx; + cosx_2 = cosx*cosx; + sincos = sinx*cosx; + + // rotate L and M columns + + ilv = n*(l-1); + imv = n*(m-1); + + for( i=1; i<=n;i++ ) { + if( (i!=l) && (i!=m) ) { + iq = (i*i-i)/2; + + if( i<m ) { + im = i + mq; + } else { + im = m + iq; + } + a_im = a[im]; + + if( i<l ) { + il = i + lq; + } else { + il = l + iq; + } + a_il = a[il]; + + a[il] = a_il*cosx - a_im*sinx; + a[im] = a_il*sinx + a_im*cosx; + } + + ilv++; + imv++; + + v_ilv = v[ilv]; + v_imv = v[imv]; + + v[ilv] = cosx*v_ilv - sinx*v_imv; + v[imv] = sinx*v_ilv + cosx*v_imv; + } + + x = a_lm*sincos; x+=x; + + a[ll] = a_ll*cosx_2 + a_mm*sinx_2 - x; + a[mm] = a_ll*sinx_2 + a_mm*cosx_2 + x; + a[lm] = 0.0; + + thr = fabs( thr - a_lm_2 ); + } + } + } + } + + // Step 5: index conversion and copy eigen values + + // back from Fortran to C++ + a++; + + for( i=0; i<n; i++ ) { + k = i + (i*(i+1))/2; + eigen_val[i] = a[k]; + } + + delete[] a; + + // Step 6: sort the eigen values and eigen vectors + + index = new int[n]; + for( i=0; i<n; i++ ) { + index[i] = i; + } + + for( i=0; i<(n-1); i++ ) { + x = eigen_val[i]; + k = i; + + for( j=i+1; j<n; j++ ) { + if( x < eigen_val[j] ) { + k = j; + x = eigen_val[j]; + } + } + + eigen_val[k] = eigen_val[i]; + eigen_val[i] = x; + + jj = index[k]; + index[k] = index[i]; + index[i] = jj; + } + + + // Step 7: save the eigen vectors + + v++; // back from Fortran to to C++ + + ij = 0; + for( k=0; k<n; k++ ) { + ik = index[k]*n; + for( i=0; i<n; i++ ) { + eigen_vec[ij++] = v[ik++]; + } + } + + delete[] v ; + delete[] index; + return; + } + +//_________________________________________________________ + + } +} diff --git a/source/blender/freestyle/intern/geometry/matrix_util.h b/source/blender/freestyle/intern/geometry/matrix_util.h new file mode 100755 index 00000000000..a990413c403 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/matrix_util.h @@ -0,0 +1,69 @@ +/* + * GXML/Graphite: Geometry and Graphics Programming Library + Utilities + * Copyright (C) 2000 Bruno Levy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * If you modify this software, you should include a notice giving the + * name of the person performing the modification, the date of modification, + * and the reason for such modification. + * + * Contact: Bruno Levy + * + * levy@loria.fr + * + * ISA Project + * LORIA, INRIA Lorraine, + * Campus Scientifique, BP 239 + * 54506 VANDOEUVRE LES NANCY CEDEX + * FRANCE + * + * Note that the GNU General Public License does not permit incorporating + * the Software into proprietary programs. + */ + +#ifndef __MATRIX_UTIL__ +#define __MATRIX_UTIL__ + +# include "../system/FreestyleConfig.h" + +namespace OGF { + + namespace MatrixUtil { + + /** + * computes the eigen values and eigen vectors + * of a semi definite symmetric matrix + * + * @param matrix is stored in column symmetric storage, i.e. + * matrix = { m11, m12, m22, m13, m23, m33, m14, m24, m34, m44 ... } + * size = n(n+1)/2 + * + * @param eigen_vectors (return) = { v1, v2, v3, ..., vn } + * where vk = vk0, vk1, ..., vkn + * size = n^2, must be allocated by caller + * + * @param eigen_values (return) are in decreasing order + * size = n, must be allocated by caller + */ + LIB_GEOMETRY_EXPORT + void semi_definite_symmetric_eigen( + const double *mat, int n, double *eigen_vec, double *eigen_val + ) ; + + } +} + +#endif diff --git a/source/blender/freestyle/intern/geometry/normal_cycle.cpp b/source/blender/freestyle/intern/geometry/normal_cycle.cpp new file mode 100755 index 00000000000..b456ced8331 --- /dev/null +++ b/source/blender/freestyle/intern/geometry/normal_cycle.cpp @@ -0,0 +1,103 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// +#include "normal_cycle.h" +#include "matrix_util.h" + + +namespace OGF { + +//_________________________________________________________ + + + NormalCycle::NormalCycle() { + } + + void NormalCycle::begin() { + M_[0] = M_[1] = M_[2] = M_[3] = M_[4] = M_[5] = 0 ; + } + + void NormalCycle::end() { + + double eigen_vectors[9] ; + MatrixUtil::semi_definite_symmetric_eigen(M_, 3, eigen_vectors, eigen_value_) ; + + axis_[0] = Vec3r( + eigen_vectors[0], eigen_vectors[1], eigen_vectors[2] + ) ; + + axis_[1] = Vec3r( + eigen_vectors[3], eigen_vectors[4], eigen_vectors[5] + ) ; + + axis_[2] = Vec3r( + eigen_vectors[6], eigen_vectors[7], eigen_vectors[8] + ) ; + + // Normalize the eigen vectors + + for(int i=0; i<3; i++) { + axis_[i].normalize() ; + } + + // Sort the eigen vectors + + i_[0] = 0 ; + i_[1] = 1 ; + i_[2] = 2 ; + + double l0 = ::fabs(eigen_value_[0]) ; + double l1 = ::fabs(eigen_value_[1]) ; + double l2 = ::fabs(eigen_value_[2]) ; + + if(l1 > l0) { + ogf_swap(l0 , l1 ) ; + ogf_swap(i_[0], i_[1]) ; + } + if(l2 > l1) { + ogf_swap(l1 , l2 ) ; + ogf_swap(i_[1], i_[2]) ; + } + if(l1 > l0) { + ogf_swap(l0 , l1 ) ; + ogf_swap(i_[0],i_[1]) ; + } + + } + + void NormalCycle::accumulate_dihedral_angle( + const Vec3r& edge, double beta, double neigh_area + ) { + Vec3r e = edge ; + e.normalize() ; + + double s = edge.norm() * beta * neigh_area ; + + M_[0] += s * e.x() * e.x() ; + M_[1] += s * e.x() * e.y() ; + M_[2] += s * e.y() * e.y() ; + M_[3] += s * e.x() * e.z() ; + M_[4] += s * e.y() * e.z() ; + M_[5] += s * e.z() * e.z() ; + } + +//_________________________________________________________ + +} diff --git a/source/blender/freestyle/intern/geometry/normal_cycle.h b/source/blender/freestyle/intern/geometry/normal_cycle.h new file mode 100755 index 00000000000..41fbf7b3fab --- /dev/null +++ b/source/blender/freestyle/intern/geometry/normal_cycle.h @@ -0,0 +1,97 @@ +/* + * OGF/Graphite: Geometry and Graphics Programming Library + Utilities + * Copyright (C) 2000 Bruno Levy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * If you modify this software, you should include a notice giving the + * name of the person performing the modification, the date of modification, + * and the reason for such modification. + * + * Contact: Bruno Levy + * + * levy@loria.fr + * + * ISA Project + * LORIA, INRIA Lorraine, + * Campus Scientifique, BP 239 + * 54506 VANDOEUVRE LES NANCY CEDEX + * FRANCE + * + * Note that the GNU General Public License does not permit incorporating + * the Software into proprietary programs. + */ + +#ifndef __MESH_TOOLS_MATH_NORMAL_CYCLE__ +#define __MESH_TOOLS_MATH_NORMAL_CYCLE__ + +# include "../system/FreestyleConfig.h" +# include "Geom.h" +using namespace Geometry; + +namespace OGF { + +template <class T> inline void ogf_swap(T& x, T& y) { + T z = x ; + x = y ; + y = z ; + } + +//_________________________________________________________ + + /** + * NormalCycle evaluates the curvature tensor in function + * of a set of dihedral angles and associated vectors. + * Reference: + * Restricted Delaunay Triangulation and Normal Cycle, + * D. Cohen-Steiner and J.M. Morvan, + * SOCG 2003 + */ + class LIB_GEOMETRY_EXPORT NormalCycle { + public: + NormalCycle() ; + void begin() ; + void end() ; + /** + * Note: the specified edge vector needs to be pre-clipped + * by the neighborhood. + */ + void accumulate_dihedral_angle( + const Vec3r& edge, real angle, real neigh_area = 1.0 + ) ; + const Vec3r& eigen_vector(int i) const { return axis_[i_[i]] ; } + real eigen_value(int i) const { return eigen_value_[i_[i]] ; } + + const Vec3r& N() const { return eigen_vector(2) ; } + const Vec3r& Kmax() const { return eigen_vector(1) ; } + const Vec3r& Kmin() const { return eigen_vector(0) ; } + + real n() const { return eigen_value(2) ; } + real kmax() const { return eigen_value(1) ; } + real kmin() const { return eigen_value(0) ; } + + private: + real center_[3] ; + Vec3r axis_[3] ; + real eigen_value_[3] ; + real M_[6] ; + int i_[3] ; + } ; + +//_________________________________________________________ + +} + +#endif diff --git a/source/blender/freestyle/intern/image/GaussianFilter.cpp b/source/blender/freestyle/intern/image/GaussianFilter.cpp new file mode 100755 index 00000000000..3a79f5f9949 --- /dev/null +++ b/source/blender/freestyle/intern/image/GaussianFilter.cpp @@ -0,0 +1,96 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "GaussianFilter.h" +#include <stdlib.h> + +GaussianFilter::GaussianFilter(float iSigma ) +{ + _sigma = iSigma; + _mask = 0; + computeMask(); +} + +GaussianFilter::GaussianFilter(const GaussianFilter& iBrother) +{ + _sigma = iBrother._sigma; + _maskSize = iBrother._maskSize; + _bound = iBrother._bound; + _storedMaskSize = iBrother._storedMaskSize; + _mask = new float[_maskSize*_maskSize]; + memcpy(_mask, iBrother._mask, _maskSize*_maskSize*sizeof(float)); +} + + +GaussianFilter& GaussianFilter::operator= (const GaussianFilter& iBrother) +{ + _sigma = iBrother._sigma; + _maskSize = iBrother._maskSize; + _bound = iBrother._bound; + _storedMaskSize = iBrother._storedMaskSize; + _mask = new float[_storedMaskSize*_storedMaskSize]; + memcpy(_mask, iBrother._mask, _storedMaskSize*_storedMaskSize*sizeof(float)); + return *this; +} + + +GaussianFilter::~GaussianFilter() +{ + if(0!=_mask) + { + delete [] _mask; + } +} + +int GaussianFilter::computeMaskSize(float sigma) +{ + int maskSize = (int)floor(4*sigma)+1; + if(0 == maskSize%2) + ++maskSize; + + return maskSize; +} + +void GaussianFilter::setSigma(float sigma) +{ + _sigma = sigma; + computeMask(); +} + +void GaussianFilter::computeMask() +{ + if(0 != _mask){ + delete [] _mask; + } + + _maskSize = computeMaskSize(_sigma); + _storedMaskSize = (_maskSize+1)>>1; + _bound = _storedMaskSize-1; + + float norm = _sigma*_sigma*2.f*M_PI; + float invNorm = 1.0/norm; + _mask = new float[_storedMaskSize*_storedMaskSize*sizeof(float)]; + for(int i=0; i<_storedMaskSize; ++i) + for(int j=0; j<_storedMaskSize; ++j) + _mask[i*_storedMaskSize+j] = invNorm*exp(-(i*i + j*j)/(2.0*_sigma*_sigma)); + //_mask[i*_storedMaskSize+j] = exp(-(i*i + j*j)/(2.0*_sigma*_sigma)); +} + diff --git a/source/blender/freestyle/intern/image/GaussianFilter.h b/source/blender/freestyle/intern/image/GaussianFilter.h new file mode 100755 index 00000000000..be0e3e2bada --- /dev/null +++ b/source/blender/freestyle/intern/image/GaussianFilter.h @@ -0,0 +1,146 @@ +// +// Filename : Image.h +// Author(s) : Stephane Grabli +// Purpose : Class to perform gaussian filtering operations on an image +// Date of creation : 20/05/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GAUSSIANFILTER_H +# define GAUSSIANFILTER_H + +#include <string.h> // for memcpy +#include <cstdlib> // for abs +#include "../system/FreestyleConfig.h" + +class LIB_IMAGE_EXPORT GaussianFilter{ +protected: + /* the mask is a symetrical 2d array (with respect + to the middle point). + Thus, M(i,j) = M(-i,j) = M(i,-j) = M(-i,-j). + For this reason, to represent a NxN array (N odd), we only store + a ((N+1)/2)x((N+1)/2) array. + */ + float _sigma; + float *_mask; + int _bound; + int _maskSize; // the real mask size (must be odd)(the size of the mask we store is ((_maskSize+1)/2)*((_maskSize+1)/2)) + int _storedMaskSize; //(_maskSize+1)/2) + +public: + GaussianFilter(float iSigma = 1.f) ; + GaussianFilter(const GaussianFilter&) ; + GaussianFilter& operator= (const GaussianFilter&) ; + virtual ~GaussianFilter() ; + + /*! Returns the value for pixel x,y of image "map" after a gaussian blur, + * made using the sigma value. + * The sigma value determines the mask size (~ 2 x sigma). + * \param map + * The image we wish to work on. The Map template must implement the + * foloowing methods: + * - float pixel(unsigned int x,unsigned int y) const; + * - unsigned width() const; + * - unsigned height() const; + * \param x + * The abscissa of the pixel where we want to evaluate the gaussian blur. + * \param y + * The ordinate of the pixel where we want to evaluate the gaussian blur. + * \param sigma + * The sigma value of the gaussian function. + */ + template<class Map> + float getSmoothedPixel(Map * map, int x, int y) ; + + /*! Compute the mask size and returns the REAL mask size ((2*_maskSize)-1) + * This method is provided for convenience. + */ + static int computeMaskSize(float sigma) ; + + /*! accessors */ + inline float sigma() const {return _sigma;} + inline int maskSize() const {return _maskSize;} + inline int getBound() {return _bound;} + + /*! modifiers */ + void setSigma(float sigma) ; + // void SetMaskSize(int size) {_maskSize = size;_storedMaskSize=(_maskSize+1)>>1;} + + +protected: + void computeMask(); +}; + +/* + + ############################################# + ############################################# + ############################################# + ###### ###### + ###### I M P L E M E N T A T I O N ###### + ###### ###### + ############################################# + ############################################# + ############################################# + +*/ + + +#include <math.h> + +#ifdef __MACH__ +#define sqrtf(x) (sqrt(x)) +#endif + +template<class Map> +float GaussianFilter::getSmoothedPixel(Map * map, int x, int y) +{ + float sum = 0.f; + float L=0.f; + int w = (int)map->width(); //soc + int h = (int)map->height(); //soc + + // Current pixel is x,y + // Sum surrounding pixels L value: + for(int i=-_bound; i<=_bound; ++i) + { + if((y+i < 0) || (y+i >= h)) + continue; + for(int j=-_bound; j<=_bound; ++j) + { + if((x+j < 0) || (x+j >= w)) + continue; + + float tmpL = map->pixel(x+j,y+i); + float m = _mask[abs(i)*_storedMaskSize+abs(j)]; + L += m*tmpL; + sum += m; + } + } + //L /= sum; + return L; +} + + +#endif // GAUSSIANFILTER diff --git a/source/blender/freestyle/intern/image/Image.h b/source/blender/freestyle/intern/image/Image.h new file mode 100755 index 00000000000..72affbc1023 --- /dev/null +++ b/source/blender/freestyle/intern/image/Image.h @@ -0,0 +1,389 @@ +// +// Filename : Image.h +// Author(s) : Stephane Grabli +// Purpose : Class to encapsulate an array of RGB or Gray level values +// Date of creation : 20/05/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef IMAGE_H +# define IMAGE_H + +# include <string.h> // for memcpy + +// +// Image base class, for all types of images +// +/////////////////////////////////////////////////////////////////////////////// + +/*! This class allows the storing of part of an image, + * while allowing a normal access to its pixel values. + * You can for example only a rectangle of sw*sh, whose + * lower-left corner is at (ox, oy), of an image of + * size w*h, and access these pixels using x,y coordinates + * specified in the whole image coordinate system. + */ +class FrsImage +{ + public: + + /*! Default constructor */ + FrsImage() { + _storedWidth = 0; + _storedHeight = 0; + _width = 0; + _height = 0; + _Ox = 0; + _Oy = 0; + } + + /*! Copy constructor */ + FrsImage(const FrsImage& brother) { + _storedWidth = brother._storedWidth; + _storedHeight = brother._storedHeight; + _width = brother._width; + _height = brother._height; + _Ox = brother._Ox; + _Oy = brother._Oy; + } + + /*! Builds an FrsImage from its width and height. + * The memory is allocated consequently. + */ + FrsImage(unsigned w, unsigned h) { + _width = w; + _height = h; + _storedWidth = w; + _storedHeight = h; + _Ox = 0; + _Oy = 0; + } + + /*! Builds a partial-storing image. + * \param w + * The width of the complete image + * \param h + * The height of the complete image + * \param sw + * The width of the rectangle that will actually + * be stored. + * \param sh + * The height of the rectangle that will actually + * be stored. + * \param ox + * The x-abscissa of the origin of the rectangle that will actually + * be stored. + * \param oy + * The x-abscissa of the origin of the rectangle that will actually + * be stored. + */ + FrsImage(unsigned w, unsigned h, unsigned sw, unsigned sh, unsigned ox, unsigned oy) { + _width = w; + _height = h; + _storedWidth = sw; + _storedHeight = sh; + _Ox = ox; + _Oy = oy; + } + + /*! Operator= */ + FrsImage& operator=(const FrsImage& brother) { + _width = brother._width; + _height = brother._height; + _storedWidth = brother._storedWidth; + _storedHeight = brother._storedHeight; + _Ox = brother._Ox; + _Oy = brother._Oy; + return* this; + } + + /*! Destructor */ + virtual ~FrsImage() {} + + /*! Returns the width of the complete image */ + inline unsigned width() const { + return _width; + } + /*! Returns the height of the complete image */ + inline unsigned height() const { + return _height; + } + + /*! Returns the grey value for pixel x,y */ + virtual float pixel(unsigned x, unsigned y) const = 0; + + /*! Sets the array. + * \param array + * The array containing the values we wish to store. + * Its size is sw*sh. + * \param width + * The width of the complete image + * \param height + * The height of the complete image + * \param sw + * The width of the rectangle that will actually + * be stored. + * \param sh + * The height of the rectangle that will actually + * be stored. + * \param ox + * The x-abscissa of the origin of the rectangle that will actually + * be stored. + * \param oy + * The x-abscissa of the origin of the rectangle that will actually + * be stored. + * \param copy + * If true, the array is copied, otherwise the pointer is + * copied + */ + virtual void setArray(float* array, unsigned width, unsigned height, unsigned sw, unsigned sh, unsigned x, unsigned y, bool copy = true) = 0; + + /*! Returns the array containing the pixels values. + * Its size is sw*sh, i.e. potentially a smaller + * rectangular part of the complete image. + */ + virtual float * getArray() = 0; + + protected: + + unsigned _width; + unsigned _height; + unsigned _storedWidth; + unsigned _storedHeight; + unsigned _Ox; // origin of the stored part + unsigned _Oy; // origin of the stored part +}; + + +// +// RGBImage +// +/////////////////////////////////////////////////////////////////////////////// + +class RGBImage : public FrsImage +{ + public: + + RGBImage() : FrsImage() { + _rgb = 0; + } + + RGBImage(const RGBImage& brother) : FrsImage(brother) { + _rgb = new float[3 * _storedWidth * _storedHeight]; + memcpy(_rgb, brother._rgb, 3 * _storedWidth * _storedHeight * sizeof(float)); + } + + RGBImage(unsigned w, unsigned h) : FrsImage(w, h) { + _rgb = new float[3 * _width * _height]; + } + + RGBImage(float* rgb, unsigned w, unsigned h) : FrsImage(w, h) { + _rgb = new float[3 * _width * _height]; + memcpy(_rgb, rgb, 3 * _width * _height * sizeof(float)); + } + + /*! Builds an RGB partial image from the useful part buffer. + * \param rgb + * The array of size 3*sw*sh containing the RGB values + * of the sw*sh pixels we need to stored. + * These sw*sh pixels constitute a rectangular part of + * a bigger RGB image containing w*h pixels. + * \param w + * The width of the complete image + * \param h + * The height of the complete image + * \param sw + * The width of the part of the image we want to store and work on + * \param sh + * The height of the part of the image we want to store and work on + */ + RGBImage(float* rgb, unsigned w, unsigned h, unsigned sw, unsigned sh, unsigned ox, unsigned oy) : FrsImage(w, h, sw, sh, ox, oy) { + _rgb = new float[3 * _storedWidth * _storedHeight]; + memcpy(_rgb, rgb, 3 * _storedWidth * _storedHeight * sizeof(float)); + } + + RGBImage& operator=(const RGBImage& brother) { + dynamic_cast<FrsImage&>(*this) = brother; + _rgb = new float[3 * _storedWidth * _storedHeight]; + memcpy(_rgb, brother._rgb, 3 * _storedWidth * _storedHeight * sizeof(float)); + return* this; + } + + virtual ~RGBImage() { + if(_rgb) + delete[] _rgb; + } + + inline float getR(unsigned x, unsigned y) const { + return _rgb[3 * (y-_Oy) * _storedWidth + (x-_Ox) * 3]; + } + + inline float getG(unsigned x, unsigned y) const { + return _rgb[3 * (y-_Oy) * _storedWidth + (x-_Ox) * 3 + 1]; + } + + inline float getB(unsigned x, unsigned y) const { + return _rgb[3 * (y-_Oy) * _storedWidth + (x-_Ox) * 3 + 2]; + } + + virtual void setPixel(unsigned x, unsigned y, float r, float g, float b){ + float * tmp = &(_rgb[3 * (y-_Oy) * _storedWidth + (x-_Ox) * 3]); + *tmp = r;++tmp; + *tmp = g;++tmp; + *tmp = b; + } + + virtual float pixel(unsigned x, unsigned y) const { + float res = 0; + float* tmp = &(_rgb[3 * (y-_Oy) * _storedWidth + (x-_Ox) * 3]); + res += 11 * (*tmp++); + res += 16 * (*tmp++); + res += 5 * (*tmp); + return res / 32; + } + + /*! Sets the RGB array. + * copy + * If true, the array is copied, otherwise the pointer is + * copied + */ + virtual void setArray(float* rgb, unsigned width, unsigned height, unsigned sw, unsigned sh, unsigned x, unsigned y, bool copy = true) { + _width = width; + _height = height; + _storedWidth = sw; + _storedHeight = sh; + _Ox = x; + _Oy = y; + if(!copy) { + _rgb = rgb; + return; + } + + memcpy(_rgb, rgb, 3 * _storedWidth * _storedHeight* sizeof(float)); + } + + virtual float * getArray() {return _rgb;} + + protected: + + float* _rgb; +}; + + +// +// GrayImage +// +/////////////////////////////////////////////////////////////////////////////// + +class GrayImage : public FrsImage +{ + public: + + GrayImage() : FrsImage() { + _lvl = 0; + } + + GrayImage(const GrayImage& brother) : FrsImage(brother) { + _lvl = new float[_storedWidth*_storedHeight]; + memcpy(_lvl, brother._lvl, _storedWidth*_storedHeight*sizeof(*_lvl)); + } + + /*! Builds an empty gray image */ + GrayImage(unsigned w, unsigned h) : FrsImage(w, h) { + _lvl = new float[_width*_height]; + } + + GrayImage(float* lvl, unsigned w, unsigned h) : FrsImage(w, h) { + _lvl = new float[_width*_height]; + memcpy(_lvl, lvl, _width*_height*sizeof(*_lvl)); + } + + /*! Builds a partial image from the useful part buffer. + * \param lvl + * The array of size sw*sh containing the gray values + * of the sw*sh pixels we need to stored. + * These sw*sh pixels constitute a rectangular part of + * a bigger gray image containing w*h pixels. + * \param w + * The width of the complete image + * \param h + * The height of the complete image + * \param sw + * The width of the part of the image we want to store and work on + * \param sh + * The height of the part of the image we want to store and work on + */ + GrayImage(float* lvl, unsigned w, unsigned h, unsigned sw, unsigned sh, unsigned ox, unsigned oy) : FrsImage(w, h, sw, sh, ox, oy) { + _lvl = new float[_storedWidth*_storedHeight]; + memcpy(_lvl, lvl, _storedWidth*_storedHeight*sizeof(float)); + } + + GrayImage& operator=(const GrayImage& brother) { + dynamic_cast<FrsImage&>(*this) = brother; + _lvl = new float[_storedWidth * _storedHeight]; + memcpy(_lvl, brother._lvl, _storedWidth * _storedHeight * sizeof(float)); + return *this; + } + + virtual ~GrayImage() { + if(_lvl) + delete[] _lvl; + } + + inline void setPixel(unsigned x, unsigned y, float v){ + _lvl[(y-_Oy) * _storedWidth+ (x-_Ox)] = v; + } + + inline float pixel(unsigned x, unsigned y) const { + return _lvl[(y-_Oy) * _storedWidth+ (x-_Ox)]; + } + + /*! Sets the array. + * copy + * If true, the array is copie, otherwise the pounsigneder is + * copied + */ + void setArray(float *lvl, unsigned width, unsigned height, unsigned sw, unsigned sh, unsigned x, unsigned y, bool copy = true) { + _width = width; + _height = height; + _storedWidth = sw; + _storedHeight = sh; + _Ox = x; + _Oy = y; + if(!copy) { + _lvl = lvl; + return; + } + + memcpy(_lvl, lvl, _storedWidth * _storedHeight * sizeof(float)); + } + /*! Returns the array containing the gray values. */ + virtual float * getArray() {return _lvl;} + + protected: + + float *_lvl; +}; + +#endif // IMAGE_H diff --git a/source/blender/freestyle/intern/image/ImagePyramid.cpp b/source/blender/freestyle/intern/image/ImagePyramid.cpp new file mode 100755 index 00000000000..542ab7917e3 --- /dev/null +++ b/source/blender/freestyle/intern/image/ImagePyramid.cpp @@ -0,0 +1,166 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// +#include "ImagePyramid.h" +#include "Image.h" +#include "GaussianFilter.h" +#include <iostream> + +using namespace std; + +//ImagePyramid::ImagePyramid(const GrayImage& level0, unsigned nbLevels){ +// //BuildPyramid(level0,nbLevels); +//} + +ImagePyramid::ImagePyramid(const ImagePyramid& iBrother){ + if(!_levels.empty()){ + for(vector<GrayImage*>::iterator im=_levels.begin(), imend=_levels.end(); + im!=imend; + ++im){ + _levels.push_back(new GrayImage(**im)); + } + } +} +ImagePyramid::~ImagePyramid(){ + if(!_levels.empty()){ + for(vector<GrayImage*>::iterator im=_levels.begin(), imend=_levels.end(); + im!=imend; + ++im){ + delete (*im); + } + _levels.clear(); + } +} + +GrayImage * ImagePyramid::getLevel(int l){ + return _levels[l]; +} + +float ImagePyramid::pixel(int x, int y, int level){ + GrayImage *img = _levels[level]; + if(0 == level){ + return img->pixel(x,y); + } + unsigned int i = 1<<level; + unsigned int sx = x>>level; + unsigned int sy = y>>level; + if(sx >= img->width()) + sx = img->width()-1; + if(sy >= img->height()) + sy = img->height()-1; + + // bilinear interpolation + float A = i*(sx+1)-x; + float B = x-i*sx; + float C = i*(sy+1)-y; + float D = y-i*sy; + + float P1(0), P2(0); + P1 = A*img->pixel(sx,sy); + if(sx < img->width()-1){ + if(x%i != 0) + P1 += B*img->pixel(sx+1,sy); + }else{ + P1 += B*img->pixel(sx,sy); + } + if(sy<img->height()-1){ + if(y%i != 0){ + P2 = A*img->pixel(sx,sy+1); + if(sx < img->width()-1){ + if(x%i != 0) + P2 += B*img->pixel(sx+1,sy+1); + }else{ + P2 += B*img->pixel(sx,sy+1); + } + } + }else{ + P2 = P1; + } + return (1.f/(float)(1<<2*level))*(C*P1 + D*P2); +} + +int ImagePyramid::width(int level){ + return _levels[level]->width(); +} + +int ImagePyramid::height(int level){ + return _levels[level]->height(); +} + +GaussianPyramid::GaussianPyramid(const GrayImage& level0, unsigned nbLevels, float iSigma) + : ImagePyramid() +{ + _sigma = iSigma; + BuildPyramid(level0,nbLevels); +} +GaussianPyramid::GaussianPyramid(GrayImage* level0, unsigned nbLevels, float iSigma) + : ImagePyramid() +{ + _sigma = iSigma; + BuildPyramid(level0,nbLevels); +} + +GaussianPyramid::GaussianPyramid(const GaussianPyramid& iBrother) +: ImagePyramid(iBrother){ + _sigma = iBrother._sigma; +} +void GaussianPyramid::BuildPyramid(const GrayImage& level0, unsigned nbLevels){ + GrayImage *pLevel = new GrayImage(level0); + BuildPyramid(pLevel, nbLevels); +} + +void GaussianPyramid::BuildPyramid(GrayImage* level0, unsigned nbLevels){ + GrayImage *pLevel = level0; + _levels.push_back(pLevel); + GaussianFilter gf(_sigma); + // build the nbLevels: + unsigned w = pLevel->width(); + unsigned h = pLevel->height(); + if(nbLevels!=0) + { + for(unsigned i=0; i<nbLevels; ++i){ //soc + w = pLevel->width()>>1; + h = pLevel->height()>>1; + GrayImage *img = new GrayImage(w,h); + for(unsigned y=0; y<h; ++y){ + for(unsigned x=0; x<w; ++x){ + float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2*x,2*y); + img->setPixel(x,y,v); + } + } + _levels.push_back(img); + pLevel = img; + } + }else{ + while((w>1) && (h>1)){ + w = pLevel->width()>>1; + h = pLevel->height()>>1; + GrayImage *img = new GrayImage(w,h); + for(unsigned y=0; y<h; ++y){ + for(unsigned x=0; x<w; ++x){ + float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2*x,2*y); + img->setPixel(x,y,v); + } + } + _levels.push_back(img); + pLevel = img; + } + } +} diff --git a/source/blender/freestyle/intern/image/ImagePyramid.h b/source/blender/freestyle/intern/image/ImagePyramid.h new file mode 100755 index 00000000000..9e326757f02 --- /dev/null +++ b/source/blender/freestyle/intern/image/ImagePyramid.h @@ -0,0 +1,92 @@ +// +// Filename : ImagePyramid.h +// Author(s) : Stephane Grabli +// Purpose : Class to represent a pyramid of images +// Date of creation : 25/12/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef IMAGEPYRAMID_H +# define IMAGEPYRAMID_H + +#include "../system/FreestyleConfig.h" +#include <vector> + +class GrayImage; +class LIB_IMAGE_EXPORT ImagePyramid{ +protected: + std::vector<GrayImage*> _levels; + +public: + ImagePyramid(){} + ImagePyramid(const ImagePyramid& iBrother); + //ImagePyramid(const GrayImage& level0, unsigned nbLevels); + virtual ~ImagePyramid(); + + /*! Builds the pyramid. + * must be overloaded by inherited classes. + * if nbLevels==0, the complete pyramid is built + */ + virtual void BuildPyramid(const GrayImage& level0, unsigned nbLevels) = 0; + + /*! Builds a pyramid without copying the base level */ + virtual void BuildPyramid(GrayImage* level0, unsigned nbLevels) = 0; + + virtual GrayImage * getLevel(int l); + /*! Returns the pixel x,y using bilinear interpolation. + * \param x + * the abscissa specified in the finest level coordinate system + * \param y + * the ordinate specified in the finest level coordinate system + * \param level + * the level from which we want the pixel to be evaluated + */ + virtual float pixel(int x, int y, int level=0); + /*! Returns the width of the level-th level image */ + virtual int width(int level=0); + /*! Returns the height of the level-th level image */ + virtual int height(int level=0); + /*! Returns the number of levels in the pyramid */ + inline int getNumberOfLevels() const { return _levels.size();} +}; + +class LIB_IMAGE_EXPORT GaussianPyramid : public ImagePyramid +{ +protected: + float _sigma; +public: + GaussianPyramid(float iSigma=1.f) : ImagePyramid() {_sigma=iSigma;} + GaussianPyramid(const GrayImage& level0, unsigned nbLevels, float iSigma=1.f); + GaussianPyramid(GrayImage* level0, unsigned nbLevels, float iSigma=1.f); + GaussianPyramid(const GaussianPyramid& iBrother); + virtual ~GaussianPyramid(){} + + virtual void BuildPyramid(const GrayImage& level0, unsigned nbLevels); + virtual void BuildPyramid(GrayImage* level0, unsigned nbLevels); + /* accessors */ + inline float getSigma() const {return _sigma;} + /* modifiers */ + +}; +#endif // IMAGEPYRAMID_H diff --git a/source/blender/freestyle/intern/python/BPy_BBox.cpp b/source/blender/freestyle/intern/python/BPy_BBox.cpp new file mode 100644 index 00000000000..3e73e871c3e --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_BBox.cpp @@ -0,0 +1,103 @@ +#include "BPy_BBox.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for BBox instance -----------*/ +static int BBox___init__(BPy_BBox *self, PyObject *args, PyObject *kwds); +static void BBox___dealloc__(BPy_BBox *self); +static PyObject * BBox___repr__(BPy_BBox *self); + +/*----------------------BBox instance definitions ----------------------------*/ +static PyMethodDef BPy_BBox_methods[] = { + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_BBox type definition ------------------------------*/ + +PyTypeObject BBox_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "BBox", /* tp_name */ + sizeof(BPy_BBox), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)BBox___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)BBox___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "BBox objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_BBox_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)BBox___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int BBox_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &BBox_Type ) < 0 ) + return -1; + + Py_INCREF( &BBox_Type ); + PyModule_AddObject(module, "BBox", (PyObject *)&BBox_Type); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int BBox___init__(BPy_BBox *self, PyObject *args, PyObject *kwds) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->bb = new BBox< Vec3r>(); + return 0; +} + +void BBox___dealloc__(BPy_BBox* self) +{ + delete self->bb; + Py_TYPE(self)->tp_free((PyObject*)self); +} + + +PyObject * BBox___repr__(BPy_BBox* self) +{ + return PyUnicode_FromFormat("BBox - address: %p", self->bb ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_BBox.h b/source/blender/freestyle/intern/python/BPy_BBox.h new file mode 100644 index 00000000000..96a61e18c2f --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_BBox.h @@ -0,0 +1,38 @@ +#ifndef FREESTYLE_PYTHON_BBOX_H +#define FREESTYLE_PYTHON_BBOX_H + +#include "../geometry/BBox.h" +#include "../geometry/Geom.h" +using namespace Geometry; + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject BBox_Type; + +#define BPy_BBox_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &BBox_Type) ) + +/*---------------------------Python BPy_BBox structure definition----------*/ +typedef struct { + PyObject_HEAD + BBox<Vec3r> *bb; +} BPy_BBox; + +/*---------------------------Python BPy_BBox visible prototypes-----------*/ + +int BBox_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_BBOX_H */ diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp new file mode 100644 index 00000000000..c6b418d727a --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.cpp @@ -0,0 +1,145 @@ +#include "BPy_BinaryPredicate0D.h" + +#include "BPy_Convert.h" +#include "BPy_Interface0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for BinaryPredicate0D instance -----------*/ +static int BinaryPredicate0D___init__(BPy_BinaryPredicate0D *self, PyObject *args, PyObject *kwds); +static void BinaryPredicate0D___dealloc__(BPy_BinaryPredicate0D *self); +static PyObject * BinaryPredicate0D___repr__(BPy_BinaryPredicate0D *self); + +static PyObject * BinaryPredicate0D_getName( BPy_BinaryPredicate0D *self, PyObject *args); +static PyObject * BinaryPredicate0D___call__( BPy_BinaryPredicate0D *self, PyObject *args, PyObject *kwds); + +/*----------------------BinaryPredicate0D instance definitions ----------------------------*/ +static PyMethodDef BPy_BinaryPredicate0D_methods[] = { + {"getName", ( PyCFunction ) BinaryPredicate0D_getName, METH_NOARGS, "() Returns the string of the name of the binary predicate."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_BinaryPredicate0D type definition ------------------------------*/ + +PyTypeObject BinaryPredicate0D_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "BinaryPredicate0D", /* tp_name */ + sizeof(BPy_BinaryPredicate0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)BinaryPredicate0D___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)BinaryPredicate0D___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)BinaryPredicate0D___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "BinaryPredicate0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_BinaryPredicate0D_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)BinaryPredicate0D___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int BinaryPredicate0D_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &BinaryPredicate0D_Type ) < 0 ) + return -1; + + Py_INCREF( &BinaryPredicate0D_Type ); + PyModule_AddObject(module, "BinaryPredicate0D", (PyObject *)&BinaryPredicate0D_Type); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int BinaryPredicate0D___init__(BPy_BinaryPredicate0D *self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->bp0D = new BinaryPredicate0D(); + self->bp0D->py_bp0D = (PyObject *) self; + + return 0; +} + +void BinaryPredicate0D___dealloc__(BPy_BinaryPredicate0D* self) +{ + if (self->bp0D) + delete self->bp0D; + Py_TYPE(self)->tp_free((PyObject*)self); +} + + +PyObject * BinaryPredicate0D___repr__(BPy_BinaryPredicate0D* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->bp0D->getName().c_str(), self->bp0D ); +} + + +PyObject * BinaryPredicate0D_getName( BPy_BinaryPredicate0D *self, PyObject *args) +{ + return PyUnicode_FromFormat( self->bp0D->getName().c_str() ); +} + +PyObject * BinaryPredicate0D___call__( BPy_BinaryPredicate0D *self, PyObject *args, PyObject *kwds) +{ + BPy_Interface0D *obj1, *obj2; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!O!", &Interface0D_Type, &obj1, &Interface0D_Type, &obj2) ) + return NULL; + + if( typeid(*(self->bp0D)) == typeid(BinaryPredicate0D) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->bp0D->operator()( *(obj1->if0D) , *(obj2->if0D) ) < 0) { + if (!PyErr_Occurred()) { + string msg(self->bp0D->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return PyBool_from_bool( self->bp0D->result ); + +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h new file mode 100644 index 00000000000..d27b6cc0fe8 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate0D.h @@ -0,0 +1,36 @@ +#ifndef FREESTYLE_PYTHON_BINARYPREDICATE0D_H +#define FREESTYLE_PYTHON_BINARYPREDICATE0D_H + +#include "../stroke/Predicates0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject BinaryPredicate0D_Type; + +#define BPy_BinaryPredicate0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &BinaryPredicate0D_Type) ) + +/*---------------------------Python BPy_BinaryPredicate0D structure definition----------*/ +typedef struct { + PyObject_HEAD + BinaryPredicate0D *bp0D; +} BPy_BinaryPredicate0D; + +/*---------------------------Python BPy_BinaryPredicate0D visible prototypes-----------*/ + +int BinaryPredicate0D_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_BINARYPREDICATE0D_H */ diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp new file mode 100644 index 00000000000..384aafeb567 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.cpp @@ -0,0 +1,172 @@ +#include "BPy_BinaryPredicate1D.h" + +#include "BPy_Convert.h" +#include "BPy_Interface1D.h" + +#include "BinaryPredicate1D/BPy_FalseBP1D.h" +#include "BinaryPredicate1D/BPy_Length2DBP1D.h" +#include "BinaryPredicate1D/BPy_SameShapeIdBP1D.h" +#include "BinaryPredicate1D/BPy_TrueBP1D.h" +#include "BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for BinaryPredicate1D instance -----------*/ +static int BinaryPredicate1D___init__(BPy_BinaryPredicate1D *self, PyObject *args, PyObject *kwds); +static void BinaryPredicate1D___dealloc__(BPy_BinaryPredicate1D *self); +static PyObject * BinaryPredicate1D___repr__(BPy_BinaryPredicate1D *self); + +static PyObject * BinaryPredicate1D_getName( BPy_BinaryPredicate1D *self, PyObject *args); +static PyObject * BinaryPredicate1D___call__( BPy_BinaryPredicate1D *self, PyObject *args, PyObject *kwds); + +/*----------------------BinaryPredicate1D instance definitions ----------------------------*/ +static PyMethodDef BPy_BinaryPredicate1D_methods[] = { + {"getName", ( PyCFunction ) BinaryPredicate1D_getName, METH_NOARGS, "() Returns the string of the name of the binary predicate."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_BinaryPredicate1D type definition ------------------------------*/ +PyTypeObject BinaryPredicate1D_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "BinaryPredicate1D", /* tp_name */ + sizeof(BPy_BinaryPredicate1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)BinaryPredicate1D___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)BinaryPredicate1D___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)BinaryPredicate1D___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "BinaryPredicate1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_BinaryPredicate1D_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)BinaryPredicate1D___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int BinaryPredicate1D_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &BinaryPredicate1D_Type ) < 0 ) + return -1; + Py_INCREF( &BinaryPredicate1D_Type ); + PyModule_AddObject(module, "BinaryPredicate1D", (PyObject *)&BinaryPredicate1D_Type); + + if( PyType_Ready( &FalseBP1D_Type ) < 0 ) + return -1; + Py_INCREF( &FalseBP1D_Type ); + PyModule_AddObject(module, "FalseBP1D", (PyObject *)&FalseBP1D_Type); + + if( PyType_Ready( &Length2DBP1D_Type ) < 0 ) + return -1; + Py_INCREF( &Length2DBP1D_Type ); + PyModule_AddObject(module, "Length2DBP1D", (PyObject *)&Length2DBP1D_Type); + + if( PyType_Ready( &SameShapeIdBP1D_Type ) < 0 ) + return -1; + Py_INCREF( &SameShapeIdBP1D_Type ); + PyModule_AddObject(module, "SameShapeIdBP1D", (PyObject *)&SameShapeIdBP1D_Type); + + if( PyType_Ready( &TrueBP1D_Type ) < 0 ) + return -1; + Py_INCREF( &TrueBP1D_Type ); + PyModule_AddObject(module, "TrueBP1D", (PyObject *)&TrueBP1D_Type); + + if( PyType_Ready( &ViewMapGradientNormBP1D_Type ) < 0 ) + return -1; + Py_INCREF( &ViewMapGradientNormBP1D_Type ); + PyModule_AddObject(module, "ViewMapGradientNormBP1D", (PyObject *)&ViewMapGradientNormBP1D_Type); + + return 0; +} + + +//------------------------INSTANCE METHODS ---------------------------------- + +int BinaryPredicate1D___init__(BPy_BinaryPredicate1D *self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->bp1D = new BinaryPredicate1D(); + self->bp1D->py_bp1D = (PyObject *) self; + return 0; +} + +void BinaryPredicate1D___dealloc__(BPy_BinaryPredicate1D* self) +{ + if (self->bp1D) + delete self->bp1D; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyObject * BinaryPredicate1D___repr__(BPy_BinaryPredicate1D* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->bp1D->getName().c_str(), self->bp1D ); +} + +PyObject *BinaryPredicate1D_getName( BPy_BinaryPredicate1D *self, PyObject *args) +{ + return PyUnicode_FromFormat( self->bp1D->getName().c_str() ); +} + +PyObject *BinaryPredicate1D___call__( BPy_BinaryPredicate1D *self, PyObject *args, PyObject *kwds) +{ + BPy_Interface1D *obj1, *obj2; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!O!", &Interface1D_Type, &obj1, &Interface1D_Type, &obj2) ) + return NULL; + + if( typeid(*(self->bp1D)) == typeid(BinaryPredicate1D) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->bp1D->operator()( *(obj1->if1D) , *(obj2->if1D) ) < 0) { + if (!PyErr_Occurred()) { + string msg(self->bp1D->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return PyBool_from_bool( self->bp1D->result ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h new file mode 100644 index 00000000000..42419ce7129 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_BinaryPredicate1D.h @@ -0,0 +1,35 @@ +#ifndef FREESTYLE_PYTHON_BINARYPREDICATE1D_H +#define FREESTYLE_PYTHON_BINARYPREDICATE1D_H + +#include "../stroke/Predicates1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject BinaryPredicate1D_Type; + +#define BPy_BinaryPredicate1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &BinaryPredicate1D_Type) ) + +/*---------------------------Python BPy_BinaryPredicate1D structure definition----------*/ +typedef struct { + PyObject_HEAD + BinaryPredicate1D *bp1D; +} BPy_BinaryPredicate1D; + +/*---------------------------Python BPy_BinaryPredicate1D visible prototypes-----------*/ + +int BinaryPredicate1D_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_BINARYPREDICATE1D_H */ diff --git a/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp b/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp new file mode 100644 index 00000000000..43db0f0eb29 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp @@ -0,0 +1,169 @@ +#include "BPy_ContextFunctions.h" +#include "BPy_Convert.h" + +#include "../stroke/ContextFunctions.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*-----------------------Python API function prototypes for the ContextFunctions module--*/ + +static PyObject * ContextFunctions_GetTimeStampCF( PyObject* self ); +static PyObject * ContextFunctions_GetCanvasWidthCF( PyObject* self ); +static PyObject * ContextFunctions_GetCanvasHeightCF( PyObject* self ); +static PyObject * ContextFunctions_LoadMapCF( PyObject *self, PyObject *args ); +static PyObject * ContextFunctions_ReadMapPixelCF( PyObject *self, PyObject *args ); +static PyObject * ContextFunctions_ReadCompleteViewMapPixelCF( PyObject *self, PyObject *args ); +static PyObject * ContextFunctions_ReadDirectionalViewMapPixelCF( PyObject *self, PyObject *args ); +static PyObject * ContextFunctions_GetSelectedFEdgeCF( PyObject *self ); + +/*-----------------------ContextFunctions module docstring-------------------------------*/ + +static char module_docstring[] = "The Blender Freestyle.ContextFunctions submodule\n\n"; + +/*-----------------------ContextFunctions module functions definitions-------------------*/ + +static PyMethodDef module_functions[] = { + {"GetTimeStampCF", (PyCFunction)ContextFunctions_GetTimeStampCF, METH_NOARGS, ""}, + {"GetCanvasWidthCF", (PyCFunction)ContextFunctions_GetCanvasWidthCF, METH_NOARGS, ""}, + {"GetCanvasHeightCF", (PyCFunction)ContextFunctions_GetCanvasHeightCF, METH_NOARGS, ""}, + {"LoadMapCF", (PyCFunction)ContextFunctions_LoadMapCF, METH_VARARGS, ""}, + {"ReadMapPixelCF", (PyCFunction)ContextFunctions_ReadMapPixelCF, METH_VARARGS, ""}, + {"ReadCompleteViewMapPixelCF", (PyCFunction)ContextFunctions_ReadCompleteViewMapPixelCF, METH_VARARGS, ""}, + {"ReadDirectionalViewMapPixelCF", (PyCFunction)ContextFunctions_ReadDirectionalViewMapPixelCF, METH_VARARGS, ""}, + {"GetSelectedFEdgeCF", (PyCFunction)ContextFunctions_GetSelectedFEdgeCF, METH_NOARGS, ""}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------ContextFunctions module definition--------------------------------*/ + +static PyModuleDef module_definition = { + PyModuleDef_HEAD_INIT, + "Freestyle.ContextFunctions", + module_docstring, + -1, + module_functions +}; + +//------------------- MODULE INITIALIZATION -------------------------------- + +int ContextFunctions_Init( PyObject *module ) +{ + PyObject *m, *d, *f; + + if( module == NULL ) + return -1; + + m = PyModule_Create(&module_definition); + if (m == NULL) + return -1; + Py_INCREF(m); + PyModule_AddObject(module, "ContextFunctions", m); + + // from ContextFunctions import * + d = PyModule_GetDict(m); + for (PyMethodDef *p = module_functions; p->ml_name; p++) { + f = PyDict_GetItemString(d, p->ml_name); + Py_INCREF(f); + PyModule_AddObject(module, p->ml_name, f); + } + + return 0; +} + +//------------------------ MODULE FUNCTIONS ---------------------------------- + +static PyObject * +ContextFunctions_GetTimeStampCF( PyObject* self ) +{ + return PyLong_FromLong( ContextFunctions::GetTimeStampCF() ); +} + +static PyObject * +ContextFunctions_GetCanvasWidthCF( PyObject* self ) +{ + return PyLong_FromLong( ContextFunctions::GetCanvasWidthCF() ); +} + +static PyObject * +ContextFunctions_GetCanvasHeightCF( PyObject* self ) +{ + return PyLong_FromLong( ContextFunctions::GetCanvasHeightCF() ); +} + +static PyObject * +ContextFunctions_LoadMapCF( PyObject *self, PyObject *args ) +{ + char *fileName, *mapName; + unsigned nbLevels; + float sigma; + + if( !PyArg_ParseTuple(args, "ssIf", &fileName, &mapName, &nbLevels, &sigma) ) + return NULL; + + ContextFunctions::LoadMapCF(fileName, mapName, nbLevels, sigma); + + Py_RETURN_NONE; +} + +static PyObject * +ContextFunctions_ReadMapPixelCF( PyObject *self, PyObject *args ) +{ + char *mapName; + int level; + unsigned x, y; + + if( !PyArg_ParseTuple(args, "siII", &mapName, &level, &x, &y) ) + return NULL; + + float f = ContextFunctions::ReadMapPixelCF(mapName, level, x, y); + + return PyFloat_FromDouble( f ); +} + +static PyObject * +ContextFunctions_ReadCompleteViewMapPixelCF( PyObject *self, PyObject *args ) +{ + int level; + unsigned x, y; + + if( !PyArg_ParseTuple(args, "iII", &level, &x, &y) ) + return NULL; + + float f = ContextFunctions::ReadCompleteViewMapPixelCF(level, x, y); + + return PyFloat_FromDouble( f ); +} + +static PyObject * +ContextFunctions_ReadDirectionalViewMapPixelCF( PyObject *self, PyObject *args ) +{ + int orientation, level; + unsigned x, y; + + if( !PyArg_ParseTuple(args, "iiII", &orientation, &level, &x, &y) ) + return NULL; + + float f = ContextFunctions::ReadDirectionalViewMapPixelCF(orientation, level, x, y); + + return PyFloat_FromDouble( f ); +} + +static PyObject * +ContextFunctions_GetSelectedFEdgeCF( PyObject *self ) +{ + FEdge *fe = ContextFunctions::GetSelectedFEdgeCF(); + if( fe ) + return Any_BPy_FEdge_from_FEdge( *fe ); + + Py_RETURN_NONE; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_ContextFunctions.h b/source/blender/freestyle/intern/python/BPy_ContextFunctions.h new file mode 100644 index 00000000000..5ec70f1a261 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_ContextFunctions.h @@ -0,0 +1,18 @@ +#ifndef FREESTYLE_PYTHON_CONTEXTFUNCTIONS_H +#define FREESTYLE_PYTHON_CONTEXTFUNCTIONS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <Python.h> + +/*---------------------------Python BPy_ContextFunctions visible prototypes-----------*/ + +int ContextFunctions_Init( PyObject *module ); + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CONTEXTFUNCTIONS_H */ diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp new file mode 100644 index 00000000000..e3f979fea8f --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp @@ -0,0 +1,609 @@ +#include "BPy_Convert.h" + +#include "BPy_BBox.h" +#include "BPy_FrsMaterial.h" +#include "BPy_Id.h" +#include "BPy_IntegrationType.h" +#include "BPy_Interface0D.h" +#include "Interface0D/BPy_CurvePoint.h" +#include "Interface0D/CurvePoint/BPy_StrokeVertex.h" +#include "Interface0D/BPy_SVertex.h" +#include "Interface0D/BPy_ViewVertex.h" +#include "Interface0D/ViewVertex/BPy_NonTVertex.h" +#include "Interface0D/ViewVertex/BPy_TVertex.h" +#include "BPy_Interface1D.h" +#include "Interface1D/BPy_FEdge.h" +#include "Interface1D/BPy_Stroke.h" +#include "Interface1D/BPy_ViewEdge.h" +#include "Interface1D/Curve/BPy_Chain.h" +#include "Interface1D/FEdge/BPy_FEdgeSharp.h" +#include "Interface1D/FEdge/BPy_FEdgeSmooth.h" +#include "BPy_Nature.h" +#include "BPy_MediumType.h" +#include "BPy_SShape.h" +#include "BPy_StrokeAttribute.h" +#include "BPy_ViewShape.h" + +#include "Iterator/BPy_AdjacencyIterator.h" +#include "Iterator/BPy_ChainPredicateIterator.h" +#include "Iterator/BPy_ChainSilhouetteIterator.h" +#include "Iterator/BPy_ChainingIterator.h" +#include "Iterator/BPy_CurvePointIterator.h" +#include "Iterator/BPy_Interface0DIterator.h" +#include "Iterator/BPy_SVertexIterator.h" +#include "Iterator/BPy_StrokeVertexIterator.h" +#include "Iterator/BPy_ViewEdgeIterator.h" +#include "Iterator/BPy_orientedViewEdgeIterator.h" + +#include "../stroke/StrokeRep.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/////////////////////////////////////////////////////////////////////////////////////////// + +//============================== +// C++ => Python +//============================== + + +PyObject * PyBool_from_bool( bool b ){ + return PyBool_FromLong( b ? 1 : 0); +} + + +PyObject * Vector_from_Vec2f( Vec2f& vec ) { + float vec_data[2]; // because vec->_coord is protected + + vec_data[0] = vec.x(); vec_data[1] = vec.y(); + return newVectorObject( vec_data, 2, Py_NEW, NULL); +} + +PyObject * Vector_from_Vec3f( Vec3f& vec ) { + float vec_data[3]; // because vec->_coord is protected + + vec_data[0] = vec.x(); vec_data[1] = vec.y(); vec_data[2] = vec.z(); + return newVectorObject( vec_data, 3, Py_NEW, NULL); +} + +PyObject * Vector_from_Vec3r( Vec3r& vec ) { + float vec_data[3]; // because vec->_coord is protected + + vec_data[0] = vec.x(); vec_data[1] = vec.y(); vec_data[2] = vec.z(); + return newVectorObject( vec_data, 3, Py_NEW, NULL); +} + +PyObject * BPy_Id_from_Id( Id& id ) { + PyObject *py_id = Id_Type.tp_new( &Id_Type, 0, 0 ); + ((BPy_Id *) py_id)->id = new Id( id.getFirst(), id.getSecond() ); + + return py_id; +} + +PyObject * Any_BPy_Interface0D_from_Interface0D( Interface0D& if0D ) { + if (typeid(if0D) == typeid(CurvePoint)) { + return BPy_CurvePoint_from_CurvePoint(dynamic_cast<CurvePoint&>(if0D)); + } else if (typeid(if0D) == typeid(StrokeVertex)) { + return BPy_StrokeVertex_from_StrokeVertex(dynamic_cast<StrokeVertex&>(if0D)); + } else if (typeid(if0D) == typeid(SVertex)) { + return BPy_SVertex_from_SVertex(dynamic_cast<SVertex&>(if0D)); + } else if (typeid(if0D) == typeid(ViewVertex)) { + return BPy_ViewVertex_from_ViewVertex(dynamic_cast<ViewVertex&>(if0D)); + } else if (typeid(if0D) == typeid(NonTVertex)) { + return BPy_NonTVertex_from_NonTVertex(dynamic_cast<NonTVertex&>(if0D)); + } else if (typeid(if0D) == typeid(TVertex)) { + return BPy_TVertex_from_TVertex(dynamic_cast<TVertex&>(if0D)); + } else if (typeid(if0D) == typeid(Interface0D)) { + return BPy_Interface0D_from_Interface0D(if0D); + } + string msg("unexpected type: " + if0D.getExactTypeName()); + PyErr_SetString(PyExc_TypeError, msg.c_str()); + return NULL; +} + +PyObject * Any_BPy_Interface1D_from_Interface1D( Interface1D& if1D ) { + if (typeid(if1D) == typeid(ViewEdge)) { + return BPy_ViewEdge_from_ViewEdge(dynamic_cast<ViewEdge&>(if1D)); + } else if (typeid(if1D) == typeid(Chain)) { + return BPy_Chain_from_Chain(dynamic_cast<Chain&>(if1D)); + } else if (typeid(if1D) == typeid(Stroke)) { + return BPy_Stroke_from_Stroke(dynamic_cast<Stroke&>(if1D)); + } else if (typeid(if1D) == typeid(FEdgeSharp)) { + return BPy_FEdgeSharp_from_FEdgeSharp(dynamic_cast<FEdgeSharp&>(if1D)); + } else if (typeid(if1D) == typeid(FEdgeSmooth)) { + return BPy_FEdgeSmooth_from_FEdgeSmooth(dynamic_cast<FEdgeSmooth&>(if1D)); + } else if (typeid(if1D) == typeid(FEdge)) { + return BPy_FEdge_from_FEdge(dynamic_cast<FEdge&>(if1D)); + } else if (typeid(if1D) == typeid(Interface1D)) { + return BPy_Interface1D_from_Interface1D( if1D ); + } + string msg("unexpected type: " + if1D.getExactTypeName()); + PyErr_SetString(PyExc_TypeError, msg.c_str()); + return NULL; +} + +PyObject * Any_BPy_FEdge_from_FEdge( FEdge& fe ) { + if (typeid(fe) == typeid(FEdgeSharp)) { + return BPy_FEdgeSharp_from_FEdgeSharp( dynamic_cast<FEdgeSharp&>(fe) ); + } else if (typeid(fe) == typeid(FEdgeSmooth)) { + return BPy_FEdgeSmooth_from_FEdgeSmooth( dynamic_cast<FEdgeSmooth&>(fe) ); + } else if (typeid(fe) == typeid(FEdge)) { + return BPy_FEdge_from_FEdge( fe ); + } + string msg("unexpected type: " + fe.getExactTypeName()); + PyErr_SetString(PyExc_TypeError, msg.c_str()); + return NULL; +} + +PyObject * Any_BPy_ViewVertex_from_ViewVertex( ViewVertex& vv ) { + if (typeid(vv) == typeid(NonTVertex)) { + return BPy_NonTVertex_from_NonTVertex( dynamic_cast<NonTVertex&>(vv) ); + } else if (typeid(vv) == typeid(TVertex)) { + return BPy_TVertex_from_TVertex( dynamic_cast<TVertex&>(vv) ); + } else if (typeid(vv) == typeid(ViewVertex)) { + return BPy_ViewVertex_from_ViewVertex( vv ); + } + string msg("unexpected type: " + vv.getExactTypeName()); + PyErr_SetString(PyExc_TypeError, msg.c_str()); + return NULL; +} + +PyObject * BPy_Interface0D_from_Interface0D( Interface0D& if0D ) { + PyObject *py_if0D = Interface0D_Type.tp_new( &Interface0D_Type, 0, 0 ); + ((BPy_Interface0D *) py_if0D)->if0D = &if0D; + ((BPy_Interface0D *) py_if0D)->borrowed = 1; + + return py_if0D; +} + +PyObject * BPy_Interface1D_from_Interface1D( Interface1D& if1D ) { + PyObject *py_if1D = Interface1D_Type.tp_new( &Interface1D_Type, 0, 0 ); + ((BPy_Interface1D *) py_if1D)->if1D = &if1D; + ((BPy_Interface1D *) py_if1D)->borrowed = 1; + + return py_if1D; +} + +PyObject * BPy_SVertex_from_SVertex( SVertex& sv ) { + PyObject *py_sv = SVertex_Type.tp_new( &SVertex_Type, 0, 0 ); + ((BPy_SVertex *) py_sv)->sv = &sv; + ((BPy_SVertex *) py_sv)->py_if0D.if0D = ((BPy_SVertex *) py_sv)->sv; + ((BPy_SVertex *) py_sv)->py_if0D.borrowed = 1; + + return py_sv; +} + +PyObject * BPy_FEdgeSharp_from_FEdgeSharp( FEdgeSharp& fes ) { + PyObject *py_fe = FEdgeSharp_Type.tp_new( &FEdgeSharp_Type, 0, 0 ); + ((BPy_FEdgeSharp *) py_fe)->fes = &fes; + ((BPy_FEdgeSharp *) py_fe)->py_fe.fe = ((BPy_FEdgeSharp *) py_fe)->fes; + ((BPy_FEdgeSharp *) py_fe)->py_fe.py_if1D.if1D = ((BPy_FEdgeSharp *) py_fe)->fes; + ((BPy_FEdgeSharp *) py_fe)->py_fe.py_if1D.borrowed = 1; + + return py_fe; +} + +PyObject * BPy_FEdgeSmooth_from_FEdgeSmooth( FEdgeSmooth& fes ) { + PyObject *py_fe = FEdgeSmooth_Type.tp_new( &FEdgeSmooth_Type, 0, 0 ); + ((BPy_FEdgeSmooth *) py_fe)->fes = &fes; + ((BPy_FEdgeSmooth *) py_fe)->py_fe.fe = ((BPy_FEdgeSmooth *) py_fe)->fes; + ((BPy_FEdgeSmooth *) py_fe)->py_fe.py_if1D.if1D = ((BPy_FEdgeSmooth *) py_fe)->fes; + ((BPy_FEdgeSmooth *) py_fe)->py_fe.py_if1D.borrowed = 1; + + return py_fe; +} + +PyObject * BPy_FEdge_from_FEdge( FEdge& fe ) { + PyObject *py_fe = FEdge_Type.tp_new( &FEdge_Type, 0, 0 ); + ((BPy_FEdge *) py_fe)->fe = &fe; + ((BPy_FEdge *) py_fe)->py_if1D.if1D = ((BPy_FEdge *) py_fe)->fe; + ((BPy_FEdge *) py_fe)->py_if1D.borrowed = 1; + + return py_fe; +} + +PyObject * BPy_Nature_from_Nature( unsigned short n ) { + PyObject *py_n; + + PyObject *args = PyTuple_New(1); + PyTuple_SetItem( args, 0, PyLong_FromLong(n) ); + py_n = Nature_Type.tp_new(&Nature_Type, args, NULL); + Py_DECREF(args); + + return py_n; +} + +PyObject * BPy_Stroke_from_Stroke( Stroke& s ) { + PyObject *py_s = Stroke_Type.tp_new( &Stroke_Type, 0, 0 ); + ((BPy_Stroke *) py_s)->s = &s; + ((BPy_Stroke *) py_s)->py_if1D.if1D = ((BPy_Stroke *) py_s)->s; + ((BPy_Stroke *) py_s)->py_if1D.borrowed = 1; + + return py_s; +} + +PyObject * BPy_StrokeAttribute_from_StrokeAttribute( StrokeAttribute& sa ) { + PyObject *py_sa = StrokeAttribute_Type.tp_new( &StrokeAttribute_Type, 0, 0 ); + ((BPy_StrokeAttribute *) py_sa)->sa = &sa; + ((BPy_StrokeAttribute *) py_sa)->borrowed = 1; + return py_sa; +} + +PyObject * BPy_MediumType_from_MediumType( Stroke::MediumType n ) { + PyObject *py_mt; + + PyObject *args = PyTuple_New(1); + PyTuple_SetItem( args, 0, PyLong_FromLong(n) ); + py_mt = MediumType_Type.tp_new( &MediumType_Type, args, NULL ); + Py_DECREF(args); + + return py_mt; +} + +PyObject * BPy_StrokeVertex_from_StrokeVertex( StrokeVertex& sv ) { + PyObject *py_sv = StrokeVertex_Type.tp_new( &StrokeVertex_Type, 0, 0 ); + ((BPy_StrokeVertex *) py_sv)->sv = &sv; + ((BPy_StrokeVertex *) py_sv)->py_cp.cp = ((BPy_StrokeVertex *) py_sv)->sv; + ((BPy_StrokeVertex *) py_sv)->py_cp.py_if0D.if0D = ((BPy_StrokeVertex *) py_sv)->sv; + ((BPy_StrokeVertex *) py_sv)->py_cp.py_if0D.borrowed = 1; + + return py_sv; +} + +PyObject * BPy_ViewVertex_from_ViewVertex( ViewVertex& vv ) { + PyObject *py_vv = ViewVertex_Type.tp_new( &ViewVertex_Type, 0, 0 ); + ((BPy_ViewVertex *) py_vv)->vv = &vv; + ((BPy_ViewVertex *) py_vv)->py_if0D.if0D = ((BPy_ViewVertex *) py_vv)->vv; + ((BPy_ViewVertex *) py_vv)->py_if0D.borrowed = 1; + + return py_vv; +} + +PyObject * BPy_NonTVertex_from_NonTVertex( NonTVertex& ntv ) { + PyObject *py_ntv = NonTVertex_Type.tp_new( &NonTVertex_Type, 0, 0 ); + ((BPy_NonTVertex *) py_ntv)->ntv = &ntv; + ((BPy_NonTVertex *) py_ntv)->py_vv.vv = ((BPy_NonTVertex *) py_ntv)->ntv; + ((BPy_NonTVertex *) py_ntv)->py_vv.py_if0D.if0D = ((BPy_NonTVertex *) py_ntv)->ntv; + ((BPy_NonTVertex *) py_ntv)->py_vv.py_if0D.borrowed = 1; + + return py_ntv; +} + +PyObject * BPy_TVertex_from_TVertex( TVertex& tv ) { + PyObject *py_tv = TVertex_Type.tp_new( &TVertex_Type, 0, 0 ); + ((BPy_TVertex *) py_tv)->tv = &tv; + ((BPy_TVertex *) py_tv)->py_vv.vv = ((BPy_TVertex *) py_tv)->tv; + ((BPy_TVertex *) py_tv)->py_vv.py_if0D.if0D = ((BPy_TVertex *) py_tv)->tv; + ((BPy_TVertex *) py_tv)->py_vv.py_if0D.borrowed = 1; + + return py_tv; +} + +PyObject * BPy_BBox_from_BBox( BBox< Vec3r > &bb ) { + PyObject *py_bb = BBox_Type.tp_new( &BBox_Type, 0, 0 ); + ((BPy_BBox *) py_bb)->bb = new BBox< Vec3r >( bb ); + + return py_bb; +} + +PyObject * BPy_ViewEdge_from_ViewEdge( ViewEdge& ve ) { + PyObject *py_ve = ViewEdge_Type.tp_new( &ViewEdge_Type, 0, 0 ); + ((BPy_ViewEdge *) py_ve)->ve = &ve; + ((BPy_ViewEdge *) py_ve)->py_if1D.if1D = ((BPy_ViewEdge *) py_ve)->ve; + ((BPy_ViewEdge *) py_ve)->py_if1D.borrowed = 1; + + return py_ve; +} + +PyObject * BPy_Chain_from_Chain( Chain& c ) { + PyObject *py_c = Chain_Type.tp_new( &Chain_Type, 0, 0 ); + ((BPy_Chain *) py_c)->c = &c; + ((BPy_Chain *) py_c)->py_c.c = ((BPy_Chain *) py_c)->c; + ((BPy_Chain *) py_c)->py_c.py_if1D.if1D = ((BPy_Chain *) py_c)->c; + ((BPy_Chain *) py_c)->py_c.py_if1D.borrowed = 1; + return py_c; +} + +PyObject * BPy_SShape_from_SShape( SShape& ss ) { + PyObject *py_ss = SShape_Type.tp_new( &SShape_Type, 0, 0 ); + ((BPy_SShape *) py_ss)->ss = &ss; + ((BPy_SShape *) py_ss)->borrowed = 1; + + return py_ss; +} + +PyObject * BPy_ViewShape_from_ViewShape( ViewShape& vs ) { + PyObject *py_vs = ViewShape_Type.tp_new( &ViewShape_Type, 0, 0 ); + ((BPy_ViewShape *) py_vs)->vs = &vs; + ((BPy_ViewShape *) py_vs)->borrowed = 1; + + return py_vs; +} + +PyObject * BPy_FrsMaterial_from_FrsMaterial( FrsMaterial& m ){ + PyObject *py_m = FrsMaterial_Type.tp_new( &FrsMaterial_Type, 0, 0 ); + ((BPy_FrsMaterial*) py_m)->m = &m; + ((BPy_FrsMaterial*) py_m)->borrowed = 1; + + return py_m; +} + +PyObject * BPy_IntegrationType_from_IntegrationType( IntegrationType i ) { + PyObject *py_it; + + PyObject *args = PyTuple_New(1); + PyTuple_SetItem( args, 0, PyLong_FromLong(i) ); + py_it = IntegrationType_Type.tp_new( &IntegrationType_Type, args, NULL ); + Py_DECREF(args); + + return py_it; +} + +PyObject * BPy_CurvePoint_from_CurvePoint( CurvePoint& cp ) { + PyObject *py_cp = CurvePoint_Type.tp_new( &CurvePoint_Type, 0, 0 ); + ((BPy_CurvePoint*) py_cp)->cp = &cp; + ((BPy_CurvePoint*) py_cp)->py_if0D.if0D = ((BPy_CurvePoint*) py_cp)->cp; + ((BPy_CurvePoint*) py_cp)->py_if0D.borrowed = 1; + + return py_cp; +} + +PyObject * BPy_directedViewEdge_from_directedViewEdge( ViewVertex::directedViewEdge& dve ) { + PyObject *py_dve = PyTuple_New(2); + + PyTuple_SetItem( py_dve, 0, BPy_ViewEdge_from_ViewEdge(*(dve.first)) ); + PyTuple_SetItem( py_dve, 1, PyBool_from_bool(dve.second) ); + + return py_dve; +} + +//============================== +// Iterators +//============================== + +PyObject * BPy_AdjacencyIterator_from_AdjacencyIterator( AdjacencyIterator& a_it ) { + PyObject *py_a_it = AdjacencyIterator_Type.tp_new( &AdjacencyIterator_Type, 0, 0 ); + ((BPy_AdjacencyIterator *) py_a_it)->a_it = new AdjacencyIterator( a_it ); + ((BPy_AdjacencyIterator *) py_a_it)->py_it.it = ((BPy_AdjacencyIterator *) py_a_it)->a_it; + + return py_a_it; +} + +PyObject * BPy_Interface0DIterator_from_Interface0DIterator( Interface0DIterator& if0D_it, int reversed ) { + PyObject *py_if0D_it = Interface0DIterator_Type.tp_new( &Interface0DIterator_Type, 0, 0 ); + ((BPy_Interface0DIterator *) py_if0D_it)->if0D_it = new Interface0DIterator( if0D_it ); + ((BPy_Interface0DIterator *) py_if0D_it)->py_it.it = ((BPy_Interface0DIterator *) py_if0D_it)->if0D_it; + ((BPy_Interface0DIterator *) py_if0D_it)->reversed = reversed; + + return py_if0D_it; +} + +PyObject * BPy_CurvePointIterator_from_CurvePointIterator( CurveInternal::CurvePointIterator& cp_it ) { + PyObject *py_cp_it = CurvePointIterator_Type.tp_new( &CurvePointIterator_Type, 0, 0 ); + ((BPy_CurvePointIterator *) py_cp_it)->cp_it = new CurveInternal::CurvePointIterator( cp_it ); + ((BPy_CurvePointIterator *) py_cp_it)->py_it.it = ((BPy_CurvePointIterator *) py_cp_it)->cp_it; + + return py_cp_it; +} + +PyObject * BPy_StrokeVertexIterator_from_StrokeVertexIterator( StrokeInternal::StrokeVertexIterator& sv_it, int reversed) { + PyObject *py_sv_it = StrokeVertexIterator_Type.tp_new( &StrokeVertexIterator_Type, 0, 0 ); + ((BPy_StrokeVertexIterator *) py_sv_it)->sv_it = new StrokeInternal::StrokeVertexIterator( sv_it ); + ((BPy_StrokeVertexIterator *) py_sv_it)->py_it.it = ((BPy_StrokeVertexIterator *) py_sv_it)->sv_it; + ((BPy_StrokeVertexIterator *) py_sv_it)->reversed = reversed; + + return py_sv_it; +} + +PyObject * BPy_SVertexIterator_from_SVertexIterator( ViewEdgeInternal::SVertexIterator& sv_it ) { + PyObject *py_sv_it = SVertexIterator_Type.tp_new( &SVertexIterator_Type, 0, 0 ); + ((BPy_SVertexIterator *) py_sv_it)->sv_it = new ViewEdgeInternal::SVertexIterator( sv_it ); + ((BPy_SVertexIterator *) py_sv_it)->py_it.it = ((BPy_SVertexIterator *) py_sv_it)->sv_it; + + return py_sv_it; +} + + +PyObject * BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator( ViewVertexInternal::orientedViewEdgeIterator& ove_it, int reversed ) { + PyObject *py_ove_it = orientedViewEdgeIterator_Type.tp_new( &orientedViewEdgeIterator_Type, 0, 0 ); + ((BPy_orientedViewEdgeIterator *) py_ove_it)->ove_it = new ViewVertexInternal::orientedViewEdgeIterator( ove_it ); + ((BPy_orientedViewEdgeIterator *) py_ove_it)->py_it.it = ((BPy_orientedViewEdgeIterator *) py_ove_it)->ove_it; + ((BPy_orientedViewEdgeIterator *) py_ove_it)->reversed = reversed; + + return py_ove_it; +} + +PyObject * BPy_ViewEdgeIterator_from_ViewEdgeIterator( ViewEdgeInternal::ViewEdgeIterator& ve_it ) { + PyObject *py_ve_it = ViewEdgeIterator_Type.tp_new( &ViewEdgeIterator_Type, 0, 0 ); + ((BPy_ViewEdgeIterator *) py_ve_it)->ve_it = new ViewEdgeInternal::ViewEdgeIterator( ve_it ); + ((BPy_ViewEdgeIterator *) py_ve_it)->py_it.it = ((BPy_ViewEdgeIterator *) py_ve_it)->ve_it; + + return py_ve_it; +} + +PyObject * BPy_ChainingIterator_from_ChainingIterator( ChainingIterator& c_it ) { + PyObject *py_c_it = ChainingIterator_Type.tp_new( &ChainingIterator_Type, 0, 0 ); + ((BPy_ChainingIterator *) py_c_it)->c_it = new ChainingIterator( c_it ); + ((BPy_ChainingIterator *) py_c_it)->py_ve_it.py_it.it = ((BPy_ChainingIterator *) py_c_it)->c_it; + + return py_c_it; +} + +PyObject * BPy_ChainPredicateIterator_from_ChainPredicateIterator( ChainPredicateIterator& cp_it ) { + PyObject *py_cp_it = ChainPredicateIterator_Type.tp_new( &ChainPredicateIterator_Type, 0, 0 ); + ((BPy_ChainPredicateIterator *) py_cp_it)->cp_it = new ChainPredicateIterator( cp_it ); + ((BPy_ChainPredicateIterator *) py_cp_it)->py_c_it.py_ve_it.py_it.it = ((BPy_ChainPredicateIterator *) py_cp_it)->cp_it; + + return py_cp_it; +} + +PyObject * BPy_ChainSilhouetteIterator_from_ChainSilhouetteIterator( ChainSilhouetteIterator& cs_it ) { + PyObject *py_cs_it = ChainSilhouetteIterator_Type.tp_new( &ChainSilhouetteIterator_Type, 0, 0 ); + ((BPy_ChainSilhouetteIterator *) py_cs_it)->cs_it = new ChainSilhouetteIterator( cs_it ); + ((BPy_ChainSilhouetteIterator *) py_cs_it)->py_c_it.py_ve_it.py_it.it = ((BPy_ChainSilhouetteIterator *) py_cs_it)->cs_it; + + return py_cs_it; +} + + +//============================== +// Python => C++ +//============================== + +bool bool_from_PyBool( PyObject *b ) { + return PyObject_IsTrue(b) != 0; +} + +IntegrationType IntegrationType_from_BPy_IntegrationType( PyObject* obj ) { + return static_cast<IntegrationType>( PyLong_AsLong(obj) ); +} + +Stroke::MediumType MediumType_from_BPy_MediumType( PyObject* obj ) { + return static_cast<Stroke::MediumType>( PyLong_AsLong(obj) ); +} + +Nature::EdgeNature EdgeNature_from_BPy_Nature( PyObject* obj ) { + return static_cast<Nature::EdgeNature>( PyLong_AsLong(obj) ); +} + +Vec2f * Vec2f_ptr_from_PyObject( PyObject* obj ) { + Vec2f *v; + if( (v = Vec2f_ptr_from_Vector( obj )) ) + return v; + if( (v = Vec2f_ptr_from_PyList( obj )) ) + return v; + if( (v = Vec2f_ptr_from_PyTuple( obj )) ) + return v; + return NULL; +} + +Vec3f * Vec3f_ptr_from_PyObject( PyObject* obj ) { + Vec3f *v; + if( (v = Vec3f_ptr_from_Vector( obj )) ) + return v; + if( (v = Vec3f_ptr_from_PyList( obj )) ) + return v; + if( (v = Vec3f_ptr_from_PyTuple( obj )) ) + return v; + return NULL; +} + +Vec3r * Vec3r_ptr_from_PyObject( PyObject* obj ) { + Vec3r *v; + if( (v = Vec3r_ptr_from_Vector( obj )) ) + return v; + if( (v = Vec3r_ptr_from_PyList( obj )) ) + return v; + if( (v = Vec3r_ptr_from_PyTuple( obj )) ) + return v; + return NULL; +} + +Vec2f * Vec2f_ptr_from_Vector( PyObject* obj ) { + PyObject *v; + if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 2) + return NULL; + v = PyObject_GetAttrString(obj,"x"); + float x = PyFloat_AsDouble( v ); + Py_DECREF( v ); + v = PyObject_GetAttrString(obj,"y"); + float y = PyFloat_AsDouble( v ); + Py_DECREF( v ); + + return new Vec2f(x,y); +} + +Vec3f * Vec3f_ptr_from_Vector( PyObject* obj ) { + PyObject *v; + if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3) + return NULL; + v = PyObject_GetAttrString(obj,"x"); + float x = PyFloat_AsDouble( v ); + Py_DECREF( v ); + v = PyObject_GetAttrString(obj,"y"); + float y = PyFloat_AsDouble( v ); + Py_DECREF( v ); + v = PyObject_GetAttrString(obj,"z"); + float z = PyFloat_AsDouble( v ); + Py_DECREF( v ); + + return new Vec3f(x,y,z); +} + +Vec3r * Vec3r_ptr_from_Vector( PyObject* obj ) { + PyObject *v; + if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3) + return NULL; + v = PyObject_GetAttrString(obj,"x"); + double x = PyFloat_AsDouble( v ); + Py_DECREF( v ); + v = PyObject_GetAttrString(obj,"y"); + double y = PyFloat_AsDouble( v ); + Py_DECREF( v ); + v = PyObject_GetAttrString(obj,"z"); + double z = PyFloat_AsDouble( v ); + Py_DECREF( v ); + + return new Vec3r(x,y,z); +} + +Vec2f * Vec2f_ptr_from_PyList( PyObject* obj ) { + if( !PyList_Check(obj) || PyList_Size(obj) != 2 ) + return NULL; + float x = PyFloat_AsDouble(PyList_GetItem(obj, 0)); + float y = PyFloat_AsDouble(PyList_GetItem(obj, 1)); + return new Vec2f(x,y); +} + +Vec3f * Vec3f_ptr_from_PyList( PyObject* obj ) { + if( !PyList_Check(obj) || PyList_Size(obj) != 3 ) + return NULL; + float x = PyFloat_AsDouble(PyList_GetItem(obj, 0)); + float y = PyFloat_AsDouble(PyList_GetItem(obj, 1)); + float z = PyFloat_AsDouble(PyList_GetItem(obj, 2)); + return new Vec3f(x,y,z); +} + +Vec3r * Vec3r_ptr_from_PyList( PyObject* obj ) { + if( !PyList_Check(obj) || PyList_Size(obj) != 3 ) + return NULL; + float x = PyFloat_AsDouble(PyList_GetItem(obj, 0)); + float y = PyFloat_AsDouble(PyList_GetItem(obj, 1)); + float z = PyFloat_AsDouble(PyList_GetItem(obj, 2)); + return new Vec3r(x,y,z); +} + +Vec2f * Vec2f_ptr_from_PyTuple( PyObject* obj ) { + if( !PyTuple_Check(obj) || PyTuple_Size(obj) != 2 ) + return NULL; + float x = PyFloat_AsDouble(PyTuple_GetItem(obj, 0)); + float y = PyFloat_AsDouble(PyTuple_GetItem(obj, 1)); + return new Vec2f(x,y); +} + +Vec3f * Vec3f_ptr_from_PyTuple( PyObject* obj ) { + if( !PyTuple_Check(obj) || PyTuple_Size(obj) != 3 ) + return NULL; + float x = PyFloat_AsDouble(PyTuple_GetItem(obj, 0)); + float y = PyFloat_AsDouble(PyTuple_GetItem(obj, 1)); + float z = PyFloat_AsDouble(PyTuple_GetItem(obj, 2)); + return new Vec3f(x,y,z); +} + +Vec3r * Vec3r_ptr_from_PyTuple( PyObject* obj ) { + if( !PyTuple_Check(obj) || PyTuple_Size(obj) != 3 ) + return NULL; + float x = PyFloat_AsDouble(PyTuple_GetItem(obj, 0)); + float y = PyFloat_AsDouble(PyTuple_GetItem(obj, 1)); + float z = PyFloat_AsDouble(PyTuple_GetItem(obj, 2)); + return new Vec3r(x,y,z); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_Convert.h b/source/blender/freestyle/intern/python/BPy_Convert.h new file mode 100644 index 00000000000..3c0ada2ce76 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Convert.h @@ -0,0 +1,147 @@ +#ifndef FREESTYLE_PYTHON_CONVERT_H +#define FREESTYLE_PYTHON_CONVERT_H + +#include <typeinfo> + +#include "../geometry/Geom.h" +using namespace Geometry; + +// BBox +#include "../geometry/BBox.h" + +// FEdge, FEdgeSharp, FEdgeSmooth, SShape, SVertex, FEdgeInternal::SVertexIterator +#include "../view_map/Silhouette.h" + +// Id +#include "../system/Id.h" + +// Interface0D, Interface0DIteratorNested, Interface0DIterator +#include "../view_map/Interface0D.h" + +// Interface1D +#include "../view_map/Interface1D.h" + +// FrsMaterial +#include "../scene_graph/FrsMaterial.h" + +// Nature::VertexNature, Nature::EdgeNature +#include "../winged_edge/Nature.h" + +// Stroke, StrokeAttribute, StrokeVertex +#include "../stroke/Stroke.h" + +// NonTVertex, TVertex, ViewEdge, ViewMap, ViewShape, ViewVertex +#include "../view_map/ViewMap.h" + +// CurvePoint, Curve +#include "../stroke/Curve.h" + +// Chain +#include "../stroke/Chain.h" + +//====== ITERATORS + +// AdjacencyIterator, ChainingIterator, ChainSilhouetteIterator, ChainPredicateIterator +#include "../stroke/ChainingIterators.h" + +// ViewVertexInternal::orientedViewEdgeIterator +// ViewEdgeInternal::SVertexIterator +// ViewEdgeInternal::ViewEdgeIterator +#include "../view_map/ViewMapIterators.h" + +// StrokeInternal::StrokeVertexIterator +#include "../stroke/StrokeIterators.h" + +// CurveInternal::CurvePointIterator +#include "../stroke/CurveIterators.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> +#include "generic/Mathutils.h" + +//============================== +// C++ => Python +//============================== + +PyObject * PyBool_from_bool( bool b ); +PyObject * Vector_from_Vec2f( Vec2f& v ); +PyObject * Vector_from_Vec3f( Vec3f& v ); +PyObject * Vector_from_Vec3r( Vec3r& v ); + +PyObject * Any_BPy_Interface0D_from_Interface0D( Interface0D& if0D ); +PyObject * Any_BPy_Interface1D_from_Interface1D( Interface1D& if1D ); +PyObject * Any_BPy_FEdge_from_FEdge( FEdge& fe ); +PyObject * Any_BPy_ViewVertex_from_ViewVertex( ViewVertex& vv ); + +PyObject * BPy_BBox_from_BBox( BBox< Vec3r > &bb ); +PyObject * BPy_CurvePoint_from_CurvePoint( CurvePoint& cp ); +PyObject * BPy_directedViewEdge_from_directedViewEdge( ViewVertex::directedViewEdge& dve ); +PyObject * BPy_FEdge_from_FEdge( FEdge& fe ); +PyObject * BPy_FEdgeSharp_from_FEdgeSharp( FEdgeSharp& fes ); +PyObject * BPy_FEdgeSmooth_from_FEdgeSmooth( FEdgeSmooth& fes ); +PyObject * BPy_Id_from_Id( Id& id ); +PyObject * BPy_Interface0D_from_Interface0D( Interface0D& if0D ); +PyObject * BPy_Interface1D_from_Interface1D( Interface1D& if1D ); +PyObject * BPy_IntegrationType_from_IntegrationType( IntegrationType i ); +PyObject * BPy_FrsMaterial_from_FrsMaterial( FrsMaterial& m ); +PyObject * BPy_Nature_from_Nature( unsigned short n ); +PyObject * BPy_MediumType_from_MediumType( Stroke::MediumType n ); +PyObject * BPy_SShape_from_SShape( SShape& ss ); +PyObject * BPy_Stroke_from_Stroke( Stroke& s ); +PyObject * BPy_StrokeAttribute_from_StrokeAttribute( StrokeAttribute& sa ); +PyObject * BPy_StrokeVertex_from_StrokeVertex( StrokeVertex& sv ); +PyObject * BPy_SVertex_from_SVertex( SVertex& sv ); +PyObject * BPy_ViewVertex_from_ViewVertex( ViewVertex& vv ); +PyObject * BPy_NonTVertex_from_NonTVertex( NonTVertex& ntv ); +PyObject * BPy_TVertex_from_TVertex( TVertex& tv ); +PyObject * BPy_ViewEdge_from_ViewEdge( ViewEdge& ve ); +PyObject * BPy_Chain_from_Chain( Chain& c ); +PyObject * BPy_ViewShape_from_ViewShape( ViewShape& vs ); + +PyObject * BPy_AdjacencyIterator_from_AdjacencyIterator( AdjacencyIterator& a_it ); +PyObject * BPy_Interface0DIterator_from_Interface0DIterator( Interface0DIterator& if0D_it, int reversed ); +PyObject * BPy_CurvePointIterator_from_CurvePointIterator( CurveInternal::CurvePointIterator& cp_it ); +PyObject * BPy_StrokeVertexIterator_from_StrokeVertexIterator( StrokeInternal::StrokeVertexIterator& sv_it, int reversed); +PyObject * BPy_SVertexIterator_from_SVertexIterator( ViewEdgeInternal::SVertexIterator& sv_it ); +PyObject * BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator( ViewVertexInternal::orientedViewEdgeIterator& ove_it, int reversed ); +PyObject * BPy_ViewEdgeIterator_from_ViewEdgeIterator( ViewEdgeInternal::ViewEdgeIterator& ve_it ); +PyObject * BPy_ChainingIterator_from_ChainingIterator( ChainingIterator& c_it ); +PyObject * BPy_ChainPredicateIterator_from_ChainPredicateIterator( ChainPredicateIterator& cp_it ); +PyObject * BPy_ChainSilhouetteIterator_from_ChainSilhouetteIterator( ChainSilhouetteIterator& cs_it ); + +//============================== +// Python => C++ +//============================== + +bool bool_from_PyBool( PyObject *b ); +IntegrationType IntegrationType_from_BPy_IntegrationType( PyObject* obj ); +Stroke::MediumType MediumType_from_BPy_MediumType( PyObject* obj ); +Nature::EdgeNature EdgeNature_from_BPy_Nature( PyObject* obj ); +Vec2f * Vec2f_ptr_from_PyObject( PyObject* obj ); +Vec3f * Vec3f_ptr_from_PyObject( PyObject* obj ); +Vec3r * Vec3r_ptr_from_PyObject( PyObject* obj ); +Vec2f * Vec2f_ptr_from_Vector( PyObject* obj ); +Vec3f * Vec3f_ptr_from_Vector( PyObject* obj ); +Vec3r * Vec3r_ptr_from_Vector( PyObject* obj ); +Vec2f * Vec2f_ptr_from_PyList( PyObject* obj ); +Vec3f * Vec3f_ptr_from_PyList( PyObject* obj ); +Vec3r * Vec3r_ptr_from_PyList( PyObject* obj ); +Vec2f * Vec2f_ptr_from_PyTuple( PyObject* obj ); +Vec3f * Vec3f_ptr_from_PyTuple( PyObject* obj ); +Vec3r * Vec3r_ptr_from_PyTuple( PyObject* obj ); + + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_CONVERT_H */ diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp new file mode 100644 index 00000000000..3e8572d07ae --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp @@ -0,0 +1,120 @@ +#include "BPy_Freestyle.h" + +#include "BPy_BBox.h" +#include "BPy_BinaryPredicate0D.h" +#include "BPy_BinaryPredicate1D.h" +#include "BPy_ContextFunctions.h" +#include "BPy_FrsMaterial.h" +#include "BPy_FrsNoise.h" +#include "BPy_Id.h" +#include "BPy_IntegrationType.h" +#include "BPy_Interface0D.h" +#include "BPy_Interface1D.h" +#include "BPy_Iterator.h" +#include "BPy_MediumType.h" +#include "BPy_Nature.h" +#include "BPy_Operators.h" +#include "BPy_SShape.h" +#include "BPy_StrokeAttribute.h" +#include "BPy_StrokeShader.h" +#include "BPy_UnaryFunction0D.h" +#include "BPy_UnaryFunction1D.h" +#include "BPy_UnaryPredicate0D.h" +#include "BPy_UnaryPredicate1D.h" +#include "BPy_ViewMap.h" +#include "BPy_ViewShape.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + + +//static PyObject *Freestyle_testOutput( BPy_Freestyle * self ); +static PyObject *Freestyle_getCurrentScene( PyObject *self ); + +/*-----------------------Freestyle module doc strings--------------------------*/ + +static char module_docstring[] = "The Blender Freestyle module\n\n"; + +/*-----------------------Freestyle module method def---------------------------*/ + +static PyMethodDef module_functions[] = { +// {"testOutput", ( PyCFunction ) Freestyle_testOutput, METH_NOARGS, "() - Return Curve Data name"}, + {"getCurrentScene", ( PyCFunction ) Freestyle_getCurrentScene, METH_NOARGS, "() - Return the current scene."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------Freestyle module definition---------------------------*/ + +static PyModuleDef module_definition = { + PyModuleDef_HEAD_INIT, + "Freestyle", + module_docstring, + -1, + module_functions +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +PyObject *Freestyle_Init( void ) +{ + PyObject *module; + + // initialize modules + module = PyModule_Create(&module_definition); + if (!module) + return NULL; + PyDict_SetItemString(PySys_GetObject("modules"), module_definition.m_name, module); + + // attach its classes (adding the object types to the module) + + // those classes have to be initialized before the others + MediumType_Init( module ); + Nature_Init( module ); + + BBox_Init( module ); + BinaryPredicate0D_Init( module ); + BinaryPredicate1D_Init( module ); + ContextFunctions_Init( module ); + FrsMaterial_Init( module ); + FrsNoise_Init( module ); + Id_Init( module ); + IntegrationType_Init( module ); + Interface0D_Init( module ); + Interface1D_Init( module ); + Iterator_Init( module ); + Operators_Init( module ); + SShape_Init( module ); + StrokeAttribute_Init( module ); + StrokeShader_Init( module ); + UnaryFunction0D_Init( module ); + UnaryFunction1D_Init( module ); + UnaryPredicate0D_Init( module ); + UnaryPredicate1D_Init( module ); + ViewMap_Init( module ); + ViewShape_Init( module ); + + return module; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include "FRS_freestyle.h" +#include "bpy_rna.h" /* pyrna_struct_CreatePyObject() */ + +static PyObject *Freestyle_getCurrentScene( PyObject *self ) +{ + if (!freestyle_scene) { + PyErr_SetString(PyExc_TypeError, "current scene not available"); + return NULL; + } + PointerRNA ptr_scene; + RNA_pointer_create(NULL, &RNA_Scene, freestyle_scene, &ptr_scene); + return pyrna_struct_CreatePyObject(&ptr_scene); +} + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.h b/source/blender/freestyle/intern/python/BPy_Freestyle.h new file mode 100644 index 00000000000..4a280cee5af --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Freestyle.h @@ -0,0 +1,22 @@ +#ifndef FREESTYLE_PYTHON_FREESTYLE_H +#define FREESTYLE_PYTHON_FREESTYLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +/*---------------------------Python BPy_Freestyle visible prototypes-----------*/ + +PyObject *Freestyle_Init( void ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_FREESTYLE_H */ diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp new file mode 100644 index 00000000000..462ea7e3430 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp @@ -0,0 +1,369 @@ +#include "BPy_FrsMaterial.h" + +#include "BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for FrsMaterial instance -----------*/ +static int FrsMaterial___init__(BPy_FrsMaterial *self, PyObject *args, PyObject *kwds); +static void FrsMaterial___dealloc__(BPy_FrsMaterial *self); +static PyObject * FrsMaterial___repr__(BPy_FrsMaterial *self); + +static PyObject * FrsMaterial_diffuse( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_diffuseR( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_diffuseG( BPy_FrsMaterial* self) ; +static PyObject * FrsMaterial_diffuseB( BPy_FrsMaterial* self) ; +static PyObject * FrsMaterial_diffuseA( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_specular( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_specularR( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_specularG( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_specularB( BPy_FrsMaterial* self) ; +static PyObject * FrsMaterial_specularA( BPy_FrsMaterial* self) ; +static PyObject * FrsMaterial_ambient( BPy_FrsMaterial* self) ; +static PyObject * FrsMaterial_ambientR( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_ambientG( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_ambientB( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_ambientA( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_emission( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_emissionR( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_emissionG( BPy_FrsMaterial* self) ; +static PyObject * FrsMaterial_emissionB( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_emissionA( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_shininess( BPy_FrsMaterial* self); +static PyObject * FrsMaterial_setDiffuse( BPy_FrsMaterial *self, PyObject *args ); +static PyObject * FrsMaterial_setSpecular( BPy_FrsMaterial *self, PyObject *args ); +static PyObject * FrsMaterial_setAmbient( BPy_FrsMaterial *self, PyObject *args ); +static PyObject * FrsMaterial_setEmission( BPy_FrsMaterial *self, PyObject *args ); +static PyObject * FrsMaterial_setShininess( BPy_FrsMaterial *self, PyObject *args ); + +/*----------------------FrsMaterial instance definitions ----------------------------*/ +static PyMethodDef BPy_FrsMaterial_methods[] = { + {"diffuse", ( PyCFunction ) FrsMaterial_diffuse, METH_NOARGS, "() Returns the diffuse color as a 4 float array"}, + {"diffuseR", ( PyCFunction ) FrsMaterial_diffuseR, METH_NOARGS, "() Returns the red component of the diffuse color "}, + {"diffuseG", ( PyCFunction ) FrsMaterial_diffuseG, METH_NOARGS, "() Returns the green component of the diffuse color "}, + {"diffuseB", ( PyCFunction ) FrsMaterial_diffuseB, METH_NOARGS, "() Returns the blue component of the diffuse color "}, + {"diffuseA", ( PyCFunction ) FrsMaterial_diffuseA, METH_NOARGS, "() Returns the alpha component of the diffuse color "}, + {"specular", ( PyCFunction ) FrsMaterial_specular, METH_NOARGS, "() Returns the specular color as a 4 float array"}, + {"specularR", ( PyCFunction ) FrsMaterial_specularR, METH_NOARGS, "() Returns the red component of the specular color "}, + {"specularG", ( PyCFunction ) FrsMaterial_specularG, METH_NOARGS, "() Returns the green component of the specular color "}, + {"specularB", ( PyCFunction ) FrsMaterial_specularB, METH_NOARGS, "() Returns the blue component of the specular color "}, + {"specularA", ( PyCFunction ) FrsMaterial_specularA, METH_NOARGS, "() Returns the alpha component of the specular color "}, + {"ambient", ( PyCFunction ) FrsMaterial_ambient, METH_NOARGS, "() Returns the ambient color as a 4 float array"}, + {"ambientR", ( PyCFunction ) FrsMaterial_ambientR, METH_NOARGS, "() Returns the red component of the ambient color "}, + {"ambientG", ( PyCFunction ) FrsMaterial_ambientG, METH_NOARGS, "() Returns the green component of the ambient color "}, + {"ambientB", ( PyCFunction ) FrsMaterial_ambientB, METH_NOARGS, "() Returns the blue component of the ambient color "}, + {"ambientA", ( PyCFunction ) FrsMaterial_ambientA, METH_NOARGS, "() Returns the alpha component of the ambient color "}, + {"emission", ( PyCFunction ) FrsMaterial_emission, METH_NOARGS, "() Returns the emission color as a 4 float array"}, + {"emissionR", ( PyCFunction ) FrsMaterial_emissionR, METH_NOARGS, "() Returns the red component of the emission color "}, + {"emissionG", ( PyCFunction ) FrsMaterial_emissionG, METH_NOARGS, "() Returns the green component of the emission color "}, + {"emissionB", ( PyCFunction ) FrsMaterial_emissionB, METH_NOARGS, "() Returns the blue component of the emission color "}, + {"emissionA", ( PyCFunction ) FrsMaterial_emissionA, METH_NOARGS, "() Returns the alpha component of the emission color "}, + {"shininess", ( PyCFunction ) FrsMaterial_shininess, METH_NOARGS, "() Returns the shininess coefficient "}, + {"setDiffuse", ( PyCFunction ) FrsMaterial_setDiffuse, METH_NOARGS, "(float r, float g, float b, float a) Sets the diffuse color"}, + {"setSpecular", ( PyCFunction ) FrsMaterial_setSpecular, METH_NOARGS, "(float r, float g, float b, float a) Sets the specular color"}, + {"setAmbient", ( PyCFunction ) FrsMaterial_setAmbient, METH_NOARGS, "(float r, float g, float b, float a) Sets the ambient color"}, + {"setEmission", ( PyCFunction ) FrsMaterial_setEmission, METH_NOARGS, "(float r, float g, float b, float a) Sets the emission color"}, + {"setShininess", ( PyCFunction ) FrsMaterial_setShininess, METH_NOARGS, "(float r, float g, float b, float a) Sets the shininess color"}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_FrsMaterial type definition ------------------------------*/ + +PyTypeObject FrsMaterial_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "FrsMaterial", /* tp_name */ + sizeof(BPy_FrsMaterial), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)FrsMaterial___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)FrsMaterial___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "FrsMaterial objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_FrsMaterial_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FrsMaterial___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int FrsMaterial_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &FrsMaterial_Type ) < 0 ) + return -1; + + Py_INCREF( &FrsMaterial_Type ); + PyModule_AddObject(module, "FrsMaterial", (PyObject *)&FrsMaterial_Type); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +static int Vec4(PyObject *obj, float *v) +{ + if (VectorObject_Check(obj) && ((VectorObject *)obj)->size == 4) { + for (int i = 0; i < 4; i++) + v[i] = ((VectorObject *)obj)->vec[i]; + } else if( PyList_Check(obj) && PyList_Size(obj) == 4 ) { + for (int i = 0; i < 4; i++) + v[i] = PyFloat_AsDouble(PyList_GetItem(obj, i)); + } else if( PyTuple_Check(obj) && PyTuple_Size(obj) == 4 ) { + for (int i = 0; i < 4; i++) + v[i] = PyFloat_AsDouble(PyTuple_GetItem(obj, i)); + } else { + return 0; + } + return 1; +} + +int FrsMaterial___init__(BPy_FrsMaterial *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0, *obj4 = 0; + float f1[4], f2[4], f3[4], f4[4], f5 = 0.; + + if (! PyArg_ParseTuple(args, "|OOOOf", &obj1, &obj2, &obj3, &obj4, &f5) ) + return -1; + + if( !obj1 ){ + self->m = new FrsMaterial(); + + } else if( BPy_FrsMaterial_Check(obj1) && !obj2 ) { + FrsMaterial *m = ((BPy_FrsMaterial *) obj1)->m; + if( !m ) { + PyErr_SetString(PyExc_RuntimeError, "invalid FrsMaterial object"); + return -1; + } + self->m = new FrsMaterial( *m ); + + } else if( Vec4(obj1, f1) && obj2 && Vec4(obj2, f2) && obj3 && Vec4(obj3, f3) && obj4 && Vec4(obj4, f4) ) { + self->m = new FrsMaterial(f1, f2, f3, f4, f5); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument(s)"); + return -1; + } + self->borrowed = 0; + + return 0; +} + +void FrsMaterial___dealloc__( BPy_FrsMaterial* self) +{ + if( self->m && !self->borrowed ) + delete self->m; + Py_TYPE(self)->tp_free((PyObject*)self); +} + + +PyObject * FrsMaterial___repr__( BPy_FrsMaterial* self) +{ + return PyUnicode_FromFormat("FrsMaterial - address: %p", self->m ); +} + +PyObject * FrsMaterial_diffuse( BPy_FrsMaterial* self) { + const float *diffuse = self->m->diffuse(); + PyObject *py_diffuse = PyTuple_New(4); + + PyTuple_SetItem( py_diffuse, 0, PyFloat_FromDouble( diffuse[0] ) ); + PyTuple_SetItem( py_diffuse, 1, PyFloat_FromDouble( diffuse[1] ) ); + PyTuple_SetItem( py_diffuse, 2, PyFloat_FromDouble( diffuse[2] ) ); + PyTuple_SetItem( py_diffuse, 3, PyFloat_FromDouble( diffuse[3] ) ); + + return py_diffuse; +} + +PyObject * FrsMaterial_diffuseR( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->diffuseR() ); +} + +PyObject * FrsMaterial_diffuseG( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->diffuseG() ); +} + +PyObject * FrsMaterial_diffuseB( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->diffuseB() ); +} + +PyObject * FrsMaterial_diffuseA( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->diffuseA() ); +} + +PyObject * FrsMaterial_specular( BPy_FrsMaterial* self) { + const float *specular = self->m->specular(); + PyObject *py_specular = PyTuple_New(4); + + PyTuple_SetItem( py_specular, 0, PyFloat_FromDouble( specular[0] ) ); + PyTuple_SetItem( py_specular, 1, PyFloat_FromDouble( specular[1] ) ); + PyTuple_SetItem( py_specular, 2, PyFloat_FromDouble( specular[2] ) ); + PyTuple_SetItem( py_specular, 3, PyFloat_FromDouble( specular[3] ) ); + + return py_specular; +} + +PyObject * FrsMaterial_specularR( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->specularR() ); +} + +PyObject * FrsMaterial_specularG( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->specularG() ); +} + +PyObject * FrsMaterial_specularB( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->specularB() ); +} + +PyObject * FrsMaterial_specularA( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->specularA() ); +} + +PyObject * FrsMaterial_ambient( BPy_FrsMaterial* self) { + const float *ambient = self->m->ambient(); + PyObject *py_ambient = PyTuple_New(4); + + PyTuple_SetItem( py_ambient, 0, PyFloat_FromDouble( ambient[0] ) ); + PyTuple_SetItem( py_ambient, 1, PyFloat_FromDouble( ambient[1] ) ); + PyTuple_SetItem( py_ambient, 2, PyFloat_FromDouble( ambient[2] ) ); + PyTuple_SetItem( py_ambient, 3, PyFloat_FromDouble( ambient[3] ) ); + + return py_ambient; +} + +PyObject * FrsMaterial_ambientR( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->ambientR() ); +} + +PyObject * FrsMaterial_ambientG( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->ambientG() ); +} + +PyObject * FrsMaterial_ambientB( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->ambientB() ); +} + +PyObject * FrsMaterial_ambientA( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->ambientA() ); +} + +PyObject * FrsMaterial_emission( BPy_FrsMaterial* self) { + const float *emission = self->m->emission(); + PyObject *py_emission = PyTuple_New(4); + + PyTuple_SetItem( py_emission, 0, PyFloat_FromDouble( emission[0] ) ); + PyTuple_SetItem( py_emission, 1, PyFloat_FromDouble( emission[1] ) ); + PyTuple_SetItem( py_emission, 2, PyFloat_FromDouble( emission[2] ) ); + PyTuple_SetItem( py_emission, 3, PyFloat_FromDouble( emission[3] ) ); + + return py_emission; +} + +PyObject * FrsMaterial_emissionR( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->emissionR() ); +} + +PyObject * FrsMaterial_emissionG( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->emissionG() ); +} + +PyObject * FrsMaterial_emissionB( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->emissionB() ); +} + +PyObject * FrsMaterial_emissionA( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->emissionA() ); +} + +PyObject * FrsMaterial_shininess( BPy_FrsMaterial* self) { + return PyFloat_FromDouble( self->m->shininess() ); +} + +PyObject * FrsMaterial_setDiffuse( BPy_FrsMaterial *self, PyObject *args ) { + float f1, f2, f3, f4; + + if(!( PyArg_ParseTuple(args, "ffff", &f1, &f2, &f3, &f4) )) + return NULL; + + self->m->setDiffuse(f1, f2, f3, f4); + + Py_RETURN_NONE; +} + +PyObject * FrsMaterial_setSpecular( BPy_FrsMaterial *self, PyObject *args ) { + float f1, f2, f3, f4; + + if(!( PyArg_ParseTuple(args, "ffff", &f1, &f2, &f3, &f4) )) + return NULL; + + self->m->setSpecular(f1, f2, f3, f4); + + Py_RETURN_NONE; +} + +PyObject * FrsMaterial_setAmbient( BPy_FrsMaterial *self, PyObject *args ) { + float f1, f2, f3, f4; + + if(!( PyArg_ParseTuple(args, "ffff", &f1, &f2, &f3, &f4) )) + return NULL; + + self->m->setAmbient(f1, f2, f3, f4); + + Py_RETURN_NONE; +} + +PyObject * FrsMaterial_setEmission( BPy_FrsMaterial *self, PyObject *args ) { + float f1, f2, f3, f4; + + if(!( PyArg_ParseTuple(args, "ffff", &f1, &f2, &f3, &f4) )) + return NULL; + + self->m->setEmission(f1, f2, f3, f4); + + Py_RETURN_NONE; +} + +PyObject * FrsMaterial_setShininess( BPy_FrsMaterial *self, PyObject *args ) { + float f; + + if(!( PyArg_ParseTuple(args, "f", &f) )) + return NULL; + + self->m->setShininess(f); + + Py_RETURN_NONE; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.h b/source/blender/freestyle/intern/python/BPy_FrsMaterial.h new file mode 100644 index 00000000000..01bdabc09d9 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.h @@ -0,0 +1,37 @@ +#ifndef FREESTYLE_PYTHON_FRSMATERIAL_H +#define FREESTYLE_PYTHON_FRSMATERIAL_H + +#include "../scene_graph/FrsMaterial.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject FrsMaterial_Type; + +#define BPy_FrsMaterial_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &FrsMaterial_Type) ) + +/*---------------------------Python BPy_FrsMaterial structure definition----------*/ +typedef struct { + PyObject_HEAD + FrsMaterial *m; + int borrowed; /* non-zero if *m is a borrowed object */ +} BPy_FrsMaterial; + +/*---------------------------Python BPy_FrsMaterial visible prototypes-----------*/ + +int FrsMaterial_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_FRSMATERIAL_H */ diff --git a/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp b/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp new file mode 100644 index 00000000000..8c21fa63ba1 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_FrsNoise.cpp @@ -0,0 +1,203 @@ +#include "BPy_FrsNoise.h" +#include "BPy_Convert.h" + +#include <sstream> + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for FrsNoise instance -----------*/ +static int FrsNoise___init__(BPy_FrsNoise *self, PyObject *args, PyObject *kwds); +static void FrsNoise___dealloc__(BPy_FrsNoise *self); +static PyObject * FrsNoise___repr__(BPy_FrsNoise *self); + +static PyObject * FrsNoise_turbulence1( BPy_FrsNoise *self, PyObject *args); +static PyObject * FrsNoise_turbulence2( BPy_FrsNoise *self, PyObject *args); +static PyObject * FrsNoise_turbulence3( BPy_FrsNoise *self, PyObject *args); +static PyObject * FrsNoise_smoothNoise1( BPy_FrsNoise *self, PyObject *args); +static PyObject * FrsNoise_smoothNoise2( BPy_FrsNoise *self, PyObject *args); +static PyObject * FrsNoise_smoothNoise3( BPy_FrsNoise *self, PyObject *args); + +/*----------------------FrsNoise instance definitions ----------------------------*/ +static PyMethodDef BPy_FrsNoise_methods[] = { + {"turbulence1", ( PyCFunction ) FrsNoise_turbulence1, METH_VARARGS, "(float arg, float freq, float amp, unsigned oct=4) Returns a noise value for a 1D element"}, + {"turbulence2", ( PyCFunction ) FrsNoise_turbulence2, METH_VARARGS, "([x, y], float freq, float amp, unsigned oct=4) Returns a noise value for a 2D element"}, + {"turbulence3", ( PyCFunction ) FrsNoise_turbulence3, METH_VARARGS, "([x, y, z], float freq, float amp, unsigned oct=4) Returns a noise value for a 3D element"}, + {"smoothNoise1", ( PyCFunction ) FrsNoise_smoothNoise1, METH_VARARGS, "(float arg) Returns a smooth noise value for a 1D element "}, + {"smoothNoise2", ( PyCFunction ) FrsNoise_smoothNoise2, METH_VARARGS, "([x, y]) Returns a smooth noise value for a 2D element "}, + {"smoothNoise3", ( PyCFunction ) FrsNoise_smoothNoise3, METH_VARARGS, "([x, y, z]) Returns a smooth noise value for a 3D element "}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_FrsNoise type definition ------------------------------*/ + +PyTypeObject FrsNoise_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "FrsNoise", /* tp_name */ + sizeof(BPy_FrsNoise), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)FrsNoise___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)FrsNoise___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "FrsNoise objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_FrsNoise_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FrsNoise___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int FrsNoise_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &FrsNoise_Type ) < 0 ) + return -1; + + Py_INCREF( &FrsNoise_Type ); + PyModule_AddObject(module, "FrsNoise", (PyObject *)&FrsNoise_Type); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int FrsNoise___init__(BPy_FrsNoise *self, PyObject *args, PyObject *kwds) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->n = new Noise(); + return 0; +} + +void FrsNoise___dealloc__(BPy_FrsNoise* self) +{ + delete self->n; + Py_TYPE(self)->tp_free((PyObject*)self); +} + + +PyObject * FrsNoise___repr__(BPy_FrsNoise* self) +{ + return PyUnicode_FromFormat("FrsNoise - address: %p", self->n ); +} + + +PyObject * FrsNoise_turbulence1( BPy_FrsNoise *self , PyObject *args) { + float f1, f2, f3; + unsigned int i = 4; + + if(!( PyArg_ParseTuple(args, "fff|I", &f1, &f2, &f3, &i) )) + return NULL; + + return PyFloat_FromDouble( self->n->turbulence1(f1, f2, f3, i) ); +} + +PyObject * FrsNoise_turbulence2( BPy_FrsNoise *self , PyObject *args) { + PyObject *obj1; + float f2, f3; + unsigned int i = 4; + + if(!( PyArg_ParseTuple(args, "Off|I", &obj1, &f2, &f3, &i) )) + return NULL; + Vec2f *v = Vec2f_ptr_from_PyObject(obj1); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 2D vector (either a list of 2 elements or Vector)"); + return NULL; + } + float t = self->n->turbulence2(*v, f2, f3, i); + delete v; + return PyFloat_FromDouble( t ); +} + +PyObject * FrsNoise_turbulence3( BPy_FrsNoise *self , PyObject *args) { + PyObject *obj1; + float f2, f3; + unsigned int i = 4; + + if(!( PyArg_ParseTuple(args, "Off|I", &obj1, &f2, &f3, &i) )) + return NULL; + Vec3f *v = Vec3f_ptr_from_PyObject(obj1); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); + return NULL; + } + float t = self->n->turbulence3(*v, f2, f3, i); + delete v; + return PyFloat_FromDouble( t ); +} + +PyObject * FrsNoise_smoothNoise1( BPy_FrsNoise *self , PyObject *args) { + float f; + + if(!( PyArg_ParseTuple(args, "f", &f) )) + return NULL; + + return PyFloat_FromDouble( self->n->smoothNoise1(f) ); +} + +PyObject * FrsNoise_smoothNoise2( BPy_FrsNoise *self , PyObject *args) { + PyObject *obj; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + Vec2f *v = Vec2f_ptr_from_PyObject(obj); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 2D vector (either a list of 2 elements or Vector)"); + return NULL; + } + float t = self->n->smoothNoise2(*v); + delete v; + return PyFloat_FromDouble( t ); +} + +PyObject * FrsNoise_smoothNoise3( BPy_FrsNoise *self , PyObject *args) { + PyObject *obj; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + Vec3f *v = Vec3f_ptr_from_PyObject(obj); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); + return NULL; + } + float t = self->n->smoothNoise3(*v); + delete v; + return PyFloat_FromDouble( t ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_FrsNoise.h b/source/blender/freestyle/intern/python/BPy_FrsNoise.h new file mode 100644 index 00000000000..9b06ea0c37d --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_FrsNoise.h @@ -0,0 +1,36 @@ +#ifndef FREESTYLE_PYTHON_FRSNOISE_H +#define FREESTYLE_PYTHON_FRSNOISE_H + +#include "../geometry/Noise.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject FrsNoise_Type; + +#define BPy_FrsNoise_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &FrsNoise_Type) ) + +/*---------------------------Python BPy_FrsNoise structure definition----------*/ +typedef struct { + PyObject_HEAD + Noise *n; +} BPy_FrsNoise; + +/*---------------------------Python BPy_FrsNoise visible prototypes-----------*/ + +int FrsNoise_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_FRSNOISE_H */ diff --git a/source/blender/freestyle/intern/python/BPy_Id.cpp b/source/blender/freestyle/intern/python/BPy_Id.cpp new file mode 100644 index 00000000000..3c157230cff --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Id.cpp @@ -0,0 +1,177 @@ +#include "BPy_Id.h" + +#include "BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Id instance -----------*/ +static int Id___init__(BPy_Id *self, PyObject *args, PyObject *kwds); +static void Id___dealloc__(BPy_Id *self); +static PyObject * Id___repr__(BPy_Id* self); +static PyObject * Id_RichCompare(BPy_Id *o1, BPy_Id *o2, int opid); + +static PyObject * Id_getFirst( BPy_Id *self ); +static PyObject * Id_getSecond( BPy_Id *self); +static PyObject * Id_setFirst( BPy_Id *self , PyObject *args); +static PyObject * Id_setSecond( BPy_Id *self , PyObject *args); + +/*----------------------Id instance definitions ----------------------------*/ +static PyMethodDef BPy_Id_methods[] = { + {"getFirst", ( PyCFunction ) Id_getFirst, METH_NOARGS, "Returns the first Id number"}, + {"getSecond", ( PyCFunction ) Id_getSecond, METH_NOARGS, "Returns the second Id number" }, + {"setFirst", ( PyCFunction ) Id_setFirst, METH_VARARGS, "Sets the first number constituing the Id" }, + {"setSecond", ( PyCFunction ) Id_setSecond, METH_VARARGS, "Sets the second number constituing the Id" }, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_Id type definition ------------------------------*/ + +PyTypeObject Id_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "Id", /* tp_name */ + sizeof(BPy_Id), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)Id___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)Id___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Id objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)Id_RichCompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_Id_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Id___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int Id_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &Id_Type ) < 0 ) + return -1; + + Py_INCREF( &Id_Type ); + PyModule_AddObject(module, "Id", (PyObject *)&Id_Type); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int Id___init__(BPy_Id *self, PyObject *args, PyObject *kwds) +{ + int first = 0, second = 0; + static char *kwlist[] = {"first", "second", NULL}; + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist, &first, &second) ) + return -1; + + self->id = new Id( first, second ); + + return 0; +} + +void Id___dealloc__(BPy_Id* self) +{ + delete self->id; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyObject * Id___repr__(BPy_Id* self) +{ + return PyUnicode_FromFormat("[ first: %i, second: %i ](BPy_Id)", self->id->getFirst(), self->id->getSecond() ); +} + +PyObject *Id_getFirst( BPy_Id *self ) { + return PyLong_FromLong( self->id->getFirst() ); +} + + +PyObject *Id_getSecond( BPy_Id *self) { + return PyLong_FromLong( self->id->getSecond() ); +} + + +PyObject *Id_setFirst( BPy_Id *self , PyObject *args) { + unsigned int i; + + if( !PyArg_ParseTuple(args, "i", &i) ) + return NULL; + + self->id->setFirst( i ); + + Py_RETURN_NONE; +} + + +PyObject *Id_setSecond( BPy_Id *self , PyObject *args) { + unsigned int i; + + if( !PyArg_ParseTuple(args, "i", &i) ) + return NULL; + + self->id->setSecond( i ); + + Py_RETURN_NONE; +} + +PyObject * Id_RichCompare(BPy_Id *o1, BPy_Id *o2, int opid) { + switch(opid){ + case Py_LT: + return PyBool_from_bool( o1->id->operator<(*(o2->id)) ); + break; + case Py_LE: + return PyBool_from_bool( o1->id->operator<(*(o2->id)) || o1->id->operator<(*(o2->id)) ); + break; + case Py_EQ: + return PyBool_from_bool( o1->id->operator==(*(o2->id)) ); + break; + case Py_NE: + return PyBool_from_bool( o1->id->operator!=(*(o2->id)) ); + break; + case Py_GT: + return PyBool_from_bool(!( o1->id->operator<(*(o2->id)) || o1->id->operator<(*(o2->id)) )); + break; + case Py_GE: + return PyBool_from_bool(!( o1->id->operator<(*(o2->id)) )); + break; + } + + Py_RETURN_NONE; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_Id.h b/source/blender/freestyle/intern/python/BPy_Id.h new file mode 100644 index 00000000000..3063334f075 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Id.h @@ -0,0 +1,37 @@ +#ifndef FREESTYLE_PYTHON_ID_H +#define FREESTYLE_PYTHON_ID_H + +#include <iostream> +using namespace std; + +#include "../system/Id.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Id_Type; + +#define BPy_Id_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Id_Type) ) + +/*---------------------------Python BPy_Id structure definition----------*/ +typedef struct { + PyObject_HEAD + Id *id; +} BPy_Id; + +/*---------------------------Python BPy_Id visible prototypes-----------*/ + +int Id_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_ID_H */ diff --git a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp new file mode 100644 index 00000000000..b40780a7778 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp @@ -0,0 +1,209 @@ +#include "BPy_IntegrationType.h" + +#include "BPy_Convert.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DDouble.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DFloat.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h" +#include "Iterator/BPy_Interface0DIterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +static PyObject * Integrator_integrate( PyObject *self, PyObject *args ); + +/*-----------------------Integrator module docstring---------------------------------------*/ + +static char module_docstring[] = "The Blender Freestyle.Integrator submodule\n\n"; + +/*-----------------------Integrator module functions definitions---------------------------*/ + +static PyMethodDef module_functions[] = { + {"integrate", (PyCFunction)Integrator_integrate, METH_VARARGS, ""}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------Integrator module definition--------------------------------------*/ + +static PyModuleDef module_definition = { + PyModuleDef_HEAD_INIT, + "Freestyle.Integrator", + module_docstring, + -1, + module_functions +}; + +/*-----------------------BPy_IntegrationType type definition ------------------------------*/ + +PyTypeObject IntegrationType_Type = { + PyObject_HEAD_INIT(NULL) + "IntegrationType", /* tp_name */ + sizeof(PyLongObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "IntegrationType objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyLong_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +/*-----------------------BPy_IntegrationType instance definitions -------------------------*/ + +static PyLongObject _IntegrationType_MEAN = { + PyVarObject_HEAD_INIT(&IntegrationType_Type, 1) + { MEAN } +}; +static PyLongObject _IntegrationType_MIN = { + PyVarObject_HEAD_INIT(&IntegrationType_Type, 1) + { MIN } +}; +static PyLongObject _IntegrationType_MAX = { + PyVarObject_HEAD_INIT(&IntegrationType_Type, 1) + { MAX } +}; +static PyLongObject _IntegrationType_FIRST = { + PyVarObject_HEAD_INIT(&IntegrationType_Type, 1) + { FIRST } +}; +static PyLongObject _IntegrationType_LAST = { + PyVarObject_HEAD_INIT(&IntegrationType_Type, 1) + { LAST } +}; + +#define BPy_IntegrationType_MEAN ((PyObject *)&_IntegrationType_MEAN) +#define BPy_IntegrationType_MIN ((PyObject *)&_IntegrationType_MIN) +#define BPy_IntegrationType_MAX ((PyObject *)&_IntegrationType_MAX) +#define BPy_IntegrationType_FIRST ((PyObject *)&_IntegrationType_FIRST) +#define BPy_IntegrationType_LAST ((PyObject *)&_IntegrationType_LAST) + +//-------------------MODULE INITIALIZATION-------------------------------- +int IntegrationType_Init( PyObject *module ) +{ + PyObject *m, *d, *f; + + if( module == NULL ) + return -1; + + if( PyType_Ready( &IntegrationType_Type ) < 0 ) + return -1; + Py_INCREF( &IntegrationType_Type ); + PyModule_AddObject(module, "IntegrationType", (PyObject *)&IntegrationType_Type); + + PyDict_SetItemString( IntegrationType_Type.tp_dict, "MEAN", BPy_IntegrationType_MEAN); + PyDict_SetItemString( IntegrationType_Type.tp_dict, "MIN", BPy_IntegrationType_MIN); + PyDict_SetItemString( IntegrationType_Type.tp_dict, "MAX", BPy_IntegrationType_MAX); + PyDict_SetItemString( IntegrationType_Type.tp_dict, "FIRST", BPy_IntegrationType_FIRST); + PyDict_SetItemString( IntegrationType_Type.tp_dict, "LAST", BPy_IntegrationType_LAST); + + m = PyModule_Create(&module_definition); + if (m == NULL) + return -1; + Py_INCREF(m); + PyModule_AddObject(module, "Integrator", m); + + // from Integrator import * + d = PyModule_GetDict(m); + for (PyMethodDef *p = module_functions; p->ml_name; p++) { + f = PyDict_GetItemString(d, p->ml_name); + Py_INCREF(f); + PyModule_AddObject(module, p->ml_name, f); + } + + return 0; +} + +//------------------------ MODULE FUNCTIONS ---------------------------------- + +static PyObject * Integrator_integrate( PyObject *self, PyObject *args ) +{ + PyObject *obj1, *obj4 = 0; + BPy_Interface0DIterator *obj2, *obj3; + +#if 1 + if(!( PyArg_ParseTuple(args, "O!O!O!|O!", &UnaryFunction0D_Type, &obj1, + &Interface0DIterator_Type, &obj2, &Interface0DIterator_Type, &obj3, + &IntegrationType_Type, &obj4) )) + return NULL; +#else + if(!( PyArg_ParseTuple(args, "OOO|O", &obj1, &obj2, &obj3, &obj4) )) + return NULL; + if(!BPy_UnaryFunction0D_Check(obj1)) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a UnaryFunction0D object"); + return NULL; + } + if(!BPy_Interface0DIterator_Check(obj2)) { + PyErr_SetString(PyExc_TypeError, "argument 2 must be a Interface0DIterator object"); + return NULL; + } + if(!BPy_Interface0DIterator_Check(obj3)) { + PyErr_SetString(PyExc_TypeError, "argument 3 must be a Interface0DIterator object"); + return NULL; + } + if(obj4 && !BPy_IntegrationType_Check(obj4)) { + PyErr_SetString(PyExc_TypeError, "argument 4 must be a IntegrationType object"); + return NULL; + } +#endif + + Interface0DIterator it(*(obj2->if0D_it)), it_end(*(obj3->if0D_it)); + IntegrationType t = ( obj4 ) ? IntegrationType_from_BPy_IntegrationType( obj4 ) : MEAN; + + if( BPy_UnaryFunction0DDouble_Check(obj1) ) { + UnaryFunction0D<double> *fun = ((BPy_UnaryFunction0DDouble *)obj1)->uf0D_double; + double res = integrate( *fun, it, it_end, t ); + return PyFloat_FromDouble( res ); + + } else if( BPy_UnaryFunction0DFloat_Check(obj1) ) { + UnaryFunction0D<float> *fun = ((BPy_UnaryFunction0DFloat *)obj1)->uf0D_float; + float res = integrate( *fun, it, it_end, t ); + return PyFloat_FromDouble( res ); + + } else if( BPy_UnaryFunction0DUnsigned_Check(obj1) ) { + UnaryFunction0D<unsigned int> *fun = ((BPy_UnaryFunction0DUnsigned *)obj1)->uf0D_unsigned; + unsigned int res = integrate( *fun, it, it_end, t ); + return PyLong_FromLong( res ); + + } else { + string msg("unsupported function type: " + string(obj1->ob_type->tp_name)); + PyErr_SetString(PyExc_TypeError, msg.c_str()); + return NULL; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + diff --git a/source/blender/freestyle/intern/python/BPy_IntegrationType.h b/source/blender/freestyle/intern/python/BPy_IntegrationType.h new file mode 100644 index 00000000000..176d8750c45 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_IntegrationType.h @@ -0,0 +1,28 @@ +#ifndef FREESTYLE_PYTHON_INTEGRATIONTYPE_H +#define FREESTYLE_PYTHON_INTEGRATIONTYPE_H + +#include "../view_map/Interface1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject IntegrationType_Type; + +#define BPy_IntegrationType_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &IntegrationType_Type) ) + +/*---------------------------Python BPy_IntegrationType visible prototypes-----------*/ + +int IntegrationType_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_INTEGRATIONTYPE_H */ diff --git a/source/blender/freestyle/intern/python/BPy_Interface0D.cpp b/source/blender/freestyle/intern/python/BPy_Interface0D.cpp new file mode 100644 index 00000000000..6e170e8e0b7 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Interface0D.cpp @@ -0,0 +1,270 @@ +#include "BPy_Interface0D.h" + +#include "BPy_Convert.h" +#include "Interface0D/BPy_CurvePoint.h" +#include "Interface0D/CurvePoint/BPy_StrokeVertex.h" +#include "Interface0D/BPy_SVertex.h" +#include "Interface0D/BPy_ViewVertex.h" +#include "Interface0D/ViewVertex/BPy_NonTVertex.h" +#include "Interface0D/ViewVertex/BPy_TVertex.h" +#include "Interface1D/BPy_FEdge.h" +#include "BPy_Nature.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Interface0D instance -----------*/ +static int Interface0D___init__(BPy_Interface0D *self, PyObject *args, PyObject *kwds); +static void Interface0D___dealloc__(BPy_Interface0D *self); +static PyObject * Interface0D___repr__(BPy_Interface0D *self); + +static PyObject *Interface0D_getExactTypeName( BPy_Interface0D *self ); +static PyObject *Interface0D_getX( BPy_Interface0D *self ); +static PyObject *Interface0D_getY( BPy_Interface0D *self ); +static PyObject *Interface0D_getZ( BPy_Interface0D *self ); +static PyObject *Interface0D_getPoint3D( BPy_Interface0D *self ); +static PyObject *Interface0D_getProjectedX( BPy_Interface0D *self ); +static PyObject *Interface0D_getProjectedY( BPy_Interface0D *self ); +static PyObject *Interface0D_getProjectedZ( BPy_Interface0D *self ); +static PyObject *Interface0D_getPoint2D( BPy_Interface0D *self ); +static PyObject *Interface0D_getFEdge( BPy_Interface0D *self, PyObject *args ); +static PyObject *Interface0D_getId( BPy_Interface0D *self ); +static PyObject *Interface0D_getNature( BPy_Interface0D *self ); + +/*----------------------Interface0D instance definitions ----------------------------*/ +static PyMethodDef BPy_Interface0D_methods[] = { + {"getExactTypeName", ( PyCFunction ) Interface0D_getExactTypeName, METH_NOARGS, "() Returns the string of the name of the interface."}, + {"getX", ( PyCFunction ) Interface0D_getX, METH_NOARGS, "() Returns the 3D x coordinate of the point. "}, + {"getY", ( PyCFunction ) Interface0D_getY, METH_NOARGS, "() Returns the 3D y coordinate of the point. "}, + {"getZ", ( PyCFunction ) Interface0D_getZ, METH_NOARGS, "() Returns the 3D z coordinate of the point. "}, + {"getPoint3D", ( PyCFunction ) Interface0D_getPoint3D, METH_NOARGS, "() Returns the 3D point."}, + {"getProjectedX", ( PyCFunction ) Interface0D_getProjectedX, METH_NOARGS, "() Returns the 2D x coordinate of the point."}, + {"getProjectedY", ( PyCFunction ) Interface0D_getProjectedY, METH_NOARGS, "() Returns the 2D y coordinate of the point."}, + {"getProjectedZ", ( PyCFunction ) Interface0D_getProjectedZ, METH_NOARGS, "() Returns the 2D z coordinate of the point."}, + {"getPoint2D", ( PyCFunction ) Interface0D_getPoint2D, METH_NOARGS, "() Returns the 2D point."}, + {"getFEdge", ( PyCFunction ) Interface0D_getFEdge, METH_VARARGS, "(Interface0D i) Returns the FEdge that lies between this Interface0D and the Interface0D given as argument."}, + {"getId", ( PyCFunction ) Interface0D_getId, METH_NOARGS, "() Returns the Id of the point."}, + {"getNature", ( PyCFunction ) Interface0D_getNature, METH_NOARGS, "() Returns the nature of the point."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_Interface0D type definition ------------------------------*/ + +PyTypeObject Interface0D_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "Interface0D", /* tp_name */ + sizeof(BPy_Interface0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)Interface0D___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)Interface0D___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Interface0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_Interface0D_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Interface0D___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int Interface0D_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &Interface0D_Type ) < 0 ) + return -1; + Py_INCREF( &Interface0D_Type ); + PyModule_AddObject(module, "Interface0D", (PyObject *)&Interface0D_Type); + + if( PyType_Ready( &CurvePoint_Type ) < 0 ) + return -1; + Py_INCREF( &CurvePoint_Type ); + PyModule_AddObject(module, "CurvePoint", (PyObject *)&CurvePoint_Type); + + if( PyType_Ready( &SVertex_Type ) < 0 ) + return -1; + Py_INCREF( &SVertex_Type ); + PyModule_AddObject(module, "SVertex", (PyObject *)&SVertex_Type); + + if( PyType_Ready( &ViewVertex_Type ) < 0 ) + return -1; + Py_INCREF( &ViewVertex_Type ); + PyModule_AddObject(module, "ViewVertex", (PyObject *)&ViewVertex_Type); + + if( PyType_Ready( &StrokeVertex_Type ) < 0 ) + return -1; + Py_INCREF( &StrokeVertex_Type ); + PyModule_AddObject(module, "StrokeVertex", (PyObject *)&StrokeVertex_Type); + + if( PyType_Ready( &NonTVertex_Type ) < 0 ) + return -1; + Py_INCREF( &NonTVertex_Type ); + PyModule_AddObject(module, "NonTVertex", (PyObject *)&NonTVertex_Type); + + if( PyType_Ready( &TVertex_Type ) < 0 ) + return -1; + Py_INCREF( &TVertex_Type ); + PyModule_AddObject(module, "TVertex", (PyObject *)&TVertex_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int Interface0D___init__(BPy_Interface0D *self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->if0D = new Interface0D(); + self->borrowed = 0; + return 0; +} + +void Interface0D___dealloc__(BPy_Interface0D* self) +{ + if( self->if0D && !self->borrowed ) + delete self->if0D; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyObject * Interface0D___repr__(BPy_Interface0D* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->if0D->getExactTypeName().c_str(), self->if0D ); +} + +PyObject *Interface0D_getExactTypeName( BPy_Interface0D *self ) { + return PyUnicode_FromFormat( self->if0D->getExactTypeName().c_str() ); +} + + +PyObject *Interface0D_getX( BPy_Interface0D *self ) { + double x = self->if0D->getX(); + if (PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble( x ); +} + + +PyObject *Interface0D_getY( BPy_Interface0D *self ) { + double y = self->if0D->getY(); + if (PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble( y ); +} + + +PyObject *Interface0D_getZ( BPy_Interface0D *self ) { + double z = self->if0D->getZ(); + if (PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble( z ); +} + + +PyObject *Interface0D_getPoint3D( BPy_Interface0D *self ) { + Vec3f v( self->if0D->getPoint3D() ); + if (PyErr_Occurred()) + return NULL; + return Vector_from_Vec3f( v ); +} + + +PyObject *Interface0D_getProjectedX( BPy_Interface0D *self ) { + double x = self->if0D->getProjectedX(); + if (PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble( x ); +} + + +PyObject *Interface0D_getProjectedY( BPy_Interface0D *self ) { + double y = self->if0D->getProjectedY(); + if (PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble( y ); +} + + +PyObject *Interface0D_getProjectedZ( BPy_Interface0D *self ) { + double z = self->if0D->getProjectedZ(); + if (PyErr_Occurred()) + return NULL; + return PyFloat_FromDouble( z ); +} + + +PyObject *Interface0D_getPoint2D( BPy_Interface0D *self ) { + Vec2f v( self->if0D->getPoint2D() ); + if (PyErr_Occurred()) + return NULL; + return Vector_from_Vec2f( v ); +} + + +PyObject *Interface0D_getFEdge( BPy_Interface0D *self, PyObject *args ) { + PyObject *py_if0D; + + if(!( PyArg_ParseTuple(args, "O!", &Interface0D_Type, &py_if0D) )) + return NULL; + + FEdge *fe = self->if0D->getFEdge(*( ((BPy_Interface0D *) py_if0D)->if0D )); + if (PyErr_Occurred()) + return NULL; + if( fe ) + return Any_BPy_FEdge_from_FEdge( *fe ); + + Py_RETURN_NONE; +} + + +PyObject *Interface0D_getId( BPy_Interface0D *self ) { + Id id( self->if0D->getId() ); + if (PyErr_Occurred()) + return NULL; + return BPy_Id_from_Id( id ); +} + + +PyObject *Interface0D_getNature( BPy_Interface0D *self ) { + Nature::VertexNature nature = self->if0D->getNature(); + if (PyErr_Occurred()) + return NULL; + return BPy_Nature_from_Nature( nature ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + diff --git a/source/blender/freestyle/intern/python/BPy_Interface0D.h b/source/blender/freestyle/intern/python/BPy_Interface0D.h new file mode 100644 index 00000000000..cd8a8e19749 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Interface0D.h @@ -0,0 +1,35 @@ +#ifndef FREESTYLE_PYTHON_INTERFACE0D_H +#define FREESTYLE_PYTHON_INTERFACE0D_H + +#include "../view_map/Interface0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Interface0D_Type; + +#define BPy_Interface0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Interface0D_Type) ) + +/*---------------------------Python BPy_Interface0D structure definition----------*/ +typedef struct { + PyObject_HEAD + Interface0D *if0D; + int borrowed; /* non-zero if *if0D is a borrowed object */ +} BPy_Interface0D; + +/*---------------------------Python BPy_Interface0D visible prototypes-----------*/ + +int Interface0D_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_INTERFACE0D_H */ diff --git a/source/blender/freestyle/intern/python/BPy_Interface1D.cpp b/source/blender/freestyle/intern/python/BPy_Interface1D.cpp new file mode 100644 index 00000000000..9f4bb75411d --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Interface1D.cpp @@ -0,0 +1,252 @@ +#include "BPy_Interface1D.h" + +#include "BPy_Convert.h" +#include "Interface1D/BPy_FrsCurve.h" +#include "Interface1D/Curve/BPy_Chain.h" +#include "Interface1D/BPy_FEdge.h" +#include "Interface1D/FEdge/BPy_FEdgeSharp.h" +#include "Interface1D/FEdge/BPy_FEdgeSmooth.h" +#include "Interface1D/BPy_Stroke.h" +#include "Interface1D/BPy_ViewEdge.h" + +#include "BPy_MediumType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Interface1D instance -----------*/ +static int Interface1D___init__(BPy_Interface1D *self, PyObject *args, PyObject *kwds); +static void Interface1D___dealloc__(BPy_Interface1D *self); +static PyObject * Interface1D___repr__(BPy_Interface1D *self); + +static PyObject *Interface1D_getExactTypeName( BPy_Interface1D *self ); +static PyObject *Interface1D_getVertices( BPy_Interface1D *self ); +static PyObject *Interface1D_getPoints( BPy_Interface1D *self ); +static PyObject *Interface1D_getLength2D( BPy_Interface1D *self ); +static PyObject *Interface1D_getId( BPy_Interface1D *self ); +static PyObject *Interface1D_getNature( BPy_Interface1D *self ); +static PyObject *Interface1D_getTimeStamp( BPy_Interface1D *self ); +static PyObject *Interface1D_setTimeStamp( BPy_Interface1D *self, PyObject *args); +static PyObject * Interface1D_verticesBegin( BPy_Interface1D *self ); +static PyObject * Interface1D_verticesEnd( BPy_Interface1D *self ); +static PyObject * Interface1D_pointsBegin( BPy_Interface1D *self, PyObject *args ); +static PyObject * Interface1D_pointsEnd( BPy_Interface1D *self, PyObject *args ); + +/*----------------------Interface1D instance definitions ----------------------------*/ +static PyMethodDef BPy_Interface1D_methods[] = { + {"getExactTypeName", ( PyCFunction ) Interface1D_getExactTypeName, METH_NOARGS, "() Returns the string of the name of the interface."}, + {"getVertices", ( PyCFunction ) Interface1D_getVertices, METH_NOARGS, "Returns the vertices"}, + {"getPoints", ( PyCFunction ) Interface1D_getPoints, METH_NOARGS, "Returns the points. The difference with getVertices() is that here we can iterate over points of the 1D element at any given sampling. At each call, a virtual point is created."}, + {"getLength2D", ( PyCFunction ) Interface1D_getLength2D, METH_NOARGS, "Returns the 2D length of the 1D element"}, + {"getId", ( PyCFunction ) Interface1D_getId, METH_NOARGS, "Returns the Id of the 1D element"}, + {"getNature", ( PyCFunction ) Interface1D_getNature, METH_NOARGS, "Returns the nature of the 1D element"}, + {"getTimeStamp", ( PyCFunction ) Interface1D_getTimeStamp, METH_NOARGS, "Returns the time stamp of the 1D element. Mainly used for selection"}, + {"setTimeStamp", ( PyCFunction ) Interface1D_setTimeStamp, METH_VARARGS, "Sets the time stamp for the 1D element"}, + {"verticesBegin", ( PyCFunction ) Interface1D_verticesBegin, METH_NOARGS, ""}, + {"verticesEnd", ( PyCFunction ) Interface1D_verticesEnd, METH_NOARGS, ""}, + {"pointsBegin", ( PyCFunction ) Interface1D_pointsBegin, METH_VARARGS, ""}, + {"pointsEnd", ( PyCFunction ) Interface1D_pointsEnd, METH_VARARGS, ""}, + + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_Interface1D type definition ------------------------------*/ + +PyTypeObject Interface1D_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "Interface1D", /* tp_name */ + sizeof(BPy_Interface1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)Interface1D___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)Interface1D___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Interface1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_Interface1D_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Interface1D___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int Interface1D_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &Interface1D_Type ) < 0 ) + return -1; + Py_INCREF( &Interface1D_Type ); + PyModule_AddObject(module, "Interface1D", (PyObject *)&Interface1D_Type); + + if( PyType_Ready( &FrsCurve_Type ) < 0 ) + return -1; + Py_INCREF( &FrsCurve_Type ); + PyModule_AddObject(module, "FrsCurve", (PyObject *)&FrsCurve_Type); + + if( PyType_Ready( &Chain_Type ) < 0 ) + return -1; + Py_INCREF( &Chain_Type ); + PyModule_AddObject(module, "Chain", (PyObject *)&Chain_Type); + + if( PyType_Ready( &FEdge_Type ) < 0 ) + return -1; + Py_INCREF( &FEdge_Type ); + PyModule_AddObject(module, "FEdge", (PyObject *)&FEdge_Type); + + if( PyType_Ready( &FEdgeSharp_Type ) < 0 ) + return -1; + Py_INCREF( &FEdgeSharp_Type ); + PyModule_AddObject(module, "FEdgeSharp", (PyObject *)&FEdgeSharp_Type); + + if( PyType_Ready( &FEdgeSmooth_Type ) < 0 ) + return -1; + Py_INCREF( &FEdgeSmooth_Type ); + PyModule_AddObject(module, "FEdgeSmooth", (PyObject *)&FEdgeSmooth_Type); + + if( PyType_Ready( &Stroke_Type ) < 0 ) + return -1; + Py_INCREF( &Stroke_Type ); + PyModule_AddObject(module, "Stroke", (PyObject *)&Stroke_Type); + + PyDict_SetItemString( Stroke_Type.tp_dict, "DRY_MEDIUM", BPy_MediumType_DRY_MEDIUM ); + PyDict_SetItemString( Stroke_Type.tp_dict, "HUMID_MEDIUM", BPy_MediumType_HUMID_MEDIUM ); + PyDict_SetItemString( Stroke_Type.tp_dict, "OPAQUE_MEDIUM", BPy_MediumType_OPAQUE_MEDIUM ); + + if( PyType_Ready( &ViewEdge_Type ) < 0 ) + return -1; + Py_INCREF( &ViewEdge_Type ); + PyModule_AddObject(module, "ViewEdge", (PyObject *)&ViewEdge_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int Interface1D___init__(BPy_Interface1D *self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->if1D = new Interface1D(); + self->borrowed = 0; + return 0; +} + +void Interface1D___dealloc__(BPy_Interface1D* self) +{ + if( self->if1D && !self->borrowed ) + delete self->if1D; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyObject * Interface1D___repr__(BPy_Interface1D* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->if1D->getExactTypeName().c_str(), self->if1D ); +} + +PyObject *Interface1D_getExactTypeName( BPy_Interface1D *self ) { + return PyUnicode_FromFormat( self->if1D->getExactTypeName().c_str() ); +} + +PyObject *Interface1D_getVertices( BPy_Interface1D *self ) { + return PyList_New(0); +} + +PyObject *Interface1D_getPoints( BPy_Interface1D *self ) { + return PyList_New(0); +} + +PyObject *Interface1D_getLength2D( BPy_Interface1D *self ) { + return PyFloat_FromDouble( (double) self->if1D->getLength2D() ); +} + +PyObject *Interface1D_getId( BPy_Interface1D *self ) { + Id id( self->if1D->getId() ); + return BPy_Id_from_Id( id ); +} + +PyObject *Interface1D_getNature( BPy_Interface1D *self ) { + return BPy_Nature_from_Nature( self->if1D->getNature() ); +} + +PyObject *Interface1D_getTimeStamp( BPy_Interface1D *self ) { + return PyLong_FromLong( self->if1D->getTimeStamp() ); +} + +PyObject *Interface1D_setTimeStamp( BPy_Interface1D *self, PyObject *args) { + int timestamp = 0 ; + + if( !PyArg_ParseTuple(args, "i", ×tamp) ) + return NULL; + + self->if1D->setTimeStamp( timestamp ); + + Py_RETURN_NONE; +} + +PyObject * Interface1D_verticesBegin( BPy_Interface1D *self ) { + Interface0DIterator if0D_it( self->if1D->verticesBegin() ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 0 ); +} + +PyObject * Interface1D_verticesEnd( BPy_Interface1D *self ) { + Interface0DIterator if0D_it( self->if1D->verticesEnd() ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 1 ); +} + + +PyObject * Interface1D_pointsBegin( BPy_Interface1D *self, PyObject *args ) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + Interface0DIterator if0D_it( self->if1D->pointsBegin(f) ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 0 ); +} + +PyObject * Interface1D_pointsEnd( BPy_Interface1D *self, PyObject *args ) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + Interface0DIterator if0D_it( self->if1D->pointsEnd(f) ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 1 ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + diff --git a/source/blender/freestyle/intern/python/BPy_Interface1D.h b/source/blender/freestyle/intern/python/BPy_Interface1D.h new file mode 100644 index 00000000000..f82b80e20eb --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Interface1D.h @@ -0,0 +1,36 @@ +#ifndef FREESTYLE_PYTHON_INTERFACE1D_H +#define FREESTYLE_PYTHON_INTERFACE1D_H + +#include "../view_map/Interface1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Interface1D_Type; + +#define BPy_Interface1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Interface1D_Type) ) + +/*---------------------------Python BPy_Interface1D structure definition----------*/ +typedef struct { + PyObject_HEAD + Interface1D *if1D; + int borrowed; /* non-zero if *if1D is a borrowed object */ +} BPy_Interface1D; + +/*---------------------------Python BPy_Interface1D visible prototypes-----------*/ + +int Interface1D_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_INTERFACE1D_H */ diff --git a/source/blender/freestyle/intern/python/BPy_Iterator.cpp b/source/blender/freestyle/intern/python/BPy_Iterator.cpp new file mode 100644 index 00000000000..0e06c869a87 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Iterator.cpp @@ -0,0 +1,204 @@ +#include "BPy_Iterator.h" + +#include "BPy_Convert.h" +#include "Iterator/BPy_AdjacencyIterator.h" +#include "Iterator/BPy_Interface0DIterator.h" +#include "Iterator/BPy_CurvePointIterator.h" +#include "Iterator/BPy_StrokeVertexIterator.h" +#include "Iterator/BPy_SVertexIterator.h" +#include "Iterator/BPy_orientedViewEdgeIterator.h" +#include "Iterator/BPy_ViewEdgeIterator.h" +#include "Iterator/BPy_ChainingIterator.h" +#include "Iterator/BPy_ChainPredicateIterator.h" +#include "Iterator/BPy_ChainSilhouetteIterator.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Iterator instance -----------*/ +static void Iterator___dealloc__(BPy_Iterator *self); +static PyObject * Iterator___repr__(BPy_Iterator* self); + +static PyObject * Iterator_getExactTypeName(BPy_Iterator* self); +static PyObject * Iterator_increment(BPy_Iterator* self); +static PyObject * Iterator_decrement(BPy_Iterator* self); +static PyObject * Iterator_isBegin(BPy_Iterator* self); +static PyObject * Iterator_isEnd(BPy_Iterator* self); + +/*----------------------Iterator instance definitions ----------------------------*/ +static PyMethodDef BPy_Iterator_methods[] = { + {"getExactTypeName", ( PyCFunction ) Iterator_getExactTypeName, METH_NOARGS, "() Returns the string of the name of the iterator."}, + {"increment", ( PyCFunction ) Iterator_increment, METH_NOARGS, "() Increments iterator."}, + {"decrement", ( PyCFunction ) Iterator_decrement, METH_NOARGS, "() Decrements iterator."}, + {"isBegin", ( PyCFunction ) Iterator_isBegin, METH_NOARGS, "() Tests if iterator points to beginning."}, + {"isEnd", ( PyCFunction ) Iterator_isEnd, METH_NOARGS, "() Tests if iterator points to end."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_Iterator type definition ------------------------------*/ + +PyTypeObject Iterator_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "Iterator", /* tp_name */ + sizeof(BPy_Iterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)Iterator___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)Iterator___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Iterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_Iterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int Iterator_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &Iterator_Type ) < 0 ) + return -1; + Py_INCREF( &Iterator_Type ); + PyModule_AddObject(module, "Iterator", (PyObject *)&Iterator_Type); + + if( PyType_Ready( &AdjacencyIterator_Type ) < 0 ) + return -1; + Py_INCREF( &AdjacencyIterator_Type ); + PyModule_AddObject(module, "AdjacencyIterator", (PyObject *)&AdjacencyIterator_Type); + + if( PyType_Ready( &Interface0DIterator_Type ) < 0 ) + return -1; + Py_INCREF( &Interface0DIterator_Type ); + PyModule_AddObject(module, "Interface0DIterator", (PyObject *)&Interface0DIterator_Type); + + if( PyType_Ready( &CurvePointIterator_Type ) < 0 ) + return -1; + Py_INCREF( &CurvePointIterator_Type ); + PyModule_AddObject(module, "CurvePointIterator", (PyObject *)&CurvePointIterator_Type); + + if( PyType_Ready( &StrokeVertexIterator_Type ) < 0 ) + return -1; + Py_INCREF( &StrokeVertexIterator_Type ); + PyModule_AddObject(module, "StrokeVertexIterator", (PyObject *)&StrokeVertexIterator_Type); + + if( PyType_Ready( &SVertexIterator_Type ) < 0 ) + return -1; + Py_INCREF( &SVertexIterator_Type ); + PyModule_AddObject(module, "SVertexIterator", (PyObject *)&SVertexIterator_Type); + + if( PyType_Ready( &orientedViewEdgeIterator_Type ) < 0 ) + return -1; + Py_INCREF( &orientedViewEdgeIterator_Type ); + PyModule_AddObject(module, "orientedViewEdgeIterator", (PyObject *)&orientedViewEdgeIterator_Type); + + if( PyType_Ready( &ViewEdgeIterator_Type ) < 0 ) + return -1; + Py_INCREF( &ViewEdgeIterator_Type ); + PyModule_AddObject(module, "ViewEdgeIterator", (PyObject *)&ViewEdgeIterator_Type); + + if( PyType_Ready( &ChainingIterator_Type ) < 0 ) + return -1; + Py_INCREF( &ChainingIterator_Type ); + PyModule_AddObject(module, "ChainingIterator", (PyObject *)&ChainingIterator_Type); + + if( PyType_Ready( &ChainPredicateIterator_Type ) < 0 ) + return -1; + Py_INCREF( &ChainPredicateIterator_Type ); + PyModule_AddObject(module, "ChainPredicateIterator", (PyObject *)&ChainPredicateIterator_Type); + + if( PyType_Ready( &ChainSilhouetteIterator_Type ) < 0 ) + return -1; + Py_INCREF( &ChainSilhouetteIterator_Type ); + PyModule_AddObject(module, "ChainSilhouetteIterator", (PyObject *)&ChainSilhouetteIterator_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +void Iterator___dealloc__(BPy_Iterator* self) +{ + if (self->it) + delete self->it; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyObject * Iterator___repr__(BPy_Iterator* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->it->getExactTypeName().c_str(), self->it ); +} + +PyObject * Iterator_getExactTypeName(BPy_Iterator* self) { + return PyUnicode_FromFormat( self->it->getExactTypeName().c_str() ); +} + + +PyObject * Iterator_increment(BPy_Iterator* self) { + if (self->it->isEnd()) { + PyErr_SetString(PyExc_RuntimeError , "cannot increment any more"); + return NULL; + } + self->it->increment(); + + Py_RETURN_NONE; +} + +PyObject * Iterator_decrement(BPy_Iterator* self) { + if (self->it->isBegin()) { + PyErr_SetString(PyExc_RuntimeError , "cannot decrement any more"); + return NULL; + } + self->it->decrement(); + + Py_RETURN_NONE; +} + +PyObject * Iterator_isBegin(BPy_Iterator* self) { + return PyBool_from_bool( self->it->isBegin() ); +} + +PyObject * Iterator_isEnd(BPy_Iterator* self) { + return PyBool_from_bool( self->it->isEnd() ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + diff --git a/source/blender/freestyle/intern/python/BPy_Iterator.h b/source/blender/freestyle/intern/python/BPy_Iterator.h new file mode 100644 index 00000000000..162df60d91e --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Iterator.h @@ -0,0 +1,35 @@ +#ifndef FREESTYLE_PYTHON_ITERATOR_H +#define FREESTYLE_PYTHON_ITERATOR_H + +#include "../system/Iterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Iterator_Type; + +#define BPy_Iterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Iterator_Type) ) + +/*---------------------------Python BPy_Iterator structure definition----------*/ +typedef struct { + PyObject_HEAD + Iterator *it; +} BPy_Iterator; + +/*---------------------------Python BPy_Iterator visible prototypes-----------*/ + +int Iterator_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_ITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/BPy_MediumType.cpp b/source/blender/freestyle/intern/python/BPy_MediumType.cpp new file mode 100644 index 00000000000..1d4838b14ad --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_MediumType.cpp @@ -0,0 +1,89 @@ +#include "BPy_MediumType.h" + +#include "BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*-----------------------BPy_MediumType type definition ------------------------------*/ + +PyTypeObject MediumType_Type = { + PyObject_HEAD_INIT(NULL) + "MediumType", /* tp_name */ + sizeof(PyLongObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "MediumType objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyLong_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +/*-----------------------BPy_IntegrationType instance definitions -------------------------*/ + +PyLongObject _BPy_MediumType_DRY_MEDIUM = { + PyVarObject_HEAD_INIT(&MediumType_Type, 1) + { Stroke::DRY_MEDIUM } +}; +PyLongObject _BPy_MediumType_HUMID_MEDIUM = { + PyVarObject_HEAD_INIT(&MediumType_Type, 1) + { Stroke::HUMID_MEDIUM } +}; +PyLongObject _BPy_MediumType_OPAQUE_MEDIUM = { + PyVarObject_HEAD_INIT(&MediumType_Type, 1) + { Stroke::OPAQUE_MEDIUM } +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int MediumType_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &MediumType_Type ) < 0 ) + return -1; + Py_INCREF( &MediumType_Type ); + PyModule_AddObject(module, "MediumType", (PyObject *)&MediumType_Type); + + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + diff --git a/source/blender/freestyle/intern/python/BPy_MediumType.h b/source/blender/freestyle/intern/python/BPy_MediumType.h new file mode 100644 index 00000000000..94bc7aa954c --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_MediumType.h @@ -0,0 +1,42 @@ +#ifndef FREESTYLE_PYTHON_MEDIUMTYPE_H +#define FREESTYLE_PYTHON_MEDIUMTYPE_H + +#include "../stroke/Stroke.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject MediumType_Type; + +#define BPy_MediumType_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &MediumType_Type) ) + +/*---------------------------Python BPy_MediumType structure definition----------*/ +typedef struct { + PyLongObject i; +} BPy_MediumType; + +/*---------------------------Python BPy_MediumType visible prototypes-----------*/ + +int MediumType_Init( PyObject *module ); + +// internal constants +extern PyLongObject _BPy_MediumType_DRY_MEDIUM; +extern PyLongObject _BPy_MediumType_HUMID_MEDIUM; +extern PyLongObject _BPy_MediumType_OPAQUE_MEDIUM; +// public constants +#define BPy_MediumType_DRY_MEDIUM ((PyObject *)&_BPy_MediumType_DRY_MEDIUM) +#define BPy_MediumType_HUMID_MEDIUM ((PyObject *)&_BPy_MediumType_HUMID_MEDIUM) +#define BPy_MediumType_OPAQUE_MEDIUM ((PyObject *)&_BPy_MediumType_OPAQUE_MEDIUM) + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_MEDIUMTYPE_H */ diff --git a/source/blender/freestyle/intern/python/BPy_Nature.cpp b/source/blender/freestyle/intern/python/BPy_Nature.cpp new file mode 100644 index 00000000000..3f6ca273ee8 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Nature.cpp @@ -0,0 +1,271 @@ +#include "BPy_Nature.h" + +#include "BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +static PyObject *BPy_Nature___and__(PyObject *a, PyObject *b); +static PyObject *BPy_Nature___xor__(PyObject *a, PyObject *b); +static PyObject *BPy_Nature___or__(PyObject *a, PyObject *b); +static int BPy_Nature_bool(PyObject *v); + +/*-----------------------BPy_Nature number method definitions --------------------*/ + +PyNumberMethods nature_as_number = { + 0, /* binaryfunc nb_add */ + 0, /* binaryfunc nb_subtract */ + 0, /* binaryfunc nb_multiply */ + 0, /* binaryfunc nb_remainder */ + 0, /* binaryfunc nb_divmod */ + 0, /* ternaryfunc nb_power */ + 0, /* unaryfunc nb_negative */ + 0, /* unaryfunc nb_positive */ + 0, /* unaryfunc nb_absolute */ + (inquiry)BPy_Nature_bool, /* inquiry nb_bool */ + 0, /* unaryfunc nb_invert */ + 0, /* binaryfunc nb_lshift */ + 0, /* binaryfunc nb_rshift */ + (binaryfunc)BPy_Nature___and__, /* binaryfunc nb_and */ + (binaryfunc)BPy_Nature___xor__, /* binaryfunc nb_xor */ + (binaryfunc)BPy_Nature___or__, /* binaryfunc nb_or */ + 0, /* unaryfunc nb_int */ + 0, /* void *nb_reserved */ + 0, /* unaryfunc nb_float */ + 0, /* binaryfunc nb_inplace_add */ + 0, /* binaryfunc nb_inplace_subtract */ + 0, /* binaryfunc nb_inplace_multiply */ + 0, /* binaryfunc nb_inplace_remainder */ + 0, /* ternaryfunc nb_inplace_power */ + 0, /* binaryfunc nb_inplace_lshift */ + 0, /* binaryfunc nb_inplace_rshift */ + 0, /* binaryfunc nb_inplace_and */ + 0, /* binaryfunc nb_inplace_xor */ + 0, /* binaryfunc nb_inplace_or */ + 0, /* binaryfunc nb_floor_divide */ + 0, /* binaryfunc nb_true_divide */ + 0, /* binaryfunc nb_inplace_floor_divide */ + 0, /* binaryfunc nb_inplace_true_divide */ + 0, /* unaryfunc nb_index */ +}; + +/*-----------------------BPy_Nature type definition ------------------------------*/ + +PyTypeObject Nature_Type = { + PyObject_HEAD_INIT(NULL) + "Nature", /* tp_name */ + sizeof(PyLongObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + &nature_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "Nature objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyLong_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +/*-----------------------BPy_Nature instance definitions ----------------------------------*/ + +static PyLongObject _Nature_POINT = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::POINT } +}; +static PyLongObject _Nature_S_VERTEX = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::S_VERTEX } +}; +static PyLongObject _Nature_VIEW_VERTEX = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::VIEW_VERTEX } +}; +static PyLongObject _Nature_NON_T_VERTEX = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::NON_T_VERTEX } +}; +static PyLongObject _Nature_T_VERTEX = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::T_VERTEX } +}; +static PyLongObject _Nature_CUSP = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::CUSP } +}; +static PyLongObject _Nature_NO_FEATURE = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::NO_FEATURE } +}; +static PyLongObject _Nature_SILHOUETTE = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::SILHOUETTE } +}; +static PyLongObject _Nature_BORDER = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::BORDER } +}; +static PyLongObject _Nature_CREASE = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::CREASE } +}; +static PyLongObject _Nature_RIDGE = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::RIDGE } +}; +static PyLongObject _Nature_VALLEY = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::VALLEY } +}; +static PyLongObject _Nature_SUGGESTIVE_CONTOUR = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::SUGGESTIVE_CONTOUR } +}; + +#define BPy_Nature_POINT ((PyObject *)&_Nature_POINT) +#define BPy_Nature_S_VERTEX ((PyObject *)&_Nature_S_VERTEX) +#define BPy_Nature_VIEW_VERTEX ((PyObject *)&_Nature_VIEW_VERTEX) +#define BPy_Nature_NON_T_VERTEX ((PyObject *)&_Nature_NON_T_VERTEX) +#define BPy_Nature_T_VERTEX ((PyObject *)&_Nature_T_VERTEX) +#define BPy_Nature_CUSP ((PyObject *)&_Nature_CUSP) +#define BPy_Nature_NO_FEATURE ((PyObject *)&_Nature_NO_FEATURE) +#define BPy_Nature_SILHOUETTE ((PyObject *)&_Nature_SILHOUETTE) +#define BPy_Nature_BORDER ((PyObject *)&_Nature_BORDER) +#define BPy_Nature_CREASE ((PyObject *)&_Nature_CREASE) +#define BPy_Nature_RIDGE ((PyObject *)&_Nature_RIDGE) +#define BPy_Nature_VALLEY ((PyObject *)&_Nature_VALLEY) +#define BPy_Nature_SUGGESTIVE_CONTOUR ((PyObject *)&_Nature_SUGGESTIVE_CONTOUR) + +//-------------------MODULE INITIALIZATION-------------------------------- +int Nature_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &Nature_Type ) < 0 ) + return -1; + Py_INCREF( &Nature_Type ); + PyModule_AddObject(module, "Nature", (PyObject *)&Nature_Type); + + // VertexNature + PyDict_SetItemString( Nature_Type.tp_dict, "POINT", BPy_Nature_POINT); + PyDict_SetItemString( Nature_Type.tp_dict, "S_VERTEX", BPy_Nature_S_VERTEX); + PyDict_SetItemString( Nature_Type.tp_dict, "VIEW_VERTEX", BPy_Nature_VIEW_VERTEX ); + PyDict_SetItemString( Nature_Type.tp_dict, "NON_T_VERTEX", BPy_Nature_NON_T_VERTEX ); + PyDict_SetItemString( Nature_Type.tp_dict, "T_VERTEX", BPy_Nature_T_VERTEX ); + PyDict_SetItemString( Nature_Type.tp_dict, "CUSP", BPy_Nature_CUSP ); + + // EdgeNature + PyDict_SetItemString( Nature_Type.tp_dict, "NO_FEATURE", BPy_Nature_NO_FEATURE ); + PyDict_SetItemString( Nature_Type.tp_dict, "SILHOUETTE", BPy_Nature_SILHOUETTE ); + PyDict_SetItemString( Nature_Type.tp_dict, "BORDER", BPy_Nature_BORDER ); + PyDict_SetItemString( Nature_Type.tp_dict, "CREASE", BPy_Nature_CREASE ); + PyDict_SetItemString( Nature_Type.tp_dict, "RIDGE", BPy_Nature_RIDGE ); + PyDict_SetItemString( Nature_Type.tp_dict, "VALLEY", BPy_Nature_VALLEY ); + PyDict_SetItemString( Nature_Type.tp_dict, "SUGGESTIVE_CONTOUR", BPy_Nature_SUGGESTIVE_CONTOUR ); + + return 0; +} + +static PyObject * +BPy_Nature_bitwise(PyObject *a, int op, PyObject *b) +{ + BPy_Nature *result; + + if (!BPy_Nature_Check(a) || !BPy_Nature_Check(b)) { + PyErr_SetString(PyExc_TypeError, "operands must be a Nature object"); + return NULL; + } + if (Py_SIZE(a) != 1) { + stringstream msg; + msg << "operand 1: unexpected Nature byte length: " << Py_SIZE(a); + PyErr_SetString(PyExc_TypeError, msg.str().c_str()); + return NULL; + } + if (Py_SIZE(b) != 1) { + stringstream msg; + msg << "operand 2: unexpected Nature byte length: " << Py_SIZE(b); + PyErr_SetString(PyExc_TypeError, msg.str().c_str()); + return NULL; + } + result = PyObject_NewVar(BPy_Nature, &Nature_Type, 1); + if (!result) + return NULL; + if (Py_SIZE(result) != 1) { + stringstream msg; + msg << "unexpected Nature byte length: " << Py_SIZE(result); + PyErr_SetString(PyExc_TypeError, msg.str().c_str()); + return NULL; + } + switch (op) { + case '&': + result->i.ob_digit[0] = (((PyLongObject *)a)->ob_digit[0]) & (((PyLongObject *)b)->ob_digit)[0]; + break; + case '^': + result->i.ob_digit[0] = (((PyLongObject *)a)->ob_digit[0]) ^ (((PyLongObject *)b)->ob_digit)[0]; + break; + case '|': + result->i.ob_digit[0] = (((PyLongObject *)a)->ob_digit[0]) | (((PyLongObject *)b)->ob_digit)[0]; + break; + } + return (PyObject *)result; +} + +static PyObject * +BPy_Nature___and__(PyObject *a, PyObject *b) +{ + return BPy_Nature_bitwise(a, '&', b); +} + +static PyObject * +BPy_Nature___xor__(PyObject *a, PyObject *b) +{ + return BPy_Nature_bitwise(a, '^', b); +} + +static PyObject * +BPy_Nature___or__(PyObject *a, PyObject *b) +{ + return BPy_Nature_bitwise(a, '|', b); +} + +static int +BPy_Nature_bool(PyObject *v) +{ + return ((PyLongObject *)v)->ob_digit[0] != 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + diff --git a/source/blender/freestyle/intern/python/BPy_Nature.h b/source/blender/freestyle/intern/python/BPy_Nature.h new file mode 100644 index 00000000000..d5e1c9c63d4 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Nature.h @@ -0,0 +1,33 @@ +#ifndef FREESTYLE_PYTHON_NATURE_H +#define FREESTYLE_PYTHON_NATURE_H + +#include "../winged_edge/Nature.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Nature_Type; + +#define BPy_Nature_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Nature_Type) ) + +/*---------------------------Python BPy_Nature structure definition----------*/ +typedef struct { + PyLongObject i; +} BPy_Nature; + +/*---------------------------Python BPy_Nature visible prototypes-----------*/ + +int Nature_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_NATURE_H */ diff --git a/source/blender/freestyle/intern/python/BPy_Operators.cpp b/source/blender/freestyle/intern/python/BPy_Operators.cpp new file mode 100644 index 00000000000..557143f22c2 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Operators.cpp @@ -0,0 +1,394 @@ +#include "BPy_Operators.h" + +#include "BPy_BinaryPredicate1D.h" +#include "BPy_UnaryPredicate0D.h" +#include "BPy_UnaryPredicate1D.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DDouble.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DVoid.h" +#include "Iterator/BPy_ViewEdgeIterator.h" +#include "Iterator/BPy_ChainingIterator.h" +#include "BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Operators instance -----------*/ +static void Operators___dealloc__(BPy_Operators *self); + +static PyObject * Operators_select(BPy_Operators* self, PyObject *args); +static PyObject * Operators_chain(BPy_Operators* self, PyObject *args); +static PyObject * Operators_bidirectionalChain(BPy_Operators* self, PyObject *args); +static PyObject * Operators_sequentialSplit(BPy_Operators* self, PyObject *args); +static PyObject * Operators_recursiveSplit(BPy_Operators* self, PyObject *args); +static PyObject * Operators_sort(BPy_Operators* self, PyObject *args); +static PyObject * Operators_create(BPy_Operators* self, PyObject *args); +static PyObject * Operators_getViewEdgesSize( BPy_Operators* self); +static PyObject * Operators_getChainsSize( BPy_Operators* self); +static PyObject * Operators_getStrokesSize( BPy_Operators* self); + +/*----------------------Operators instance definitions ----------------------------*/ +static PyMethodDef BPy_Operators_methods[] = { + {"select", ( PyCFunction ) Operators_select, METH_VARARGS | METH_STATIC, + "select operator"}, + {"chain", ( PyCFunction ) Operators_chain, METH_VARARGS | METH_STATIC, + "chain operator"}, + {"bidirectionalChain", ( PyCFunction ) Operators_bidirectionalChain, METH_VARARGS | METH_STATIC, + "bidirectionalChain operator"}, + {"sequentialSplit", ( PyCFunction ) Operators_sequentialSplit, METH_VARARGS | METH_STATIC, + "sequentialSplit operator"}, + {"recursiveSplit", ( PyCFunction ) Operators_recursiveSplit, METH_VARARGS | METH_STATIC, + "recursiveSplit operator"}, + {"sort", ( PyCFunction ) Operators_sort, METH_VARARGS | METH_STATIC, + "sort operator"}, + {"create", ( PyCFunction ) Operators_create, METH_VARARGS | METH_STATIC, + "create operator"}, + {"getViewEdgesSize", ( PyCFunction ) Operators_getViewEdgesSize, METH_NOARGS | METH_STATIC, ""}, + {"getChainsSize", ( PyCFunction ) Operators_getChainsSize, METH_NOARGS | METH_STATIC, ""}, + {"getStrokesSize", ( PyCFunction ) Operators_getStrokesSize, METH_NOARGS | METH_STATIC, ""}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_Operators type definition ------------------------------*/ + +PyTypeObject Operators_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "Operators", /* tp_name */ + sizeof(BPy_Operators), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)Operators___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "Operators objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_Operators_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int Operators_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &Operators_Type ) < 0 ) + return -1; + + Py_INCREF( &Operators_Type ); + PyModule_AddObject(module, "Operators", (PyObject *)&Operators_Type); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +void Operators___dealloc__(BPy_Operators* self) +{ + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyObject * Operators_select(BPy_Operators* self, PyObject *args) +{ + PyObject *obj = 0; + + if ( !PyArg_ParseTuple(args, "O!", &UnaryPredicate1D_Type, &obj) ) + return NULL; + if ( !((BPy_UnaryPredicate1D *) obj)->up1D ) { + PyErr_SetString(PyExc_TypeError, "Operators.select(): 1st argument: invalid UnaryPredicate1D object"); + return NULL; + } + + if (Operators::select(*( ((BPy_UnaryPredicate1D *) obj)->up1D )) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.select() failed"); + return NULL; + } + + Py_RETURN_NONE; +} + +// CHANGE: first parameter is a chaining iterator, not just a view + +PyObject * Operators_chain(BPy_Operators* self, PyObject *args) +{ + PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0; + + if ( !PyArg_ParseTuple(args, "O!O!|O!", &ChainingIterator_Type, &obj1, + &UnaryPredicate1D_Type, &obj2, + &UnaryFunction1DVoid_Type, &obj3) ) + return NULL; + if ( !((BPy_ChainingIterator *) obj1)->c_it ) { + PyErr_SetString(PyExc_TypeError, "Operators.chain(): 1st argument: invalid ChainingIterator object"); + return NULL; + } + if ( !((BPy_UnaryPredicate1D *) obj2)->up1D ) { + PyErr_SetString(PyExc_TypeError, "Operators.chain(): 2nd argument: invalid UnaryPredicate1D object"); + return NULL; + } + + if( !obj3 ) { + + if (Operators::chain( *( ((BPy_ChainingIterator *) obj1)->c_it ), + *( ((BPy_UnaryPredicate1D *) obj2)->up1D ) ) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.chain() failed"); + return NULL; + } + + } else { + + if ( !((BPy_UnaryFunction1DVoid *) obj3)->uf1D_void ) { + PyErr_SetString(PyExc_TypeError, "Operators.chain(): 3rd argument: invalid UnaryFunction1DVoid object"); + return NULL; + } + if (Operators::chain( *( ((BPy_ChainingIterator *) obj1)->c_it ), + *( ((BPy_UnaryPredicate1D *) obj2)->up1D ), + *( ((BPy_UnaryFunction1DVoid *) obj3)->uf1D_void ) ) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.chain() failed"); + return NULL; + } + + } + + Py_RETURN_NONE; +} + +PyObject * Operators_bidirectionalChain(BPy_Operators* self, PyObject *args) +{ + PyObject *obj1 = 0, *obj2 = 0; + + if( !PyArg_ParseTuple(args, "O!|O!", &ChainingIterator_Type, &obj1, &UnaryPredicate1D_Type, &obj2) ) + return NULL; + if ( !((BPy_ChainingIterator *) obj1)->c_it ) { + PyErr_SetString(PyExc_TypeError, "Operators.bidirectionalChain(): 1st argument: invalid ChainingIterator object"); + return NULL; + } + + if( !obj2 ) { + + if (Operators::bidirectionalChain( *( ((BPy_ChainingIterator *) obj1)->c_it ) ) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.bidirectionalChain() failed"); + return NULL; + } + + } else { + + if ( !((BPy_UnaryPredicate1D *) obj2)->up1D ) { + PyErr_SetString(PyExc_TypeError, "Operators.bidirectionalChain(): 2nd argument: invalid UnaryPredicate1D object"); + return NULL; + } + if (Operators::bidirectionalChain( *( ((BPy_ChainingIterator *) obj1)->c_it ), + *( ((BPy_UnaryPredicate1D *) obj2)->up1D ) ) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.bidirectionalChain() failed"); + return NULL; + } + + } + + Py_RETURN_NONE; +} + +PyObject * Operators_sequentialSplit(BPy_Operators* self, PyObject *args) +{ + PyObject *obj1 = 0, *obj2 = 0; + float f = 0.0; + + if( !PyArg_ParseTuple(args, "O!|Of", &UnaryPredicate0D_Type, &obj1, &obj2, &f) ) + return NULL; + if ( !((BPy_UnaryPredicate0D *) obj1)->up0D ) { + PyErr_SetString(PyExc_TypeError, "Operators.sequentialSplit(): 1st argument: invalid UnaryPredicate0D object"); + return NULL; + } + + if( obj2 && BPy_UnaryPredicate0D_Check(obj2) ) { + + if ( !((BPy_UnaryPredicate0D *) obj2)->up0D ) { + PyErr_SetString(PyExc_TypeError, "Operators.sequentialSplit(): 2nd argument: invalid UnaryPredicate0D object"); + return NULL; + } + if (Operators::sequentialSplit( *( ((BPy_UnaryPredicate0D *) obj1)->up0D ), + *( ((BPy_UnaryPredicate0D *) obj2)->up0D ), + f ) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.sequentialSplit() failed"); + return NULL; + } + + } else { + + if ( obj2 ) { + if ( !PyFloat_Check(obj2) ) { + PyErr_SetString(PyExc_TypeError, "Operators.sequentialSplit(): invalid 2nd argument"); + return NULL; + } + f = PyFloat_AsDouble(obj2); + } + if (Operators::sequentialSplit( *( ((BPy_UnaryPredicate0D *) obj1)->up0D ), f ) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.sequentialSplit() failed"); + return NULL; + } + + } + + Py_RETURN_NONE; +} + +PyObject * Operators_recursiveSplit(BPy_Operators* self, PyObject *args) +{ + PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0; + float f = 0.0; + + if ( !PyArg_ParseTuple(args, "O!O|Of", &UnaryFunction0DDouble_Type, &obj1, &obj2, &obj3, &f) ) + return NULL; + if ( !((BPy_UnaryFunction0DDouble *) obj1)->uf0D_double ) { + PyErr_SetString(PyExc_TypeError, "Operators.recursiveSplit(): 1st argument: invalid UnaryFunction0DDouble object"); + return NULL; + } + + if ( BPy_UnaryPredicate1D_Check(obj2) ) { + + if ( !((BPy_UnaryPredicate1D *) obj2)->up1D ) { + PyErr_SetString(PyExc_TypeError, "Operators.recursiveSplit(): 2nd argument: invalid UnaryPredicate1D object"); + return NULL; + } + if ( obj3 ) { + if ( !PyFloat_Check(obj3) ) { + PyErr_SetString(PyExc_TypeError, "Operators.recursiveSplit(): invalid 3rd argument"); + return NULL; + } + f = PyFloat_AsDouble(obj3); + } + if (Operators::recursiveSplit( *( ((BPy_UnaryFunction0DDouble *) obj1)->uf0D_double ), + *( ((BPy_UnaryPredicate1D *) obj2)->up1D ), + f ) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.recursiveSplit() failed"); + return NULL; + } + + } else { + + if ( !BPy_UnaryPredicate0D_Check(obj2) || !((BPy_UnaryPredicate0D *) obj2)->up0D ) { + PyErr_SetString(PyExc_TypeError, "Operators.recursiveSplit(): invalid 2nd argument"); + return NULL; + } + if ( !BPy_UnaryPredicate1D_Check(obj3) || !((BPy_UnaryPredicate1D *) obj3)->up1D ) { + PyErr_SetString(PyExc_TypeError, "Operators.recursiveSplit(): invalid 3rd argument"); + return NULL; + } + if (Operators::recursiveSplit( *( ((BPy_UnaryFunction0DDouble *) obj1)->uf0D_double ), + *( ((BPy_UnaryPredicate0D *) obj2)->up0D ), + *( ((BPy_UnaryPredicate1D *) obj3)->up1D ), + f ) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.recursiveSplit() failed"); + return NULL; + } + + } + + Py_RETURN_NONE; +} + +PyObject * Operators_sort(BPy_Operators* self, PyObject *args) +{ + PyObject *obj = 0; + + if ( !PyArg_ParseTuple(args, "O!", &BinaryPredicate1D_Type, &obj) ) + return NULL; + if ( !((BPy_BinaryPredicate1D *) obj)->bp1D ) { + PyErr_SetString(PyExc_TypeError, "Operators.sort(): 1st argument: invalid BinaryPredicate1D object"); + return NULL; + } + + if (Operators::sort(*( ((BPy_BinaryPredicate1D *) obj)->bp1D )) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.sort() failed"); + return NULL; + } + Py_RETURN_NONE; +} + +PyObject * Operators_create(BPy_Operators* self, PyObject *args) +{ + PyObject *obj1 = 0, *obj2 = 0; + + if ( !PyArg_ParseTuple(args, "O!O!", &UnaryPredicate1D_Type, &obj1, &PyList_Type, &obj2) ) + return NULL; + if ( !((BPy_UnaryPredicate1D *) obj1)->up1D ) { + PyErr_SetString(PyExc_TypeError, "Operators.create(): 1st argument: invalid UnaryPredicate1D object"); + return NULL; + } + + vector<StrokeShader *> shaders; + for( int i = 0; i < PyList_Size(obj2); i++) { + PyObject *py_ss = PyList_GetItem(obj2,i); + + if ( !BPy_StrokeShader_Check(py_ss) ) { + PyErr_SetString(PyExc_TypeError, "Operators.create() 2nd argument must be a list of StrokeShader objects"); + return NULL; + } + shaders.push_back( ((BPy_StrokeShader *) py_ss)->ss ); + } + + if (Operators::create( *( ((BPy_UnaryPredicate1D *) obj1)->up1D ), shaders) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Operators.create() failed"); + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject * Operators_getViewEdgesSize( BPy_Operators* self) { + return PyLong_FromLong( Operators::getViewEdgesSize() ); +} + +PyObject * Operators_getChainsSize( BPy_Operators* self ) { + return PyLong_FromLong( Operators::getChainsSize() ); +} + +PyObject * Operators_getStrokesSize( BPy_Operators* self) { + return PyLong_FromLong( Operators::getStrokesSize() ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + diff --git a/source/blender/freestyle/intern/python/BPy_Operators.h b/source/blender/freestyle/intern/python/BPy_Operators.h new file mode 100644 index 00000000000..c6b088415c4 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_Operators.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_OPERATORS_H +#define FREESTYLE_PYTHON_OPERATORS_H + +#include "../stroke/Operators.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Operators_Type; + +#define BPy_Operators_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Operators_Type) ) + +/*---------------------------Python BPy_Operators structure definition----------*/ +typedef struct { + PyObject_HEAD +} BPy_Operators; + +/*---------------------------Python BPy_Operators visible prototypes-----------*/ + +int Operators_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_OPERATORS_H */ diff --git a/source/blender/freestyle/intern/python/BPy_SShape.cpp b/source/blender/freestyle/intern/python/BPy_SShape.cpp new file mode 100644 index 00000000000..9ab2fbac096 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_SShape.cpp @@ -0,0 +1,232 @@ +#include "BPy_SShape.h" + +#include "BPy_Convert.h" +#include "BPy_BBox.h" +#include "BPy_Id.h" +#include "Interface0D/BPy_SVertex.h" +#include "Interface1D/BPy_FEdge.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for SShape instance -----------*/ +static int SShape___init__(BPy_SShape *self, PyObject *args, PyObject *kwds); +static void SShape___dealloc__(BPy_SShape *self); +static PyObject * SShape___repr__(BPy_SShape* self); + +static PyObject * SShape_AddEdge( BPy_SShape *self , PyObject *args); +static PyObject * SShape_AddNewVertex( BPy_SShape *self , PyObject *args); +static PyObject * SShape_setBBox( BPy_SShape *self , PyObject *args); +static PyObject * SShape_ComputeBBox( BPy_SShape *self ); +static PyObject * SShape_bbox( BPy_SShape *self ); +static PyObject * SShape_getVertexList( BPy_SShape *self ); +static PyObject * SShape_getEdgeList( BPy_SShape *self ); +static PyObject * SShape_getId( BPy_SShape *self ); +static PyObject * SShape_setId( BPy_SShape *self , PyObject *args); + +/*----------------------SShape instance definitions ----------------------------*/ +static PyMethodDef BPy_SShape_methods[] = { + {"AddEdge", ( PyCFunction ) SShape_AddEdge, METH_VARARGS, "(FEdge fe) Adds a FEdge to the list of FEdges. "}, + {"AddNewVertex", ( PyCFunction ) SShape_AddNewVertex, METH_VARARGS, "(SVertex sv) Adds a SVertex to the list of SVertex of this Shape. The SShape attribute of the SVertex is also set to 'this'."}, + {"setBBox", ( PyCFunction ) SShape_setBBox, METH_VARARGS, "(BBox bb) Sets the Bounding Box of the Shape"}, + {"ComputeBBox", ( PyCFunction ) SShape_ComputeBBox, METH_NOARGS, "() Compute the bbox of the SShape"}, + {"bbox", ( PyCFunction ) SShape_bbox, METH_NOARGS, "() Returns the bounding box of the shape."}, + {"getVertexList", ( PyCFunction ) SShape_getVertexList, METH_NOARGS, "() Returns the list of SVertex of the Shape"}, + {"getEdgeList", ( PyCFunction ) SShape_getEdgeList, METH_NOARGS, "() Returns the list of FEdges of the Shape."}, + {"getId", ( PyCFunction ) SShape_getId, METH_NOARGS, "() Returns the Id of the Shape. "}, + {"setId", ( PyCFunction ) SShape_setId, METH_VARARGS, "(Id id) Sets the Id of the shape. "}, + + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_SShape type definition ------------------------------*/ + +PyTypeObject SShape_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "SShape", /* tp_name */ + sizeof(BPy_SShape), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)SShape___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)SShape___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "SShape objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_SShape_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)SShape___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int SShape_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &SShape_Type ) < 0 ) + return -1; + + Py_INCREF( &SShape_Type ); + PyModule_AddObject(module, "SShape", (PyObject *)&SShape_Type); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int SShape___init__(BPy_SShape *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj = NULL; + + if (! PyArg_ParseTuple(args, "|O!", &SShape_Type, &obj) ) + return -1; + + if( !obj ) { + self->ss = new SShape(); + + } else { + self->ss = new SShape(*( ((BPy_SShape *) obj)->ss )); + } + self->borrowed = 0; + + return 0; +} + +void SShape___dealloc__(BPy_SShape *self) +{ + if( self->ss && !self->borrowed ) + delete self->ss; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyObject * SShape___repr__(BPy_SShape *self) +{ + return PyUnicode_FromFormat("SShape - address: %p", self->ss ); +} + +PyObject * SShape_AddEdge( BPy_SShape *self , PyObject *args) { + PyObject *py_fe = 0; + + if(!( PyArg_ParseTuple(args, "O!", &FEdge_Type, &py_fe) )) + return NULL; + + self->ss->AddEdge( ((BPy_FEdge *) py_fe)->fe ); + + Py_RETURN_NONE; +} + +PyObject * SShape_AddNewVertex( BPy_SShape *self , PyObject *args) { + PyObject *py_sv = 0; + + if(!( PyArg_ParseTuple(args, "O!", &SVertex_Type, &py_sv) )) + return NULL; + + self->ss->AddNewVertex( ((BPy_SVertex *) py_sv)->sv ); + + Py_RETURN_NONE; +} + +PyObject * SShape_setBBox( BPy_SShape *self , PyObject *args) { + PyObject *py_bb = 0; + + if(!( PyArg_ParseTuple(args, "O!", &BBox_Type, &py_bb) )) + return NULL; + + self->ss->setBBox(*( ((BPy_BBox*) py_bb)->bb )); + + Py_RETURN_NONE; +} + +PyObject * SShape_ComputeBBox( BPy_SShape *self ) { + self->ss->ComputeBBox(); + + Py_RETURN_NONE; +} + +PyObject * SShape_bbox( BPy_SShape *self ) { + BBox<Vec3r> bb( self->ss->bbox() ); + return BPy_BBox_from_BBox( bb ); +} + + +PyObject * SShape_getVertexList( BPy_SShape *self ) { + PyObject *py_vertices = PyList_New(0); + + vector< SVertex * > vertices = self->ss->getVertexList(); + vector< SVertex * >::iterator it; + + for( it = vertices.begin(); it != vertices.end(); it++ ) { + PyList_Append( py_vertices, BPy_SVertex_from_SVertex(*( *it )) ); + } + + return py_vertices; +} + + +PyObject * SShape_getEdgeList( BPy_SShape *self ) { + PyObject *py_edges = PyList_New(0); + + vector< FEdge * > edges = self->ss->getEdgeList(); + vector< FEdge * >::iterator it; + + for( it = edges.begin(); it != edges.end(); it++ ) { + PyList_Append( py_edges, Any_BPy_FEdge_from_FEdge(*( *it )) ); + } + + return py_edges; +} + +PyObject * SShape_getId( BPy_SShape *self ) { + Id id( self->ss->getId() ); + return BPy_Id_from_Id( id ); +} + +PyObject * SShape_setId( BPy_SShape *self , PyObject *args) { + PyObject *py_id; + + if(!( PyArg_ParseTuple(args, "O!", &Id_Type, &py_id) )) + return NULL; + + self->ss->setId(*( ((BPy_Id *) py_id)->id )); + + Py_RETURN_NONE; +} + + +// const Material & material (unsigned i) const +// const vector< Material > & materials () const +// void SetMaterials (const vector< Material > &iMaterials) + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_SShape.h b/source/blender/freestyle/intern/python/BPy_SShape.h new file mode 100644 index 00000000000..3bcb6a60603 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_SShape.h @@ -0,0 +1,35 @@ +#ifndef FREESTYLE_PYTHON_SSHAPE_H +#define FREESTYLE_PYTHON_SSHAPE_H + +#include "../view_map/Silhouette.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject SShape_Type; + +#define BPy_SShape_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &SShape_Type) ) + +/*---------------------------Python BPy_SShape structure definition----------*/ +typedef struct { + PyObject_HEAD + SShape *ss; + int borrowed; /* non-zero if *ss is a borrowed object */ +} BPy_SShape; + +/*---------------------------Python BPy_SShape visible prototypes-----------*/ + +int SShape_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_SSHAPE_H */ diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp new file mode 100644 index 00000000000..30fb7a5c2e3 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp @@ -0,0 +1,415 @@ +#include "BPy_StrokeAttribute.h" + +#include "BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for StrokeAttribute instance -----------*/ +static int StrokeAttribute___init__(BPy_StrokeAttribute *self, PyObject *args, PyObject *kwds); +static void StrokeAttribute___dealloc__(BPy_StrokeAttribute *self); +static PyObject * StrokeAttribute___repr__(BPy_StrokeAttribute *self); + +static PyObject * StrokeAttribute_getColorR( BPy_StrokeAttribute *self ); +static PyObject * StrokeAttribute_getColorG( BPy_StrokeAttribute *self ); +static PyObject * StrokeAttribute_getColorB( BPy_StrokeAttribute *self ); +static PyObject * StrokeAttribute_getColorRGB( BPy_StrokeAttribute *self ); +static PyObject * StrokeAttribute_getAlpha( BPy_StrokeAttribute *self ); +static PyObject * StrokeAttribute_getThicknessR( BPy_StrokeAttribute *self ); +static PyObject * StrokeAttribute_getThicknessL( BPy_StrokeAttribute *self ); +static PyObject * StrokeAttribute_getThicknessRL( BPy_StrokeAttribute *self ); +static PyObject * StrokeAttribute_isVisible( BPy_StrokeAttribute *self ); +static PyObject * StrokeAttribute_getAttributeReal( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_getAttributeVec2f( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_getAttributeVec3f( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_isAttributeAvailableReal( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_isAttributeAvailableVec2f( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_isAttributeAvailableVec3f( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_setColor( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_setAlpha( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_setThickness( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_setVisible( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_setAttributeReal( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_setAttributeVec2f( BPy_StrokeAttribute *self, PyObject *args ); +static PyObject * StrokeAttribute_setAttributeVec3f( BPy_StrokeAttribute *self, PyObject *args ); + + +/*----------------------StrokeAttribute instance definitions ----------------------------*/ +static PyMethodDef BPy_StrokeAttribute_methods[] = { + {"getColorR", ( PyCFunction ) StrokeAttribute_getColorR, METH_NOARGS, "Returns the R color component. "}, + {"getColorG", ( PyCFunction ) StrokeAttribute_getColorG, METH_NOARGS, "Returns the G color component. "}, + {"getColorB", ( PyCFunction ) StrokeAttribute_getColorB, METH_NOARGS, "Returns the B color component. "}, + {"getColorRGB", ( PyCFunction ) StrokeAttribute_getColorRGB, METH_NOARGS, "Returns the RGB color components."}, + {"getAlpha", ( PyCFunction ) StrokeAttribute_getAlpha, METH_NOARGS, "Returns the alpha color component."}, + {"getThicknessR", ( PyCFunction ) StrokeAttribute_getThicknessR, METH_NOARGS, "Returns the thickness on the right of the vertex when following the stroke. "}, + {"getThicknessL", ( PyCFunction ) StrokeAttribute_getThicknessL, METH_NOARGS, "Returns the thickness on the left of the vertex when following the stroke."}, + {"getThicknessRL", ( PyCFunction ) StrokeAttribute_getThicknessRL, METH_NOARGS, "Returns the thickness on the right and on the left of the vertex when following the stroke. "}, + {"isVisible", ( PyCFunction ) StrokeAttribute_isVisible, METH_NOARGS, "Returns true if the strokevertex is visible, false otherwise"}, + {"getAttributeReal", ( PyCFunction ) StrokeAttribute_getAttributeReal, METH_VARARGS, "(name) Returns an attribute of type real specified by name."}, + {"getAttributeVec2f", ( PyCFunction ) StrokeAttribute_getAttributeVec2f, METH_VARARGS, "(name) Returns an attribute of type Vec2f specified by name."}, + {"getAttributeVec3f", ( PyCFunction ) StrokeAttribute_getAttributeVec3f, METH_VARARGS, "(name) Returns an attribute of type Vec3f specified by name."}, + {"isAttributeAvailableReal", ( PyCFunction ) StrokeAttribute_isAttributeAvailableReal, METH_VARARGS, "(name) Checks whether the real attribute specified by name is available"}, + {"isAttributeAvailableVec2f", ( PyCFunction ) StrokeAttribute_isAttributeAvailableVec2f, METH_VARARGS, "(name) Checks whether the Vec2f attribute specified by name is available"}, + {"isAttributeAvailableVec3f", ( PyCFunction ) StrokeAttribute_isAttributeAvailableVec3f, METH_VARARGS, "(name) Checks whether the Vec3f attribute specified by name is available"}, + {"setColor", ( PyCFunction ) StrokeAttribute_setColor, METH_VARARGS, "(float a)Sets the attribute's alpha value. "}, + {"setAlpha", ( PyCFunction ) StrokeAttribute_setAlpha, METH_VARARGS, "(float a) Sets the attribute's alpha value."}, + {"setThickness", ( PyCFunction ) StrokeAttribute_setThickness, METH_VARARGS, ""}, + {"setVisible", ( PyCFunction ) StrokeAttribute_setVisible, METH_VARARGS, ""}, + {"setAttributeReal", ( PyCFunction ) StrokeAttribute_setAttributeReal, METH_VARARGS, "(name, float att) Adds a user defined attribute of type real. If there is no attribute of specified by name, it is added. Otherwise, the new value replaces the old one."}, + {"setAttributeVec2f", ( PyCFunction ) StrokeAttribute_setAttributeVec2f, METH_VARARGS, "(name, float att) Adds a user defined attribute of type Vec2f. If there is no attribute of specified by name, it is added. Otherwise, the new value replaces the old one."}, + {"setAttributeVec3f", ( PyCFunction ) StrokeAttribute_setAttributeVec3f, METH_VARARGS, "(name, float att) Adds a user defined attribute of type Vec4f. If there is no attribute of specified by name, it is added. Otherwise, the new value replaces the old one."}, + {NULL, NULL, 0, NULL} +}; + + + +/*-----------------------BPy_StrokeAttribute type definition ------------------------------*/ + +PyTypeObject StrokeAttribute_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "StrokeAttribute", /* tp_name */ + sizeof(BPy_StrokeAttribute), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)StrokeAttribute___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)StrokeAttribute___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "StrokeAttribute objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_StrokeAttribute_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)StrokeAttribute___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int StrokeAttribute_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &StrokeAttribute_Type ) < 0 ) + return -1; + Py_INCREF( &StrokeAttribute_Type ); + PyModule_AddObject(module, "StrokeAttribute", (PyObject *)&StrokeAttribute_Type); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int StrokeAttribute___init__(BPy_StrokeAttribute *self, PyObject *args, PyObject *kwds) +{ + + PyObject *obj1 = 0, *obj2 = 0 , *obj3 = 0, *obj4 = 0, *obj5 = 0 , *obj6 = 0; + + if (! PyArg_ParseTuple(args, "|OOOOOO", &obj1, &obj2, &obj3, &obj4, &obj5, &obj6) ) + return -1; + + if( !obj1 || !obj2 || !obj3 ){ + + self->sa = new StrokeAttribute(); + + } else if( BPy_StrokeAttribute_Check(obj1) && + BPy_StrokeAttribute_Check(obj2) && + PyFloat_Check(obj3) ) { + + self->sa = new StrokeAttribute( *( ((BPy_StrokeAttribute *) obj1)->sa ), + *( ((BPy_StrokeAttribute *) obj2)->sa ), + PyFloat_AsDouble( obj3 ) ); + + } else if( obj4 && obj5 && obj6 ) { + + self->sa = new StrokeAttribute( PyFloat_AsDouble( obj1 ), + PyFloat_AsDouble( obj2 ), + PyFloat_AsDouble( obj3 ), + PyFloat_AsDouble( obj4 ), + PyFloat_AsDouble( obj5 ), + PyFloat_AsDouble( obj6 ) ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid arguments"); + return -1; + } + + self->borrowed = 0; + + return 0; + +} + +void StrokeAttribute___dealloc__(BPy_StrokeAttribute* self) +{ + if( self->sa && !self->borrowed ) + delete self->sa; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyObject * StrokeAttribute___repr__(BPy_StrokeAttribute* self) +{ + stringstream repr("StrokeAttribute:"); + repr << " r: " << self->sa->getColorR() + << " g: " << self->sa->getColorG() + << " b: " << self->sa->getColorB() + << " a: " << self->sa->getAlpha() + << " - R: " << self->sa->getThicknessR() + << " L: " << self->sa->getThicknessL(); + + return PyUnicode_FromFormat( repr.str().c_str() ); +} + + +PyObject *StrokeAttribute_getColorR( BPy_StrokeAttribute *self ) { + return PyFloat_FromDouble( self->sa->getColorR() ); +} + +PyObject *StrokeAttribute_getColorG( BPy_StrokeAttribute *self ) { + return PyFloat_FromDouble( self->sa->getColorG() ); +} + +PyObject *StrokeAttribute_getColorB( BPy_StrokeAttribute *self ) { + return PyFloat_FromDouble( self->sa->getColorB() ); +} + +PyObject *StrokeAttribute_getColorRGB( BPy_StrokeAttribute *self ) { + Vec3f v( self->sa->getColorRGB() ); + return Vector_from_Vec3f( v ); +} + +PyObject *StrokeAttribute_getAlpha( BPy_StrokeAttribute *self ) { + return PyFloat_FromDouble( self->sa->getAlpha() ); +} + +PyObject *StrokeAttribute_getThicknessR( BPy_StrokeAttribute *self ) { + return PyFloat_FromDouble( self->sa->getThicknessR() ); +} +PyObject *StrokeAttribute_getThicknessL( BPy_StrokeAttribute *self ) { + return PyFloat_FromDouble( self->sa->getThicknessL() ); +} +PyObject *StrokeAttribute_getThicknessRL( BPy_StrokeAttribute *self ) { + Vec2f v( self->sa->getThicknessRL() ); + return Vector_from_Vec2f( v ); +} + +PyObject *StrokeAttribute_isVisible( BPy_StrokeAttribute *self ) { + return PyBool_from_bool( self->sa->isVisible() ); +} + + +PyObject *StrokeAttribute_getAttributeReal( BPy_StrokeAttribute *self, PyObject *args ) { + char *attr; + + if(!( PyArg_ParseTuple(args, "s", &attr) )) + return NULL; + + double a = self->sa->getAttributeReal( attr ); + return PyFloat_FromDouble( a ); +} + +PyObject *StrokeAttribute_getAttributeVec2f( BPy_StrokeAttribute *self, PyObject *args ) { + char *attr; + + if(!( PyArg_ParseTuple(args, "s", &attr) )) + return NULL; + + Vec2f a = self->sa->getAttributeVec2f( attr ); + return Vector_from_Vec2f( a ); +} + + +PyObject *StrokeAttribute_getAttributeVec3f( BPy_StrokeAttribute *self, PyObject *args ) { + char *attr; + + if(!( PyArg_ParseTuple(args, "s", &attr) )) + return NULL; + + Vec3f a = self->sa->getAttributeVec3f( attr ); + return Vector_from_Vec3f( a ); +} + +PyObject *StrokeAttribute_isAttributeAvailableReal( BPy_StrokeAttribute *self, PyObject *args ) { + char *attr; + + if(!( PyArg_ParseTuple(args, "s", &attr) )) + return NULL; + + return PyBool_from_bool( self->sa->isAttributeAvailableReal( attr ) ); +} + +PyObject *StrokeAttribute_isAttributeAvailableVec2f( BPy_StrokeAttribute *self, PyObject *args ) { + char *attr; + + if(!( PyArg_ParseTuple(args, "s", &attr) )) + return NULL; + + return PyBool_from_bool( self->sa->isAttributeAvailableVec2f( attr ) ); +} + +PyObject *StrokeAttribute_isAttributeAvailableVec3f( BPy_StrokeAttribute *self, PyObject *args ) { + char *attr; + + if(!( PyArg_ParseTuple(args, "s", &attr) )) + return NULL; + + return PyBool_from_bool( self->sa->isAttributeAvailableVec3f( attr ) ); +} + + +PyObject * StrokeAttribute_setColor( BPy_StrokeAttribute *self, PyObject *args ) { + PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0 ; + + if(!( PyArg_ParseTuple(args, "O|OO", &obj1, &obj2, &obj3) )) + return NULL; + + if( obj1 && !obj2 && !obj3 ){ + + Vec3f *v = Vec3f_ptr_from_PyObject(obj1); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); + return NULL; + } + self->sa->setColor( *v ); + delete v; + + } else if( obj1 && obj2 && obj3 ){ + + self->sa->setColor( PyFloat_AsDouble(obj1), + PyFloat_AsDouble(obj2), + PyFloat_AsDouble(obj3) ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid arguments"); + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject * StrokeAttribute_setAlpha( BPy_StrokeAttribute *self, PyObject *args ){ + float f = 0; + + if(!( PyArg_ParseTuple(args, "f", &f) )) + return NULL; + + self->sa->setAlpha( f ); + Py_RETURN_NONE; +} + +PyObject * StrokeAttribute_setThickness( BPy_StrokeAttribute *self, PyObject *args ) { + PyObject *obj1 = 0, *obj2 = 0; + + if(!( PyArg_ParseTuple(args, "O|O", &obj1, &obj2) )) + return NULL; + + if( obj1 && !obj2 ){ + + Vec2f *v = Vec2f_ptr_from_PyObject(obj1); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 2D vector (either a list of 2 elements or Vector)"); + return NULL; + } + self->sa->setThickness( *v ); + delete v; + + } else if( obj1 && obj2 ){ + + self->sa->setThickness( PyFloat_AsDouble(obj1), + PyFloat_AsDouble(obj2) ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid arguments"); + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject * StrokeAttribute_setVisible( BPy_StrokeAttribute *self, PyObject *args ) { + PyObject *py_b; + + if(!( PyArg_ParseTuple(args, "O", &py_b) )) + return NULL; + + self->sa->setVisible( bool_from_PyBool(py_b) ); + + Py_RETURN_NONE; +} + + +PyObject * StrokeAttribute_setAttributeReal( BPy_StrokeAttribute *self, PyObject *args ) { + char *s = 0; + double d = 0; + + if(!( PyArg_ParseTuple(args, "sd", &s, &d) )) + return NULL; + + self->sa->setAttributeReal( s, d ); + Py_RETURN_NONE; +} + +PyObject * StrokeAttribute_setAttributeVec2f( BPy_StrokeAttribute *self, PyObject *args ) { + char *s; + PyObject *obj = 0; + + if(!( PyArg_ParseTuple(args, "sO", &s, &obj) )) + return NULL; + Vec2f *v = Vec2f_ptr_from_PyObject(obj); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 2 must be a 2D vector (either a list of 2 elements or Vector)"); + return NULL; + } + self->sa->setAttributeVec2f( s, *v ); + delete v; + + Py_RETURN_NONE; +} + +PyObject * StrokeAttribute_setAttributeVec3f( BPy_StrokeAttribute *self, PyObject *args ) { + char *s; + PyObject *obj = 0; + + if(!( PyArg_ParseTuple(args, "sO", &s, &obj) )) + return NULL; + Vec3f *v = Vec3f_ptr_from_PyObject(obj); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 2 must be a 3D vector (either a list of 3 elements or Vector)"); + return NULL; + } + self->sa->setAttributeVec3f( s, *v ); + delete v; + + Py_RETURN_NONE; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h new file mode 100644 index 00000000000..a2193c681aa --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.h @@ -0,0 +1,35 @@ +#ifndef FREESTYLE_PYTHON_STROKEATTRIBUTE_H +#define FREESTYLE_PYTHON_STROKEATTRIBUTE_H + +#include "../stroke/Stroke.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject StrokeAttribute_Type; + +#define BPy_StrokeAttribute_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &StrokeAttribute_Type) ) + +/*---------------------------Python BPy_StrokeAttribute structure definition----------*/ +typedef struct { + PyObject_HEAD + StrokeAttribute *sa; + int borrowed; /* non-zero if *sa is a borrowed reference */ +} BPy_StrokeAttribute; + +/*---------------------------Python BPy_StrokeAttribute visible prototypes-----------*/ + +int StrokeAttribute_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_STROKEATTRIBUTE_H */ diff --git a/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp new file mode 100644 index 00000000000..637d917fb6d --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_StrokeShader.cpp @@ -0,0 +1,273 @@ +#include "BPy_StrokeShader.h" + +#include "BPy_Convert.h" +#include "Interface1D/BPy_Stroke.h" + +#include "StrokeShader/BPy_BackboneStretcherShader.h" +#include "StrokeShader/BPy_BezierCurveShader.h" +#include "StrokeShader/BPy_CalligraphicShader.h" +#include "StrokeShader/BPy_ColorNoiseShader.h" +#include "StrokeShader/BPy_ColorVariationPatternShader.h" +#include "StrokeShader/BPy_ConstantColorShader.h" +#include "StrokeShader/BPy_ConstantThicknessShader.h" +#include "StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h" +#include "StrokeShader/BPy_fstreamShader.h" +#include "StrokeShader/BPy_GuidingLinesShader.h" +#include "StrokeShader/BPy_IncreasingColorShader.h" +#include "StrokeShader/BPy_IncreasingThicknessShader.h" +#include "StrokeShader/BPy_PolygonalizationShader.h" +#include "StrokeShader/BPy_SamplingShader.h" +#include "StrokeShader/BPy_SmoothingShader.h" +#include "StrokeShader/BPy_SpatialNoiseShader.h" +#include "StrokeShader/BPy_streamShader.h" +#include "StrokeShader/BPy_StrokeTextureShader.h" +#include "StrokeShader/BPy_TextureAssignerShader.h" +#include "StrokeShader/BPy_ThicknessNoiseShader.h" +#include "StrokeShader/BPy_ThicknessVariationPatternShader.h" +#include "StrokeShader/BPy_TipRemoverShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for StrokeShader instance -----------*/ +static int StrokeShader___init__(BPy_StrokeShader *self, PyObject *args, PyObject *kwds); +static void StrokeShader___dealloc__(BPy_StrokeShader *self); +static PyObject * StrokeShader___repr__(BPy_StrokeShader *self); + +static PyObject * StrokeShader_getName( BPy_StrokeShader *self, PyObject *args); +static PyObject * StrokeShader_shade( BPy_StrokeShader *self , PyObject *args); + +/*----------------------StrokeShader instance definitions ----------------------------*/ +static PyMethodDef BPy_StrokeShader_methods[] = { + {"getName", ( PyCFunction ) StrokeShader_getName, METH_NOARGS, "() Returns the string of the name of the binary predicate."}, + {"shade", ( PyCFunction ) StrokeShader_shade, METH_VARARGS, "(Stroke s) The shading method. This method must be overloaded by inherited classes. The shading method is designed to modify any Stroke's attribute such as Thickness, Color, Geometry, Texture, Blending mode... The basic way to achieve this operation consists in iterating over the StrokeVertices of the Stroke and to modify each one's StrokeAttribute."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_StrokeShader type definition ------------------------------*/ + +PyTypeObject StrokeShader_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "StrokeShader", /* tp_name */ + sizeof(BPy_StrokeShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)StrokeShader___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)StrokeShader___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "StrokeShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_StrokeShader_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)StrokeShader___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int StrokeShader_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &StrokeShader_Type ) < 0 ) + return -1; + Py_INCREF( &StrokeShader_Type ); + PyModule_AddObject(module, "StrokeShader", (PyObject *)&StrokeShader_Type); + + if( PyType_Ready( &BackboneStretcherShader_Type ) < 0 ) + return -1; + Py_INCREF( &BackboneStretcherShader_Type ); + PyModule_AddObject(module, "BackboneStretcherShader", (PyObject *)&BackboneStretcherShader_Type); + + if( PyType_Ready( &BezierCurveShader_Type ) < 0 ) + return -1; + Py_INCREF( &BezierCurveShader_Type ); + PyModule_AddObject(module, "BezierCurveShader", (PyObject *)&BezierCurveShader_Type); + + if( PyType_Ready( &CalligraphicShader_Type ) < 0 ) + return -1; + Py_INCREF( &CalligraphicShader_Type ); + PyModule_AddObject(module, "CalligraphicShader", (PyObject *)&CalligraphicShader_Type); + + if( PyType_Ready( &ColorNoiseShader_Type ) < 0 ) + return -1; + Py_INCREF( &ColorNoiseShader_Type ); + PyModule_AddObject(module, "ColorNoiseShader", (PyObject *)&ColorNoiseShader_Type); + + if( PyType_Ready( &ColorVariationPatternShader_Type ) < 0 ) + return -1; + Py_INCREF( &ColorVariationPatternShader_Type ); + PyModule_AddObject(module, "ColorVariationPatternShader", (PyObject *)&ColorVariationPatternShader_Type); + + if( PyType_Ready( &ConstantColorShader_Type ) < 0 ) + return -1; + Py_INCREF( &ConstantColorShader_Type ); + PyModule_AddObject(module, "ConstantColorShader", (PyObject *)&ConstantColorShader_Type); + + if( PyType_Ready( &ConstantThicknessShader_Type ) < 0 ) + return -1; + Py_INCREF( &ConstantThicknessShader_Type ); + PyModule_AddObject(module, "ConstantThicknessShader", (PyObject *)&ConstantThicknessShader_Type); + + if( PyType_Ready( &ConstrainedIncreasingThicknessShader_Type ) < 0 ) + return -1; + Py_INCREF( &ConstrainedIncreasingThicknessShader_Type ); + PyModule_AddObject(module, "ConstrainedIncreasingThicknessShader", (PyObject *)&ConstrainedIncreasingThicknessShader_Type); + + if( PyType_Ready( &fstreamShader_Type ) < 0 ) + return -1; + Py_INCREF( &fstreamShader_Type ); + PyModule_AddObject(module, "fstreamShader", (PyObject *)&fstreamShader_Type); + + if( PyType_Ready( &GuidingLinesShader_Type ) < 0 ) + return -1; + Py_INCREF( &GuidingLinesShader_Type ); + PyModule_AddObject(module, "GuidingLinesShader", (PyObject *)&GuidingLinesShader_Type); + + if( PyType_Ready( &IncreasingColorShader_Type ) < 0 ) + return -1; + Py_INCREF( &IncreasingColorShader_Type ); + PyModule_AddObject(module, "IncreasingColorShader", (PyObject *)&IncreasingColorShader_Type); + + if( PyType_Ready( &IncreasingThicknessShader_Type ) < 0 ) + return -1; + Py_INCREF( &IncreasingThicknessShader_Type ); + PyModule_AddObject(module, "IncreasingThicknessShader", (PyObject *)&IncreasingThicknessShader_Type); + + if( PyType_Ready( &PolygonalizationShader_Type ) < 0 ) + return -1; + Py_INCREF( &PolygonalizationShader_Type ); + PyModule_AddObject(module, "PolygonalizationShader", (PyObject *)&PolygonalizationShader_Type); + + if( PyType_Ready( &SamplingShader_Type ) < 0 ) + return -1; + Py_INCREF( &SamplingShader_Type ); + PyModule_AddObject(module, "SamplingShader", (PyObject *)&SamplingShader_Type); + + if( PyType_Ready( &SmoothingShader_Type ) < 0 ) + return -1; + Py_INCREF( &SmoothingShader_Type ); + PyModule_AddObject(module, "SmoothingShader", (PyObject *)&SmoothingShader_Type); + + if( PyType_Ready( &SpatialNoiseShader_Type ) < 0 ) + return -1; + Py_INCREF( &SpatialNoiseShader_Type ); + PyModule_AddObject(module, "SpatialNoiseShader", (PyObject *)&SpatialNoiseShader_Type); + + if( PyType_Ready( &streamShader_Type ) < 0 ) + return -1; + Py_INCREF( &streamShader_Type ); + PyModule_AddObject(module, "streamShader", (PyObject *)&streamShader_Type); + + if( PyType_Ready( &StrokeTextureShader_Type ) < 0 ) + return -1; + Py_INCREF( &StrokeTextureShader_Type ); + PyModule_AddObject(module, "StrokeTextureShader", (PyObject *)&StrokeTextureShader_Type); + + if( PyType_Ready( &TextureAssignerShader_Type ) < 0 ) + return -1; + Py_INCREF( &TextureAssignerShader_Type ); + PyModule_AddObject(module, "TextureAssignerShader", (PyObject *)&TextureAssignerShader_Type); + + if( PyType_Ready( &ThicknessNoiseShader_Type ) < 0 ) + return -1; + Py_INCREF( &ThicknessNoiseShader_Type ); + PyModule_AddObject(module, "ThicknessNoiseShader", (PyObject *)&ThicknessNoiseShader_Type); + + if( PyType_Ready( &ThicknessVariationPatternShader_Type ) < 0 ) + return -1; + Py_INCREF( &ThicknessVariationPatternShader_Type ); + PyModule_AddObject(module, "ThicknessVariationPatternShader", (PyObject *)&ThicknessVariationPatternShader_Type); + + if( PyType_Ready( &TipRemoverShader_Type ) < 0 ) + return -1; + Py_INCREF( &TipRemoverShader_Type ); + PyModule_AddObject(module, "TipRemoverShader", (PyObject *)&TipRemoverShader_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int StrokeShader___init__(BPy_StrokeShader *self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->ss = new StrokeShader(); + self->ss->py_ss = (PyObject *) self; + return 0; +} + +void StrokeShader___dealloc__(BPy_StrokeShader* self) +{ + if (self->ss) + delete self->ss; + Py_TYPE(self)->tp_free((PyObject*)self); +} + + +PyObject * StrokeShader___repr__(BPy_StrokeShader* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->ss->getName().c_str(), self->ss ); +} + + +PyObject * StrokeShader_getName( BPy_StrokeShader *self, PyObject *args) +{ + return PyUnicode_FromFormat( self->ss->getName().c_str() ); +} + +PyObject *StrokeShader_shade( BPy_StrokeShader *self , PyObject *args) { + PyObject *py_s = 0; + + if(!( PyArg_ParseTuple(args, "O!", &Stroke_Type, &py_s) )) + return NULL; + + if( typeid(*(self->ss)) == typeid(StrokeShader) ) { + PyErr_SetString(PyExc_TypeError, "shade method not properly overridden"); + return NULL; + } + if (self->ss->shade(*( ((BPy_Stroke *) py_s)->s )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->ss->getName() + " shade method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + Py_RETURN_NONE; +} + + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_StrokeShader.h b/source/blender/freestyle/intern/python/BPy_StrokeShader.h new file mode 100644 index 00000000000..e1d72cef546 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_StrokeShader.h @@ -0,0 +1,41 @@ +#ifndef FREESTYLE_PYTHON_STROKESHADER_H +#define FREESTYLE_PYTHON_STROKESHADER_H + + +#include "../system/FreestyleConfig.h" + +using namespace std; + +#include "../stroke/StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject StrokeShader_Type; + +#define BPy_StrokeShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &StrokeShader_Type) ) + +/*---------------------------Python BPy_StrokeShader structure definition----------*/ +typedef struct { + PyObject_HEAD + StrokeShader *ss; +} BPy_StrokeShader; + +/*---------------------------Python BPy_StrokeShader visible prototypes-----------*/ + +int StrokeShader_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_STROKESHADER_H */ diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp new file mode 100644 index 00000000000..8558daf0693 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.cpp @@ -0,0 +1,111 @@ +#include "BPy_UnaryFunction0D.h" + +#include "UnaryFunction0D/BPy_UnaryFunction0DDouble.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DFloat.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DId.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DMaterial.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DVec2f.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DVec3f.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DViewShape.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0D instance -----------*/ + +static void UnaryFunction0D___dealloc__(BPy_UnaryFunction0D *self); +static PyObject * UnaryFunction0D___repr__(BPy_UnaryFunction0D *self); + +/*-----------------------BPy_UnaryFunction0D type definition ------------------------------*/ + +PyTypeObject UnaryFunction0D_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0D", /* tp_name */ + sizeof(BPy_UnaryFunction0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0D___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0D___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int UnaryFunction0D_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0D_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0D_Type ); + PyModule_AddObject(module, "UnaryFunction0D", (PyObject *)&UnaryFunction0D_Type); + + UnaryFunction0DDouble_Init( module ); + UnaryFunction0DEdgeNature_Init( module ); + UnaryFunction0DFloat_Init( module ); + UnaryFunction0DId_Init( module ); + UnaryFunction0DMaterial_Init( module ); + UnaryFunction0DUnsigned_Init( module ); + UnaryFunction0DVec2f_Init( module ); + UnaryFunction0DVec3f_Init( module ); + UnaryFunction0DVectorViewShape_Init( module ); + UnaryFunction0DViewShape_Init( module ); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +void UnaryFunction0D___dealloc__(BPy_UnaryFunction0D* self) +{ + Py_TYPE(self)->tp_free((PyObject*)self); +} + + +PyObject * UnaryFunction0D___repr__(BPy_UnaryFunction0D* self) +{ + return PyUnicode_FromFormat("UnaryFunction0D"); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h new file mode 100644 index 00000000000..d9215e3275f --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction0D.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0D_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0D_H + +#include "../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0D_Type; + +#define BPy_UnaryFunction0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0D_Type) ) + +/*---------------------------Python BPy_UnaryFunction0D structure definition----------*/ +typedef struct { + PyObject_HEAD + PyObject *py_uf0D; +} BPy_UnaryFunction0D; + +/*---------------------------Python BPy_UnaryFunction0D visible prototypes-----------*/ + +int UnaryFunction0D_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0D_H */ diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp new file mode 100644 index 00000000000..c05ba35422f --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.cpp @@ -0,0 +1,105 @@ +#include "BPy_UnaryFunction1D.h" + +#include "UnaryFunction1D/BPy_UnaryFunction1DDouble.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DFloat.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DVec2f.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DVec3f.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DVoid.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction1D instance -----------*/ + +static void UnaryFunction1D___dealloc__(BPy_UnaryFunction1D *self); +static PyObject * UnaryFunction1D___repr__(BPy_UnaryFunction1D *self); + +/*-----------------------BPy_UnaryFunction1D type definition ------------------------------*/ + +PyTypeObject UnaryFunction1D_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction1D", /* tp_name */ + sizeof(BPy_UnaryFunction1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction1D___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction1D___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int UnaryFunction1D_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction1D_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction1D_Type ); + PyModule_AddObject(module, "UnaryFunction1D", (PyObject *)&UnaryFunction1D_Type); + + UnaryFunction1DDouble_Init( module ); + UnaryFunction1DEdgeNature_Init( module ); + UnaryFunction1DFloat_Init( module ); + UnaryFunction1DUnsigned_Init( module ); + UnaryFunction1DVec2f_Init( module ); + UnaryFunction1DVec3f_Init( module ); + UnaryFunction1DVectorViewShape_Init( module ); + UnaryFunction1DVoid_Init( module ); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +void UnaryFunction1D___dealloc__(BPy_UnaryFunction1D* self) +{ + Py_TYPE(self)->tp_free((PyObject*)self); +} + + +PyObject * UnaryFunction1D___repr__(BPy_UnaryFunction1D* self) +{ + return PyUnicode_FromFormat("UnaryFunction1D"); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h new file mode 100644 index 00000000000..b8d92ba649d --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_UnaryFunction1D.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION1D_H +#define FREESTYLE_PYTHON_UNARYFUNCTION1D_H + +#include "../view_map/Functions1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction1D_Type; + +#define BPy_UnaryFunction1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction1D_Type) ) + +/*---------------------------Python BPy_UnaryFunction1D structure definition----------*/ +typedef struct { + PyObject_HEAD + PyObject *py_uf1D; +} BPy_UnaryFunction1D; + +/*---------------------------Python BPy_UnaryFunction1D visible prototypes-----------*/ + +int UnaryFunction1D_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION1D_H */ diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp new file mode 100644 index 00000000000..0a2a943b346 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.cpp @@ -0,0 +1,165 @@ +#include "BPy_UnaryPredicate0D.h" + +#include "BPy_Convert.h" +#include "Iterator/BPy_Interface0DIterator.h" +#include "UnaryPredicate0D/BPy_FalseUP0D.h" +#include "UnaryPredicate0D/BPy_TrueUP0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryPredicate0D instance -----------*/ +static int UnaryPredicate0D___init__(BPy_UnaryPredicate0D *self, PyObject *args, PyObject *kwds); +static void UnaryPredicate0D___dealloc__(BPy_UnaryPredicate0D *self); +static PyObject * UnaryPredicate0D___repr__(BPy_UnaryPredicate0D *self); +static PyObject * UnaryPredicate0D___call__( BPy_UnaryPredicate0D *self, PyObject *args, PyObject *kwds); + +static PyObject * UnaryPredicate0D_getName( BPy_UnaryPredicate0D *self ); + +/*----------------------UnaryPredicate0D instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryPredicate0D_methods[] = { + {"getName", ( PyCFunction ) UnaryPredicate0D_getName, METH_NOARGS, "Returns the string of the name of the UnaryPredicate0D."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryPredicate0D type definition ------------------------------*/ + +PyTypeObject UnaryPredicate0D_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryPredicate0D", /* tp_name */ + sizeof(BPy_UnaryPredicate0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryPredicate0D___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryPredicate0D___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryPredicate0D___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryPredicate0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryPredicate0D_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryPredicate0D___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int UnaryPredicate0D_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryPredicate0D_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryPredicate0D_Type ); + PyModule_AddObject(module, "UnaryPredicate0D", (PyObject *)&UnaryPredicate0D_Type); + + if( PyType_Ready( &FalseUP0D_Type ) < 0 ) + return -1; + Py_INCREF( &FalseUP0D_Type ); + PyModule_AddObject(module, "FalseUP0D", (PyObject *)&FalseUP0D_Type); + + if( PyType_Ready( &TrueUP0D_Type ) < 0 ) + return -1; + Py_INCREF( &TrueUP0D_Type ); + PyModule_AddObject(module, "TrueUP0D", (PyObject *)&TrueUP0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryPredicate0D___init__(BPy_UnaryPredicate0D *self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->up0D = new UnaryPredicate0D(); + self->up0D->py_up0D = (PyObject *) self; + return 0; +} + +void UnaryPredicate0D___dealloc__(BPy_UnaryPredicate0D* self) +{ + if (self->up0D) + delete self->up0D; + Py_TYPE(self)->tp_free((PyObject*)self); +} + + +PyObject * UnaryPredicate0D___repr__(BPy_UnaryPredicate0D* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->up0D->getName().c_str(), self->up0D ); +} + + +PyObject * UnaryPredicate0D_getName( BPy_UnaryPredicate0D *self ) +{ + return PyUnicode_FromFormat( self->up0D->getName().c_str() ); +} + +PyObject * UnaryPredicate0D___call__( BPy_UnaryPredicate0D *self, PyObject *args, PyObject *kwds) +{ + PyObject *py_if0D_it; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &py_if0D_it) ) + return NULL; + + Interface0DIterator *if0D_it = ((BPy_Interface0DIterator *) py_if0D_it)->if0D_it; + + if( !if0D_it ) { + string msg(self->up0D->getName() + " has no Interface0DIterator"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + return NULL; + } + if( typeid(*(self->up0D)) == typeid(UnaryPredicate0D) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->up0D->operator()(*if0D_it) < 0) { + if (!PyErr_Occurred()) { + string msg(self->up0D->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return PyBool_from_bool( self->up0D->result ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + + diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h new file mode 100644 index 00000000000..a3b56d39594 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate0D.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYPREDICATE0D_H +#define FREESTYLE_PYTHON_UNARYPREDICATE0D_H + +#include "../stroke/Predicates0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryPredicate0D_Type; + +#define BPy_UnaryPredicate0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryPredicate0D_Type) ) + +/*---------------------------Python BPy_UnaryPredicate0D structure definition----------*/ +typedef struct { + PyObject_HEAD + UnaryPredicate0D *up0D; +} BPy_UnaryPredicate0D; + +/*---------------------------Python BPy_UnaryPredicate0D visible prototypes-----------*/ + +int UnaryPredicate0D_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYPREDICATE0D_H */ diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp new file mode 100644 index 00000000000..be0062644fd --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.cpp @@ -0,0 +1,208 @@ +#include "BPy_UnaryPredicate1D.h" + +#include "BPy_Convert.h" +#include "BPy_Interface1D.h" + +#include "UnaryPredicate1D/BPy_ContourUP1D.h" +#include "UnaryPredicate1D/BPy_DensityLowerThanUP1D.h" +#include "UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h" +#include "UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h" +#include "UnaryPredicate1D/BPy_ExternalContourUP1D.h" +#include "UnaryPredicate1D/BPy_FalseUP1D.h" +#include "UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h" +#include "UnaryPredicate1D/BPy_ShapeUP1D.h" +#include "UnaryPredicate1D/BPy_TrueUP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryPredicate1D instance -----------*/ +static int UnaryPredicate1D___init__(BPy_UnaryPredicate1D *self, PyObject *args, PyObject *kwds); +static void UnaryPredicate1D___dealloc__(BPy_UnaryPredicate1D *self); +static PyObject * UnaryPredicate1D___repr__(BPy_UnaryPredicate1D *self); +static PyObject * UnaryPredicate1D___call__( BPy_UnaryPredicate1D *self, PyObject *args, PyObject *kwds); + +static PyObject * UnaryPredicate1D_getName( BPy_UnaryPredicate1D *self, PyObject *args); + +/*----------------------UnaryPredicate1D instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryPredicate1D_methods[] = { + {"getName", ( PyCFunction ) UnaryPredicate1D_getName, METH_NOARGS, ""}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryPredicate1D type definition ------------------------------*/ + +PyTypeObject UnaryPredicate1D_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryPredicate1D", /* tp_name */ + sizeof(BPy_UnaryPredicate1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryPredicate1D___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryPredicate1D___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryPredicate1D___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryPredicate1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryPredicate1D_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryPredicate1D___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int UnaryPredicate1D_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryPredicate1D_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryPredicate1D_Type ); + PyModule_AddObject(module, "UnaryPredicate1D", (PyObject *)&UnaryPredicate1D_Type); + + if( PyType_Ready( &ContourUP1D_Type ) < 0 ) + return -1; + Py_INCREF( &ContourUP1D_Type ); + PyModule_AddObject(module, "ContourUP1D", (PyObject *)&ContourUP1D_Type); + + if( PyType_Ready( &DensityLowerThanUP1D_Type ) < 0 ) + return -1; + Py_INCREF( &DensityLowerThanUP1D_Type ); + PyModule_AddObject(module, "DensityLowerThanUP1D", (PyObject *)&DensityLowerThanUP1D_Type); + + if( PyType_Ready( &EqualToChainingTimeStampUP1D_Type ) < 0 ) + return -1; + Py_INCREF( &EqualToChainingTimeStampUP1D_Type ); + PyModule_AddObject(module, "EqualToChainingTimeStampUP1D", (PyObject *)&EqualToChainingTimeStampUP1D_Type); + + if( PyType_Ready( &EqualToTimeStampUP1D_Type ) < 0 ) + return -1; + Py_INCREF( &EqualToTimeStampUP1D_Type ); + PyModule_AddObject(module, "EqualToTimeStampUP1D", (PyObject *)&EqualToTimeStampUP1D_Type); + + if( PyType_Ready( &ExternalContourUP1D_Type ) < 0 ) + return -1; + Py_INCREF( &ExternalContourUP1D_Type ); + PyModule_AddObject(module, "ExternalContourUP1D", (PyObject *)&ExternalContourUP1D_Type); + + if( PyType_Ready( &FalseUP1D_Type ) < 0 ) + return -1; + Py_INCREF( &FalseUP1D_Type ); + PyModule_AddObject(module, "FalseUP1D", (PyObject *)&FalseUP1D_Type); + + if( PyType_Ready( &QuantitativeInvisibilityUP1D_Type ) < 0 ) + return -1; + Py_INCREF( &QuantitativeInvisibilityUP1D_Type ); + PyModule_AddObject(module, "QuantitativeInvisibilityUP1D", (PyObject *)&QuantitativeInvisibilityUP1D_Type); + + if( PyType_Ready( &ShapeUP1D_Type ) < 0 ) + return -1; + Py_INCREF( &ShapeUP1D_Type ); + PyModule_AddObject(module, "ShapeUP1D", (PyObject *)&ShapeUP1D_Type); + + if( PyType_Ready( &TrueUP1D_Type ) < 0 ) + return -1; + Py_INCREF( &TrueUP1D_Type ); + PyModule_AddObject(module, "TrueUP1D", (PyObject *)&TrueUP1D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryPredicate1D___init__(BPy_UnaryPredicate1D *self, PyObject *args, PyObject *kwds) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->up1D = new UnaryPredicate1D(); + self->up1D->py_up1D = (PyObject *) self; + return 0; +} + +void UnaryPredicate1D___dealloc__(BPy_UnaryPredicate1D* self) +{ + if (self->up1D) + delete self->up1D; + Py_TYPE(self)->tp_free((PyObject*)self); +} + + +PyObject * UnaryPredicate1D___repr__(BPy_UnaryPredicate1D* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->up1D->getName().c_str(), self->up1D ); +} + + +PyObject * UnaryPredicate1D_getName( BPy_UnaryPredicate1D *self, PyObject *args) +{ + return PyUnicode_FromFormat( self->up1D->getName().c_str() ); +} + +static PyObject * UnaryPredicate1D___call__( BPy_UnaryPredicate1D *self, PyObject *args, PyObject *kwds) +{ + PyObject *py_if1D; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!", &Interface1D_Type, &py_if1D) ) + return NULL; + + Interface1D *if1D = ((BPy_Interface1D *) py_if1D)->if1D; + + if( !if1D ) { + string msg(self->up1D->getName() + " has no Interface0DIterator"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + return NULL; + } + if( typeid(*(self->up1D)) == typeid(UnaryPredicate1D) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if( self->up1D->operator()(*if1D) < 0 ) { + if (!PyErr_Occurred()) { + string msg(self->up1D->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return PyBool_from_bool( self->up1D->result ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + + diff --git a/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h new file mode 100644 index 00000000000..f23b2e0d25f --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_UnaryPredicate1D.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYPREDICATE1D_H +#define FREESTYLE_PYTHON_UNARYPREDICATE1D_H + +#include "../stroke/Predicates1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryPredicate1D_Type; + +#define BPy_UnaryPredicate1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryPredicate1D_Type) ) + +/*---------------------------Python BPy_UnaryPredicate1D structure definition----------*/ +typedef struct { + PyObject_HEAD + UnaryPredicate1D *up1D; +} BPy_UnaryPredicate1D; + +/*---------------------------Python BPy_UnaryPredicate1D visible prototypes-----------*/ + +int UnaryPredicate1D_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYPREDICATE1D_H */ diff --git a/source/blender/freestyle/intern/python/BPy_ViewMap.cpp b/source/blender/freestyle/intern/python/BPy_ViewMap.cpp new file mode 100644 index 00000000000..19ba7469a24 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_ViewMap.cpp @@ -0,0 +1,157 @@ +#include "BPy_ViewMap.h" + +#include "BPy_Convert.h" +#include "BPy_BBox.h" +#include "Interface1D/BPy_FEdge.h" +#include "Interface1D/BPy_ViewEdge.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ViewMap instance -----------*/ +static int ViewMap___init__(BPy_ViewMap *self, PyObject *args, PyObject *kwds); +static void ViewMap___dealloc__(BPy_ViewMap *self); +static PyObject * ViewMap___repr__(BPy_ViewMap* self); + +static PyObject * ViewMap_getClosestViewEdge( BPy_ViewMap *self , PyObject *args); +static PyObject * ViewMap_getClosestFEdge( BPy_ViewMap *self , PyObject *args); +static PyObject * ViewMap_getScene3dBBox( BPy_ViewMap *self , PyObject *args); +static PyObject * ViewMap_setScene3dBBox( BPy_ViewMap *self , PyObject *args); + +/*---------------------- BPy_ViewShape instance definitions ----------------------------*/ +static PyMethodDef BPy_ViewMap_methods[] = { + {"getClosestViewEdge", ( PyCFunction ) ViewMap_getClosestViewEdge, METH_VARARGS, "(double x, double y) Gets the viewedge the nearest to the 2D position specified as argument "}, + {"getClosestFEdge", ( PyCFunction ) ViewMap_getClosestFEdge, METH_VARARGS, "(double x, double y) Gets the Fedge the nearest to the 2D position specified as argument "}, + {"getScene3dBBox", ( PyCFunction ) ViewMap_getScene3dBBox, METH_NOARGS, "() Returns the scene 3D bounding box. "}, + {"setScene3dBBox", ( PyCFunction ) ViewMap_setScene3dBBox, METH_VARARGS, "(BBox bb) Sets the scene 3D bounding box."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_ViewMap type definition ------------------------------*/ + +PyTypeObject ViewMap_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "ViewMap", /* tp_name */ + sizeof(BPy_ViewMap), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)ViewMap___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)ViewMap___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ViewMap objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_ViewMap_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ViewMap___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int ViewMap_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &ViewMap_Type ) < 0 ) + return -1; + + Py_INCREF( &ViewMap_Type ); + PyModule_AddObject(module, "ViewMap", (PyObject *)&ViewMap_Type); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int ViewMap___init__(BPy_ViewMap *self, PyObject *args, PyObject *kwds) +{ + self->vm = new ViewMap(); + return 0; +} + +void ViewMap___dealloc__(BPy_ViewMap *self) +{ + if( self->vm ) + delete self->vm; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyObject * ViewMap___repr__(BPy_ViewMap *self) +{ + return PyUnicode_FromFormat("ViewMap - address: %p", self->vm ); +} + +PyObject * ViewMap_getClosestViewEdge( BPy_ViewMap *self , PyObject *args) { + double x, y; + + if(!( PyArg_ParseTuple(args, "dd", &x, &y) )) + return NULL; + + ViewEdge *ve = const_cast<ViewEdge *>( self->vm->getClosestViewEdge(x,y) ); + if( ve ) + return BPy_ViewEdge_from_ViewEdge(*ve); + + Py_RETURN_NONE; +} + +PyObject * ViewMap_getClosestFEdge( BPy_ViewMap *self , PyObject *args) { + double x, y; + + if(!( PyArg_ParseTuple(args, "dd", &x, &y) )) + return NULL; + + FEdge *fe = const_cast<FEdge *>( self->vm->getClosestFEdge(x,y) ); + if( fe ) + return Any_BPy_FEdge_from_FEdge(*fe); + + Py_RETURN_NONE; +} + +PyObject * ViewMap_getScene3dBBox( BPy_ViewMap *self , PyObject *args) { + BBox<Vec3r> bb( self->vm->getScene3dBBox() ); + return BPy_BBox_from_BBox( bb ); +} + +PyObject * ViewMap_setScene3dBBox( BPy_ViewMap *self , PyObject *args) { + PyObject *py_bb = 0; + + if(!( PyArg_ParseTuple(args, "O!", &BBox_Type, &py_bb) )) + return NULL; + + self->vm->setScene3dBBox(*( ((BPy_BBox *) py_bb)->bb )); + + Py_RETURN_NONE; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_ViewMap.h b/source/blender/freestyle/intern/python/BPy_ViewMap.h new file mode 100644 index 00000000000..f1966e5c71e --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_ViewMap.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_VIEWMAP_H +#define FREESTYLE_PYTHON_VIEWMAP_H + +#include "../view_map/ViewMap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ViewMap_Type; + +#define BPy_ViewMap_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ViewMap_Type) ) + +/*---------------------------Python BPy_ViewMap structure definition----------*/ +typedef struct { + PyObject_HEAD + ViewMap *vm; +} BPy_ViewMap; + +/*---------------------------Python BPy_ViewMap visible prototypes-----------*/ + +int ViewMap_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_VIEWMAP_H */ diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp new file mode 100644 index 00000000000..46ac5e44d0d --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp @@ -0,0 +1,263 @@ +#include "BPy_ViewShape.h" + +#include "BPy_Convert.h" +#include "Interface0D/BPy_ViewVertex.h" +#include "Interface1D/BPy_ViewEdge.h" +#include "BPy_SShape.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ViewShape instance -----------*/ +static int ViewShape___init__(BPy_ViewShape *self, PyObject *args, PyObject *kwds); +static void ViewShape___dealloc__(BPy_ViewShape *self); +static PyObject * ViewShape___repr__(BPy_ViewShape* self); + +static PyObject * ViewShape_sshape( BPy_ViewShape *self ); +static PyObject * ViewShape_vertices( BPy_ViewShape *self ); +static PyObject * ViewShape_edges( BPy_ViewShape *self ); +static PyObject * ViewShape_getId( BPy_ViewShape *self ); +static PyObject * ViewShape_setSShape( BPy_ViewShape *self , PyObject *args); +static PyObject * ViewShape_setVertices( BPy_ViewShape *self , PyObject *args); +static PyObject * ViewShape_setEdges( BPy_ViewShape *self , PyObject *args); +static PyObject * ViewShape_AddEdge( BPy_ViewShape *self , PyObject *args); +static PyObject * ViewShape_AddVertex( BPy_ViewShape *self , PyObject *args); + +/*---------------------- BPy_ViewShape instance definitions ----------------------------*/ +static PyMethodDef BPy_ViewShape_methods[] = { + {"sshape", ( PyCFunction ) ViewShape_sshape, METH_NOARGS, "() Returns the SShape on top of which this ViewShape is built. "}, + {"vertices", ( PyCFunction ) ViewShape_vertices, METH_NOARGS, "() Returns the list of ViewVertex contained in this ViewShape."}, + {"edges", ( PyCFunction ) ViewShape_edges, METH_NOARGS, "() Returns the list of ViewEdge contained in this ViewShape. "}, + {"getId", ( PyCFunction ) ViewShape_getId, METH_NOARGS, "() Returns the ViewShape id. "}, + {"setSShape", ( PyCFunction ) ViewShape_setSShape, METH_VARARGS, "(SShape ss) Sets the SShape on top of which the ViewShape is built. "}, + {"setVertices", ( PyCFunction ) ViewShape_setVertices, METH_VARARGS, "([<ViewVertex>]) Sets the list of ViewVertex contained in this ViewShape."}, + {"setEdges", ( PyCFunction ) ViewShape_setEdges, METH_VARARGS, "([<ViewEdge>]) Sets the list of ViewEdge contained in this ViewShape."}, + {"AddEdge", ( PyCFunction ) ViewShape_AddEdge, METH_VARARGS, "(ViewEdge ve) Adds a ViewEdge to the list "}, + {"AddVertex", ( PyCFunction ) ViewShape_AddVertex, METH_VARARGS, "(ViewVertex ve) Adds a ViewVertex to the list. "}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_ViewShape type definition ------------------------------*/ + +PyTypeObject ViewShape_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "ViewShape", /* tp_name */ + sizeof(BPy_ViewShape), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)ViewShape___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)ViewShape___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ViewShape objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_ViewShape_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ViewShape___init__, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- +int ViewShape_Init( PyObject *module ) +{ + if( module == NULL ) + return -1; + + if( PyType_Ready( &ViewShape_Type ) < 0 ) + return -1; + + Py_INCREF( &ViewShape_Type ); + PyModule_AddObject(module, "ViewShape", (PyObject *)&ViewShape_Type); + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int ViewShape___init__(BPy_ViewShape *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if (! PyArg_ParseTuple(args, "|O", &obj) ) + return -1; + + if( !obj ) { + self->vs = new ViewShape(); + + } else if( BPy_SShape_Check(obj) ) { + self->vs = new ViewShape( ((BPy_SShape *) obj)->ss ); + + } else if( BPy_ViewShape_Check(obj) ) { + self->vs = new ViewShape(*( ((BPy_ViewShape *) obj)->vs )); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return -1; + } + self->borrowed = 0; + + return 0; +} + +void ViewShape___dealloc__(BPy_ViewShape *self) +{ + if( self->vs && !self->borrowed ) + delete self->vs; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +PyObject * ViewShape___repr__(BPy_ViewShape *self) +{ + return PyUnicode_FromFormat("ViewShape - address: %p", self->vs ); +} + +PyObject * ViewShape_sshape( BPy_ViewShape *self ) { + return BPy_SShape_from_SShape( *(self->vs->sshape()) ); +} + + +PyObject * ViewShape_vertices( BPy_ViewShape *self ) { + PyObject *py_vertices = PyList_New(0); + + vector< ViewVertex * > vertices = self->vs->vertices(); + vector< ViewVertex * >::iterator it; + + for( it = vertices.begin(); it != vertices.end(); it++ ) { + PyList_Append( py_vertices, Any_BPy_ViewVertex_from_ViewVertex(*( *it )) ); + } + + return py_vertices; +} + + +PyObject * ViewShape_edges( BPy_ViewShape *self ) { + PyObject *py_edges = PyList_New(0); + + vector< ViewEdge * > edges = self->vs->edges(); + vector< ViewEdge * >::iterator it; + + for( it = edges.begin(); it != edges.end(); it++ ) { + PyList_Append( py_edges, BPy_ViewEdge_from_ViewEdge(*( *it )) ); + } + + return py_edges; +} + +PyObject * ViewShape_getId( BPy_ViewShape *self ) { + Id id( self->vs->getId() ); + return BPy_Id_from_Id( id ); +} + +PyObject * ViewShape_setSShape( BPy_ViewShape *self , PyObject *args) { + PyObject *py_ss = 0; + + if(!( PyArg_ParseTuple(args, "O!", &SShape_Type, &py_ss) )) + return NULL; + + self->vs->setSShape( ((BPy_SShape *) py_ss)->ss ); + + Py_RETURN_NONE; +} + +PyObject * ViewShape_setVertices( BPy_ViewShape *self , PyObject *args) { + PyObject *list = 0; + PyObject *tmp; + + if(!( PyArg_ParseTuple(args, "O!", &PyList_Type, &list) )) + return NULL; + + vector< ViewVertex *> v; + + for( int i=0; i < PyList_Size(list); i++ ) { + tmp = PyList_GetItem(list, i); + if( BPy_ViewVertex_Check(tmp) ) + v.push_back( ((BPy_ViewVertex *) tmp)->vv ); + else { + PyErr_SetString(PyExc_TypeError, "argument must be list of ViewVertex objects"); + return NULL; + } + } + + self->vs->setVertices( v ); + + Py_RETURN_NONE; +} + +PyObject * ViewShape_setEdges( BPy_ViewShape *self , PyObject *args) { + PyObject *list = 0; + PyObject *tmp; + + if(!( PyArg_ParseTuple(args, "O!", &PyList_Type, &list) )) + return NULL; + + vector<ViewEdge *> v; + + for( int i=0; i < PyList_Size(list); i++ ) { + tmp = PyList_GetItem(list, i); + if( BPy_ViewEdge_Check(tmp) ) + v.push_back( ((BPy_ViewEdge *) tmp)->ve ); + else { + PyErr_SetString(PyExc_TypeError, "argument must be list of ViewEdge objects"); + return NULL; + } + } + + self->vs->setEdges( v ); + + Py_RETURN_NONE; +} + +PyObject * ViewShape_AddEdge( BPy_ViewShape *self , PyObject *args) { + PyObject *py_ve = 0; + + if(!( PyArg_ParseTuple(args, "O!", &ViewEdge_Type, &py_ve) )) + return NULL; + + self->vs->AddEdge( ((BPy_ViewEdge *) py_ve)->ve ); + + Py_RETURN_NONE; +} + +PyObject * ViewShape_AddVertex( BPy_ViewShape *self , PyObject *args) { + PyObject *py_vv = 0; + + if(!( PyArg_ParseTuple(args, "O!", &ViewVertex_Type, &py_vv) )) + return NULL; + + self->vs->AddVertex( ((BPy_ViewVertex *) py_vv)->vv ); + + Py_RETURN_NONE; +} + +// virtual ViewShape * dupplicate () + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.h b/source/blender/freestyle/intern/python/BPy_ViewShape.h new file mode 100644 index 00000000000..e88ab090b47 --- /dev/null +++ b/source/blender/freestyle/intern/python/BPy_ViewShape.h @@ -0,0 +1,35 @@ +#ifndef FREESTYLE_PYTHON_VIEWSHAPE_H +#define FREESTYLE_PYTHON_VIEWSHAPE_H + +#include "../view_map/ViewMap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ViewShape_Type; + +#define BPy_ViewShape_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ViewShape_Type) ) + +/*---------------------------Python BPy_ViewShape structure definition----------*/ +typedef struct { + PyObject_HEAD + ViewShape *vs; + int borrowed; /* non-zero if *vs a borrowed object */ +} BPy_ViewShape; + +/*---------------------------Python BPy_ViewShape visible prototypes-----------*/ + +int ViewShape_Init( PyObject *module ); + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_VIEWSHAPE_H */ diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp new file mode 100644 index 00000000000..6508776a5e3 --- /dev/null +++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp @@ -0,0 +1,68 @@ +#include "BPy_FalseBP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for FalseBP1D instance -----------*/ +static int FalseBP1D___init__(BPy_FalseBP1D* self, PyObject *args); + +/*-----------------------BPy_FalseBP1D type definition ------------------------------*/ +PyTypeObject FalseBP1D_Type = { + PyObject_HEAD_INIT(NULL) + "FalseBP1D", /* tp_name */ + sizeof(BPy_FalseBP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "FalseBP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &BinaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FalseBP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int FalseBP1D___init__( BPy_FalseBP1D* self, PyObject *args ) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_bp1D.bp1D = new Predicates1D::FalseBP1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h new file mode 100644 index 00000000000..a8d4aad88aa --- /dev/null +++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_FALSEBP1D_H +#define FREESTYLE_PYTHON_FALSEBP1D_H + +#include "../BPy_BinaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject FalseBP1D_Type; + +#define BPy_FalseBP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &FalseBP1D_Type) ) + +/*---------------------------Python BPy_FalseBP1D structure definition----------*/ +typedef struct { + BPy_BinaryPredicate1D py_bp1D; +} BPy_FalseBP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_FALSEBP1D_H */ diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp new file mode 100644 index 00000000000..97e8bc198e9 --- /dev/null +++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp @@ -0,0 +1,68 @@ +#include "BPy_Length2DBP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Length2DBP1D instance -----------*/ +static int Length2DBP1D___init__(BPy_Length2DBP1D* self, PyObject *args); + +/*-----------------------BPy_Length2DBP1D type definition ------------------------------*/ +PyTypeObject Length2DBP1D_Type = { + PyObject_HEAD_INIT(NULL) + "Length2DBP1D", /* tp_name */ + sizeof(BPy_Length2DBP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Length2DBP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &BinaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Length2DBP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int Length2DBP1D___init__( BPy_Length2DBP1D* self, PyObject *args ) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_bp1D.bp1D = new Predicates1D::Length2DBP1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h new file mode 100644 index 00000000000..d5bce5b150d --- /dev/null +++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_LENGTH2DBP1D_H +#define FREESTYLE_PYTHON_LENGTH2DBP1D_H + +#include "../BPy_BinaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Length2DBP1D_Type; + +#define BPy_Length2DBP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Length2DBP1D_Type) ) + +/*---------------------------Python BPy_Length2DBP1D structure definition----------*/ +typedef struct { + BPy_BinaryPredicate1D py_bp1D; +} BPy_Length2DBP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_LENGTH2DBP1D_H */ diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp new file mode 100644 index 00000000000..a39a7023c49 --- /dev/null +++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp @@ -0,0 +1,68 @@ +#include "BPy_SameShapeIdBP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for SameShapeIdBP1D instance -----------*/ +static int SameShapeIdBP1D___init__(BPy_SameShapeIdBP1D* self, PyObject *args); + +/*-----------------------BPy_SameShapeIdBP1D type definition ------------------------------*/ +PyTypeObject SameShapeIdBP1D_Type = { + PyObject_HEAD_INIT(NULL) + "SameShapeIdBP1D", /* tp_name */ + sizeof(BPy_SameShapeIdBP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "SameShapeIdBP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &BinaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)SameShapeIdBP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int SameShapeIdBP1D___init__( BPy_SameShapeIdBP1D* self, PyObject *args ) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_bp1D.bp1D = new Predicates1D::SameShapeIdBP1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h new file mode 100644 index 00000000000..71065d4ceeb --- /dev/null +++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_SAMESHAPEIDBP1D_H +#define FREESTYLE_PYTHON_SAMESHAPEIDBP1D_H + +#include "../BPy_BinaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject SameShapeIdBP1D_Type; + +#define BPy_SameShapeIdBP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &SameShapeIdBP1D_Type) ) + +/*---------------------------Python BPy_SameShapeIdBP1D structure definition----------*/ +typedef struct { + BPy_BinaryPredicate1D py_bp1D; +} BPy_SameShapeIdBP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_SAMESHAPEIDBP1D_H */ diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp new file mode 100644 index 00000000000..e2c355b1f48 --- /dev/null +++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp @@ -0,0 +1,68 @@ +#include "BPy_TrueBP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for TrueBP1D instance -----------*/ +static int TrueBP1D___init__( BPy_TrueBP1D* self, PyObject *args ); + +/*-----------------------BPy_TrueBP1D type definition ------------------------------*/ +PyTypeObject TrueBP1D_Type = { + PyObject_HEAD_INIT(NULL) + "TrueBP1D", /* tp_name */ + sizeof(BPy_TrueBP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "TrueBP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &BinaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)TrueBP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int TrueBP1D___init__( BPy_TrueBP1D* self, PyObject *args ) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_bp1D.bp1D = new Predicates1D::TrueBP1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h new file mode 100644 index 00000000000..7d809e1fe65 --- /dev/null +++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_TRUEBP1D_H +#define FREESTYLE_PYTHON_TRUEBP1D_H + +#include "../BPy_BinaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject TrueBP1D_Type; + +#define BPy_TrueBP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &TrueBP1D_Type) ) + +/*---------------------------Python BPy_TrueBP1D structure definition----------*/ +typedef struct { + BPy_BinaryPredicate1D py_bp1D; +} BPy_TrueBP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_TRUEBP1D_H */ diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp new file mode 100644 index 00000000000..51b8940ebeb --- /dev/null +++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp @@ -0,0 +1,79 @@ +#include "BPy_ViewMapGradientNormBP1D.h" + +#include "../BPy_Convert.h" +#include "../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ViewMapGradientNormBP1D instance -----------*/ +static int ViewMapGradientNormBP1D___init__(BPy_ViewMapGradientNormBP1D* self, PyObject *args ); + +/*-----------------------BPy_ViewMapGradientNormBP1D type definition ------------------------------*/ +PyTypeObject ViewMapGradientNormBP1D_Type = { + PyObject_HEAD_INIT(NULL) + "ViewMapGradientNormBP1D", /* tp_name */ + sizeof(BPy_ViewMapGradientNormBP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ViewMapGradientNormBP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &BinaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ViewMapGradientNormBP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +//ViewMapGradientNormBP1D(int level, IntegrationType iType=MEAN, float sampling=2.0) + +int ViewMapGradientNormBP1D___init__( BPy_ViewMapGradientNormBP1D* self, PyObject *args ) +{ + int i; + PyObject *obj; + float f = 2.0; + + if(!( PyArg_ParseTuple(args, "i|O!f", &i, &IntegrationType_Type, &obj, &f) )) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_bp1D.bp1D = new Predicates1D::ViewMapGradientNormBP1D(i,t,f); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h new file mode 100644 index 00000000000..23d27e118a9 --- /dev/null +++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_VIEWMAPGRADIENTNORMBP1D_H +#define FREESTYLE_PYTHON_VIEWMAPGRADIENTNORMBP1D_H + +#include "../BPy_BinaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ViewMapGradientNormBP1D_Type; + +#define BPy_ViewMapGradientNormBP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ViewMapGradientNormBP1D_Type) ) + +/*---------------------------Python BPy_ViewMapGradientNormBP1D structure definition----------*/ +typedef struct { + BPy_BinaryPredicate1D py_bp1D; +} BPy_ViewMapGradientNormBP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_VIEWMAPGRADIENTNORMBP1D_H */ diff --git a/source/blender/freestyle/intern/python/Director.cpp b/source/blender/freestyle/intern/python/Director.cpp new file mode 100644 index 00000000000..1948da2b6b0 --- /dev/null +++ b/source/blender/freestyle/intern/python/Director.cpp @@ -0,0 +1,304 @@ +#include "Director.h" + +#include "BPy_Convert.h" + +#include "BPy_BinaryPredicate0D.h" +#include "BPy_BinaryPredicate1D.h" +#include "BPy_FrsMaterial.h" +#include "BPy_Id.h" +#include "BPy_UnaryFunction0D.h" +#include "BPy_UnaryFunction1D.h" +#include "BPy_UnaryPredicate0D.h" +#include "BPy_UnaryPredicate1D.h" +#include "BPy_StrokeShader.h" +#include "Iterator/BPy_ChainingIterator.h" +#include "Iterator/BPy_Interface0DIterator.h" +#include "Interface1D/BPy_Stroke.h" +#include "Interface1D/BPy_ViewEdge.h" +#include "BPy_ViewShape.h" + +#include "UnaryFunction0D/BPy_UnaryFunction0DDouble.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DFloat.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DId.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DMaterial.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DVec2f.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DVec3f.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h" +#include "UnaryFunction0D/BPy_UnaryFunction0DViewShape.h" + +#include "UnaryFunction1D/BPy_UnaryFunction1DDouble.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DFloat.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DVec2f.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DVec3f.h" +#include "UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h" + + +// BinaryPredicate0D: __call__ +int Director_BPy_BinaryPredicate0D___call__( BinaryPredicate0D *bp0D, Interface0D& i1, Interface0D& i2 ) { + if (!bp0D->py_bp0D) { // internal error + PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_bp0D) not initialized"); + return -1; + } + PyObject *arg1 = Any_BPy_Interface0D_from_Interface0D(i1); + PyObject *arg2 = Any_BPy_Interface0D_from_Interface0D(i2); + if (!arg1 || !arg2) { + Py_XDECREF(arg1); + Py_XDECREF(arg2); + return -1; + } + PyObject *result = PyObject_CallMethod( bp0D->py_bp0D, "__call__", "OO", arg1, arg2 ); + Py_DECREF(arg1); + Py_DECREF(arg2); + if (!result) + return -1; + int ret = PyObject_IsTrue(result); + Py_DECREF(result); + if (ret < 0) + return -1; + bp0D->result = ret; + return 0; +} + + +// BinaryPredicate1D: __call__ +int Director_BPy_BinaryPredicate1D___call__( BinaryPredicate1D *bp1D, Interface1D& i1, Interface1D& i2 ) { + if (!bp1D->py_bp1D) { // internal error + PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_bp1D) not initialized"); + return -1; + } + PyObject *arg1 = Any_BPy_Interface1D_from_Interface1D(i1); + PyObject *arg2 = Any_BPy_Interface1D_from_Interface1D(i2); + if (!arg1 || !arg2) { + Py_XDECREF(arg1); + Py_XDECREF(arg2); + return -1; + } + PyObject *result = PyObject_CallMethod( bp1D->py_bp1D, "__call__", "OO", arg1, arg2 ); + Py_DECREF(arg1); + Py_DECREF(arg2); + if (!result) + return -1; + int ret = PyObject_IsTrue(result); + Py_DECREF(result); + if (ret < 0) + return -1; + bp1D->result = ret; + return 0; +} + + +// UnaryPredicate0D: __call__ +int Director_BPy_UnaryPredicate0D___call__( UnaryPredicate0D *up0D, Interface0DIterator& if0D_it ) { + if (!up0D->py_up0D) { // internal error + PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_up0D) not initialized"); + return -1; + } + PyObject *arg = BPy_Interface0DIterator_from_Interface0DIterator(if0D_it, 0); + if (!arg) + return -1; + PyObject *result = PyObject_CallMethod( up0D->py_up0D, "__call__", "O", arg ); + Py_DECREF(arg); + if (!result) + return -1; + int ret = PyObject_IsTrue(result); + Py_DECREF(result); + if (ret < 0) + return -1; + up0D->result = ret; + return 0; +} + + +// UnaryPredicate1D: __call__ +int Director_BPy_UnaryPredicate1D___call__( UnaryPredicate1D *up1D, Interface1D& if1D ) { + if (!up1D->py_up1D) { // internal error + PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_up1D) not initialized"); + return -1; + } + PyObject *arg = Any_BPy_Interface1D_from_Interface1D(if1D); + if (!arg) + return -1; + PyObject *result = PyObject_CallMethod( up1D->py_up1D, "__call__", "O", arg ); + Py_DECREF(arg); + if (!result) + return -1; + int ret = PyObject_IsTrue(result); + Py_DECREF(result); + if (ret < 0) + return -1; + up1D->result = ret; + return 0; +} + + +// StrokeShader: shade +int Director_BPy_StrokeShader_shade( StrokeShader *ss, Stroke& s ) { + if (!ss->py_ss) { // internal error + PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_ss) not initialized"); + return -1; + } + PyObject *arg = BPy_Stroke_from_Stroke(s); + if (!arg) + return -1; + PyObject *result = PyObject_CallMethod( ss->py_ss, "shade", "O", arg ); + Py_DECREF(arg); + if (!result) + return -1; + Py_DECREF(result); + return 0; +} + +// ChainingIterator: init, traverse +int Director_BPy_ChainingIterator_init( ChainingIterator *c_it ) { + if (!c_it->py_c_it) { // internal error + PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_c_it) not initialized"); + return -1; + } + PyObject *result = PyObject_CallMethod( c_it->py_c_it, "init", ""); + if (!result) + return -1; + Py_DECREF(result); + return 0; +} + +int Director_BPy_ChainingIterator_traverse( ChainingIterator *c_it, AdjacencyIterator& a_it ) { + if (!c_it->py_c_it) { // internal error + PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_c_it) not initialized"); + return -1; + } + PyObject *arg = BPy_AdjacencyIterator_from_AdjacencyIterator(a_it); + if (!arg) + return -1; + PyObject *result = PyObject_CallMethod( c_it->py_c_it, "traverse", "O", arg ); + Py_DECREF(arg); + if (!result) + return -1; + if (BPy_ViewEdge_Check(result)) { + c_it->result = ((BPy_ViewEdge *) result)->ve; + } else if (result == Py_None) { + c_it->result = NULL; + } else { + PyErr_SetString(PyExc_RuntimeError, "traverse method returned a wrong value"); + Py_DECREF(result); + return -1; + } + Py_DECREF(result); + return 0; +} + + +// BPy_UnaryFunction{0D,1D}: __call__ +int Director_BPy_UnaryFunction0D___call__( void *uf0D, PyObject *obj, Interface0DIterator& if0D_it) { + + if (!obj) { // internal error + PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_uf0D) not initialized"); + return -1; + } + PyObject *arg = BPy_Interface0DIterator_from_Interface0DIterator(if0D_it, 0); + if (!arg) + return -1; + PyObject *result = PyObject_CallMethod( obj, "__call__", "O", arg ); + Py_DECREF(arg); + if (!result) + return -1; + + if( BPy_UnaryFunction0DDouble_Check(obj) ) { + ((UnaryFunction0D<double> *) uf0D)->result = PyFloat_AsDouble(result); + + } else if ( BPy_UnaryFunction0DEdgeNature_Check(obj) ) { + ((UnaryFunction0D<Nature::EdgeNature> *) uf0D)->result = EdgeNature_from_BPy_Nature(result); + + } else if ( BPy_UnaryFunction0DFloat_Check(obj) ) { + ((UnaryFunction0D<float> *) uf0D)->result = PyFloat_AsDouble(result); + + } else if ( BPy_UnaryFunction0DId_Check(obj) ) { + ((UnaryFunction0D<Id> *) uf0D)->result = *( ((BPy_Id *) result)->id ); + + } else if ( BPy_UnaryFunction0DMaterial_Check(obj) ) { + ((UnaryFunction0D<FrsMaterial> *) uf0D)->result = *( ((BPy_FrsMaterial *) result)->m ); + + } else if ( BPy_UnaryFunction0DUnsigned_Check(obj) ) { + ((UnaryFunction0D<unsigned> *) uf0D)->result = PyLong_AsLong(result); + + } else if ( BPy_UnaryFunction0DVec2f_Check(obj) ) { + Vec2f *v = Vec2f_ptr_from_Vector( result ); + ((UnaryFunction0D<Vec2f> *) uf0D)->result = *v; + delete v; + + } else if ( BPy_UnaryFunction0DVec3f_Check(obj) ) { + Vec3f *v = Vec3f_ptr_from_Vector( result ); + ((UnaryFunction0D<Vec3f> *) uf0D)->result = *v; + delete v; + + } else if ( BPy_UnaryFunction0DVectorViewShape_Check(obj) ) { + vector<ViewShape*> vec; + for( int i = 0; i < PyList_Size(result); i++) { + ViewShape *b = ( (BPy_ViewShape *) PyList_GetItem(result, i) )->vs; + vec.push_back( b ); + } + + ((UnaryFunction0D< vector<ViewShape*> > *) uf0D)->result = vec; + + } else if ( BPy_UnaryFunction0DViewShape_Check(obj) ) { + ((UnaryFunction0D<ViewShape*> *) uf0D)->result = ((BPy_ViewShape *) result)->vs; + + } + + Py_DECREF(result); + return 0; +} + +int Director_BPy_UnaryFunction1D___call__( void *uf1D, PyObject *obj, Interface1D& if1D) { + + if (!obj) { // internal error + PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_uf1D) not initialized"); + return -1; + } + PyObject *arg = Any_BPy_Interface1D_from_Interface1D(if1D); + if (!arg) + return -1; + PyObject *result = PyObject_CallMethod( obj, "__call__", "O", arg ); + Py_DECREF(arg); + if (!result) + return -1; + + if( BPy_UnaryFunction1DDouble_Check(obj) ) { + ((UnaryFunction1D<double> *) uf1D)->result = PyFloat_AsDouble(result); + + } else if ( BPy_UnaryFunction1DEdgeNature_Check(obj) ) { + ((UnaryFunction1D<Nature::EdgeNature> *) uf1D)->result = EdgeNature_from_BPy_Nature(result); + + } else if ( BPy_UnaryFunction1DFloat_Check(obj) ) { + ((UnaryFunction1D<float> *) uf1D)->result = PyFloat_AsDouble(result); + + } else if ( BPy_UnaryFunction1DUnsigned_Check(obj) ) { + ((UnaryFunction1D<unsigned> *) uf1D)->result = PyLong_AsLong(result); + + } else if ( BPy_UnaryFunction1DVec2f_Check(obj) ) { + Vec2f *v = Vec2f_ptr_from_Vector( result ); + ((UnaryFunction1D<Vec2f> *) uf1D)->result = *v; + delete v; + + } else if ( BPy_UnaryFunction1DVec3f_Check(obj) ) { + Vec3f *v = Vec3f_ptr_from_Vector( result ); + ((UnaryFunction1D<Vec3f> *) uf1D)->result = *v; + delete v; + + } else if ( BPy_UnaryFunction1DVectorViewShape_Check(obj) ) { + vector<ViewShape*> vec; + for( int i = 1; i < PyList_Size(result); i++) { + ViewShape *b = ( (BPy_ViewShape *) PyList_GetItem(result, i) )->vs; + vec.push_back( b ); + } + + ((UnaryFunction1D< vector<ViewShape*> > *) uf1D)->result = vec; + + } + + Py_DECREF(result); + return 0; +} diff --git a/source/blender/freestyle/intern/python/Director.h b/source/blender/freestyle/intern/python/Director.h new file mode 100644 index 00000000000..667d4a65942 --- /dev/null +++ b/source/blender/freestyle/intern/python/Director.h @@ -0,0 +1,49 @@ +#ifndef FREESTYLE_PYTHON_DIRECTOR +# define FREESTYLE_PYTHON_DIRECTOR + +class UnaryPredicate0D; +class UnaryPredicate1D; +class BinaryPredicate0D; +class BinaryPredicate1D; +class ChainingIterator; +class AdjacencyIterator; +class Interface0D; +class Interface1D; +class Interface0DIterator; +class Stroke; +class StrokeShader; + +#ifdef __cplusplus +extern "C" { +#endif + +#include <Python.h> + +#ifdef __cplusplus +} +#endif + +// BinaryPredicate0D: __call__ +int Director_BPy_BinaryPredicate0D___call__( BinaryPredicate0D *bp0D, Interface0D& i1, Interface0D& i2 ); + +// BinaryPredicate1D: __call__ +int Director_BPy_BinaryPredicate1D___call__( BinaryPredicate1D *bp1D, Interface1D& i1, Interface1D& i2 ); + +// UnaryFunction{0D,1D}: __call__ +int Director_BPy_UnaryFunction0D___call__( void *uf0D, PyObject *obj, Interface0DIterator& if0D_it); +int Director_BPy_UnaryFunction1D___call__( void *uf1D, PyObject *obj, Interface1D& if1D); + +// UnaryPredicate0D: __call__ +int Director_BPy_UnaryPredicate0D___call__( UnaryPredicate0D *up0D, Interface0DIterator& if0D_it ); + +// UnaryPredicate1D: __call__ +int Director_BPy_UnaryPredicate1D___call__( UnaryPredicate1D *up1D, Interface1D& if1D ); + +// StrokeShader: shade +int Director_BPy_StrokeShader_shade( StrokeShader *ss, Stroke& s ); + +// ChainingIterator: init, traverse +int Director_BPy_ChainingIterator_init( ChainingIterator *c_it ); +int Director_BPy_ChainingIterator_traverse( ChainingIterator *c_it, AdjacencyIterator& a_it ); + +#endif // FREESTYLE_PYTHON_DIRECTOR diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp new file mode 100644 index 00000000000..86baa4727cf --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp @@ -0,0 +1,202 @@ +#include "BPy_CurvePoint.h" + +#include "../BPy_Convert.h" +#include "../Interface0D/BPy_SVertex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for CurvePoint instance -----------*/ +static int CurvePoint___init__(BPy_CurvePoint *self, PyObject *args, PyObject *kwds); +static PyObject * CurvePoint___copy__( BPy_CurvePoint *self ); +static PyObject * CurvePoint_A( BPy_CurvePoint *self ); +static PyObject * CurvePoint_B( BPy_CurvePoint *self ); +static PyObject * CurvePoint_t2d( BPy_CurvePoint *self ); +static PyObject *CurvePoint_setA( BPy_CurvePoint *self , PyObject *args); +static PyObject *CurvePoint_setB( BPy_CurvePoint *self , PyObject *args); +static PyObject *CurvePoint_setT2d( BPy_CurvePoint *self , PyObject *args); +static PyObject *CurvePoint_curvatureFredo( BPy_CurvePoint *self , PyObject *args); + +/*----------------------CurvePoint instance definitions ----------------------------*/ +static PyMethodDef BPy_CurvePoint_methods[] = { + {"__copy__", ( PyCFunction ) CurvePoint___copy__, METH_NOARGS, "() Cloning method."}, + {"A", ( PyCFunction ) CurvePoint_A, METH_NOARGS, "() Returns the first SVertex upon which the CurvePoint is built."}, + {"B", ( PyCFunction ) CurvePoint_B, METH_NOARGS, "() Returns the second SVertex upon which the CurvePoint is built."}, + {"t2d", ( PyCFunction ) CurvePoint_t2d, METH_NOARGS, "() Returns the interpolation parameter."}, + {"setA", ( PyCFunction ) CurvePoint_setA, METH_VARARGS, "(SVertex sv) Sets the first SVertex upon which to build the CurvePoint."}, + {"setB", ( PyCFunction ) CurvePoint_setB, METH_VARARGS, "(SVertex sv) Sets the second SVertex upon which to build the CurvePoint."}, + {"setT2d", ( PyCFunction ) CurvePoint_setT2d, METH_VARARGS, "() Sets the 2D interpolation parameter to use."}, + {"curvatureFredo", ( PyCFunction ) CurvePoint_curvatureFredo, METH_NOARGS, "() angle in radians."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_CurvePoint type definition ------------------------------*/ + +PyTypeObject CurvePoint_Type = { + PyObject_HEAD_INIT(NULL) + "CurvePoint", /* tp_name */ + sizeof(BPy_CurvePoint), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "CurvePoint objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_CurvePoint_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Interface0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)CurvePoint___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int CurvePoint___init__(BPy_CurvePoint *self, PyObject *args, PyObject *kwds) +{ + + PyObject *obj1 = 0, *obj2 = 0 , *obj3 = 0; + + if (! PyArg_ParseTuple(args, "|OOO!", &obj1, &obj2, &PyFloat_Type, &obj3) ) + return -1; + + if( !obj1 ){ + self->cp = new CurvePoint(); + + } else if( !obj2 && BPy_CurvePoint_Check(obj1) ) { + self->cp = new CurvePoint( *(((BPy_CurvePoint *) obj1)->cp) ); + + } else if( obj3 && BPy_SVertex_Check(obj1) && BPy_SVertex_Check(obj2) ) { + self->cp = new CurvePoint( ((BPy_SVertex *) obj1)->sv, + ((BPy_SVertex *) obj2)->sv, + PyFloat_AsDouble( obj3 ) ); + + } else if( obj3 && BPy_CurvePoint_Check(obj1) && BPy_CurvePoint_Check(obj2) ) { + CurvePoint *cp1 = ((BPy_CurvePoint *) obj1)->cp; + CurvePoint *cp2 = ((BPy_CurvePoint *) obj2)->cp; + if( !cp1 || cp1->A() == 0 || cp1->B() == 0 ) { + PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid CurvePoint object"); + return -1; + } + if( !cp2 || cp2->A() == 0 || cp2->B() == 0 ) { + PyErr_SetString(PyExc_TypeError, "argument 2 is an invalid CurvePoint object"); + return -1; + } + self->cp = new CurvePoint( cp1, cp2, PyFloat_AsDouble( obj3 ) ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument(s)"); + return -1; + } + + self->py_if0D.if0D = self->cp; + self->py_if0D.borrowed = 0; + + return 0; +} + +PyObject * CurvePoint___copy__( BPy_CurvePoint *self ) { + BPy_CurvePoint *py_cp; + + py_cp = (BPy_CurvePoint *) CurvePoint_Type.tp_new( &CurvePoint_Type, 0, 0 ); + + py_cp->cp = new CurvePoint( *(self->cp) ); + py_cp->py_if0D.if0D = py_cp->cp; + py_cp->py_if0D.borrowed = 0; + + return (PyObject *) py_cp; +} + +PyObject * CurvePoint_A( BPy_CurvePoint *self ) { + SVertex *A = self->cp->A(); + if( A ) + return BPy_SVertex_from_SVertex( *A ); + + Py_RETURN_NONE; +} + +PyObject * CurvePoint_B( BPy_CurvePoint *self ) { + SVertex *B = self->cp->B(); + if( B ) + return BPy_SVertex_from_SVertex( *B ); + + Py_RETURN_NONE; +} + +PyObject * CurvePoint_t2d( BPy_CurvePoint *self ) { + return PyFloat_FromDouble( self->cp->t2d() ); +} + +PyObject *CurvePoint_setA( BPy_CurvePoint *self , PyObject *args) { + PyObject *py_sv; + + if(!( PyArg_ParseTuple(args, "O!", &SVertex_Type, &py_sv) )) + return NULL; + + self->cp->setA( ((BPy_SVertex *) py_sv)->sv ); + + Py_RETURN_NONE; +} + +PyObject *CurvePoint_setB( BPy_CurvePoint *self , PyObject *args) { + PyObject *py_sv; + + if(!( PyArg_ParseTuple(args, "O!", &SVertex_Type, &py_sv) )) + return NULL; + + self->cp->setB( ((BPy_SVertex *) py_sv)->sv ); + + Py_RETURN_NONE; +} + +PyObject *CurvePoint_setT2d( BPy_CurvePoint *self , PyObject *args) { + float t; + + if(!( PyArg_ParseTuple(args, "f", &t) )) + return NULL; + + self->cp->setT2d( t ); + + Py_RETURN_NONE; +} + +PyObject *CurvePoint_curvatureFredo( BPy_CurvePoint *self , PyObject *args) { + return PyFloat_FromDouble( self->cp->curvatureFredo() ); +} + +///bool operator== (const CurvePoint &b) + + + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h new file mode 100644 index 00000000000..b4c22645503 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_CURVEPOINT_H +#define FREESTYLE_PYTHON_CURVEPOINT_H + +#include "../BPy_Interface0D.h" +#include "../../stroke/Curve.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject CurvePoint_Type; + +#define BPy_CurvePoint_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &CurvePoint_Type) ) + +/*---------------------------Python BPy_CurvePoint structure definition----------*/ +typedef struct { + BPy_Interface0D py_if0D; + CurvePoint *cp; +} BPy_CurvePoint; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CURVEPOINT_H */ diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp new file mode 100644 index 00000000000..dd204925936 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp @@ -0,0 +1,239 @@ +#include "BPy_SVertex.h" + +#include "../BPy_Convert.h" +#include "../BPy_Id.h" +#include "../Interface1D/BPy_FEdge.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for SVertex instance -----------*/ +static int SVertex___init__(BPy_SVertex *self, PyObject *args, PyObject *kwds); +static PyObject * SVertex___copy__( BPy_SVertex *self ); +static PyObject * SVertex_normals( BPy_SVertex *self ); +static PyObject * SVertex_normalsSize( BPy_SVertex *self ); +static PyObject * SVertex_viewvertex( BPy_SVertex *self ); +static PyObject * SVertex_setPoint3D( BPy_SVertex *self , PyObject *args); +static PyObject * SVertex_setPoint2D( BPy_SVertex *self , PyObject *args); +static PyObject * SVertex_AddNormal( BPy_SVertex *self , PyObject *args); +static PyObject * SVertex_setId( BPy_SVertex *self , PyObject *args); +static PyObject *SVertex_AddFEdge( BPy_SVertex *self , PyObject *args); + +/*----------------------SVertex instance definitions ----------------------------*/ +static PyMethodDef BPy_SVertex_methods[] = { + {"__copy__", ( PyCFunction ) SVertex___copy__, METH_NOARGS, "() Cloning method."}, + {"normals", ( PyCFunction ) SVertex_normals, METH_NOARGS, "Returns the normals for this Vertex as a list. In a smooth surface, a vertex has exactly one normal. In a sharp surface, a vertex can have any number of normals."}, + {"normalsSize", ( PyCFunction ) SVertex_normalsSize, METH_NOARGS, "Returns the number of different normals for this vertex." }, + {"viewvertex", ( PyCFunction ) SVertex_viewvertex, METH_NOARGS, "If this SVertex is also a ViewVertex, this method returns a pointer onto this ViewVertex. 0 is returned otherwise." }, + {"setPoint3D", ( PyCFunction ) SVertex_setPoint3D, METH_VARARGS, "Sets the 3D coordinates of the SVertex." }, + {"setPoint2D", ( PyCFunction ) SVertex_setPoint2D, METH_VARARGS, "Sets the 3D projected coordinates of the SVertex." }, + {"AddNormal", ( PyCFunction ) SVertex_AddNormal, METH_VARARGS, "Adds a normal to the Svertex's set of normals. If the same normal is already in the set, nothing changes." }, + {"setId", ( PyCFunction ) SVertex_setId, METH_VARARGS, "Sets the Id." }, + {"AddFEdge", ( PyCFunction ) SVertex_AddFEdge, METH_VARARGS, "Add an FEdge to the list of edges emanating from this SVertex." }, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_SVertex type definition ------------------------------*/ + +PyTypeObject SVertex_Type = { + PyObject_HEAD_INIT(NULL) + "SVertex", /* tp_name */ + sizeof(BPy_SVertex), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "SVertex objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_SVertex_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Interface0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)SVertex___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int SVertex___init__(BPy_SVertex *self, PyObject *args, PyObject *kwds) +{ + PyObject *py_point = 0; + BPy_Id *py_id = 0; + + + if (! PyArg_ParseTuple(args, "|OO!", &py_point, &Id_Type, &py_id) ) + return -1; + + if( !py_point ) { + self->sv = new SVertex(); + + } else if( !py_id && BPy_SVertex_Check(py_point) ) { + self->sv = new SVertex( *(((BPy_SVertex *)py_point)->sv) ); + + } else if( py_point && py_id ) { + Vec3r *v = Vec3r_ptr_from_PyObject(py_point); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); + return -1; + } + self->sv = new SVertex( *v, *(py_id->id) ); + delete v; + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument(s)"); + return -1; + } + + self->py_if0D.if0D = self->sv; + self->py_if0D.borrowed = 0; + + return 0; +} + +PyObject * SVertex___copy__( BPy_SVertex *self ) { + BPy_SVertex *py_svertex; + + py_svertex = (BPy_SVertex *) SVertex_Type.tp_new( &SVertex_Type, 0, 0 ); + + py_svertex->sv = self->sv->duplicate(); + py_svertex->py_if0D.if0D = py_svertex->sv; + py_svertex->py_if0D.borrowed = 0; + + return (PyObject *) py_svertex; +} + + +PyObject * SVertex_normals( BPy_SVertex *self ) { + PyObject *py_normals; + set< Vec3r > normals; + + py_normals = PyList_New(0); + normals = self->sv->normals(); + + for( set< Vec3r >::iterator set_iterator = normals.begin(); set_iterator != normals.end(); set_iterator++ ) { + Vec3r v( *set_iterator ); + PyList_Append( py_normals, Vector_from_Vec3r(v) ); + } + + return py_normals; +} + +PyObject * SVertex_normalsSize( BPy_SVertex *self ) { + return PyLong_FromLong( self->sv->normalsSize() ); +} + +PyObject * SVertex_viewvertex( BPy_SVertex *self ) { + ViewVertex *vv = self->sv->viewvertex(); + if( vv ) + return Any_BPy_ViewVertex_from_ViewVertex( *vv ); + + Py_RETURN_NONE; +} + +PyObject *SVertex_setPoint3D( BPy_SVertex *self , PyObject *args) { + PyObject *py_point; + + if(!( PyArg_ParseTuple(args, "O", &py_point) )) + return NULL; + Vec3r *v = Vec3r_ptr_from_PyObject(py_point); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); + return NULL; + } + self->sv->setPoint3D( *v ); + delete v; + + Py_RETURN_NONE; +} + +PyObject *SVertex_setPoint2D( BPy_SVertex *self , PyObject *args) { + PyObject *py_point; + + if(!( PyArg_ParseTuple(args, "O", &py_point) )) + return NULL; + Vec3r *v = Vec3r_ptr_from_PyObject(py_point); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); + return NULL; + } + self->sv->setPoint2D( *v ); + delete v; + + Py_RETURN_NONE; +} + +PyObject *SVertex_AddNormal( BPy_SVertex *self , PyObject *args) { + PyObject *py_normal; + + if(!( PyArg_ParseTuple(args, "O", &py_normal) )) + return NULL; + Vec3r *n = Vec3r_ptr_from_PyObject(py_normal); + if( !n ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); + return NULL; + } + self->sv->AddNormal( *n ); + delete n; + + Py_RETURN_NONE; +} + +PyObject *SVertex_setId( BPy_SVertex *self , PyObject *args) { + BPy_Id *py_id; + + if( !PyArg_ParseTuple(args, "O!", &Id_Type, &py_id) ) + return NULL; + + self->sv->setId( *(py_id->id) ); + + Py_RETURN_NONE; +} + +PyObject *SVertex_AddFEdge( BPy_SVertex *self , PyObject *args) { + PyObject *py_fe; + + if(!( PyArg_ParseTuple(args, "O!", &FEdge_Type, &py_fe) )) + return NULL; + + self->sv->AddFEdge( ((BPy_FEdge *) py_fe)->fe ); + + Py_RETURN_NONE; +} + + +// virtual bool operator== (const SVertex &iBrother) +// ViewVertex * viewvertex () + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h new file mode 100644 index 00000000000..7d310f2b7dc --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.h @@ -0,0 +1,32 @@ +#ifndef FREESTYLE_PYTHON_SVERTEX_H +#define FREESTYLE_PYTHON_SVERTEX_H + +#include "../../view_map/Silhouette.h" +#include "../BPy_Interface0D.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject SVertex_Type; + +#define BPy_SVertex_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &SVertex_Type) ) + +/*---------------------------Python BPy_SVertex structure definition----------*/ +typedef struct { + BPy_Interface0D py_if0D; + SVertex *sv; +} BPy_SVertex; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_SVERTEX_H */ diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp new file mode 100644 index 00000000000..3dcd7f55bbf --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.cpp @@ -0,0 +1,143 @@ +#include "BPy_ViewVertex.h" + +#include "../BPy_Convert.h" +#include "../Interface1D/BPy_ViewEdge.h" +#include "../BPy_Nature.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ViewVertex instance -----------*/ +static int ViewVertex___init__( BPy_ViewVertex *self, PyObject *args, PyObject *kwds ); +static PyObject * ViewVertex_setNature( BPy_ViewVertex *self, PyObject *args ); +static PyObject * ViewVertex_edgesBegin( BPy_ViewVertex *self ); +static PyObject * ViewVertex_edgesEnd( BPy_ViewVertex *self ); +static PyObject * ViewVertex_edgesIterator( BPy_ViewVertex *self, PyObject *args ); + +/*----------------------ViewVertex instance definitions ----------------------------*/ +static PyMethodDef BPy_ViewVertex_methods[] = { + {"setNature", ( PyCFunction ) ViewVertex_setNature, METH_VARARGS, "(Nature n) Sets the nature of the vertex."}, + {"edgesBegin", ( PyCFunction ) ViewVertex_edgesBegin, METH_NOARGS, "() Returns an iterator over the ViewEdges that goes to or comes from this ViewVertex pointing to the first ViewEdge of the list. The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges and to get the orientation for each ViewEdge (incoming/outgoing). "}, + {"edgesEnd", ( PyCFunction ) ViewVertex_edgesEnd, METH_NOARGS, "() Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, pointing after the last ViewEdge."}, + {"edgesIterator", ( PyCFunction ) ViewVertex_edgesIterator, METH_VARARGS, "(ViewEdge ve) Returns an orientedViewEdgeIterator pointing to the ViewEdge given as argument. "}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_ViewVertex type definition ------------------------------*/ + +PyTypeObject ViewVertex_Type = { + PyObject_HEAD_INIT(NULL) + "ViewVertex", /* tp_name */ + sizeof(BPy_ViewVertex), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ViewVertex objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_ViewVertex_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Interface0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ViewVertex___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ViewVertex___init__( BPy_ViewVertex *self, PyObject *args, PyObject *kwds ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->vv = 0; // ViewVertex is abstract + self->py_if0D.if0D = self->vv; + self->py_if0D.borrowed = 0; + return 0; +} + + + +PyObject * ViewVertex_setNature( BPy_ViewVertex *self, PyObject *args ) { + PyObject *py_n; + + if( !self->vv ) + Py_RETURN_NONE; + + if(!( PyArg_ParseTuple(args, "O!", &Nature_Type, &py_n) )) + return NULL; + + PyObject *i = (PyObject *) &( ((BPy_Nature *) py_n)->i ); + ((ViewVertex *) self->py_if0D.if0D)->setNature( PyLong_AsLong(i) ); + + Py_RETURN_NONE; +} + +PyObject * ViewVertex_edgesBegin( BPy_ViewVertex *self ) { + if( !self->vv ) + Py_RETURN_NONE; + + ViewVertexInternal::orientedViewEdgeIterator ove_it( self->vv->edgesBegin() ); + return BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator( ove_it, 0 ); +} + +PyObject * ViewVertex_edgesEnd( BPy_ViewVertex *self ) { +#if 0 + if( !self->vv ) + Py_RETURN_NONE; + + ViewVertexInternal::orientedViewEdgeIterator ove_it( self->vv->edgesEnd() ); + return BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator( ove_it, 1 ); +#else + PyErr_SetString(PyExc_NotImplementedError, "edgesEnd method currently disabled"); + return NULL; +#endif +} + + +PyObject * ViewVertex_edgesIterator( BPy_ViewVertex *self, PyObject *args ) { + PyObject *py_ve; + + if( !self->vv ) + Py_RETURN_NONE; + + if(!( PyArg_ParseTuple(args, "O!", &ViewEdge_Type, &py_ve) )) + return NULL; + + ViewEdge *ve = ((BPy_ViewEdge *) py_ve)->ve; + ViewVertexInternal::orientedViewEdgeIterator ove_it( self->vv->edgesIterator( ve ) ); + return BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator( ove_it, 0 ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h new file mode 100644 index 00000000000..26c06b50d71 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/BPy_ViewVertex.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_VIEWVERTEX_H +#define FREESTYLE_PYTHON_VIEWVERTEX_H + +#include "../../view_map/ViewMap.h" +#include "../BPy_Interface0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ViewVertex_Type; + +#define BPy_ViewVertex_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ViewVertex_Type) ) + +/*---------------------------Python BPy_ViewVertex structure definition----------*/ +typedef struct { + BPy_Interface0D py_if0D; + ViewVertex *vv; +} BPy_ViewVertex; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_VIEWVERTEX_H */ diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp new file mode 100644 index 00000000000..b4480aa7e67 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp @@ -0,0 +1,257 @@ +#include "BPy_StrokeVertex.h" + +#include "../../BPy_Convert.h" +#include "../../BPy_StrokeAttribute.h" +#include "../../Interface0D/BPy_SVertex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for StrokeVertex instance -----------*/ +static int StrokeVertex___init__(BPy_StrokeVertex *self, PyObject *args, PyObject *kwds); + +static PyObject * StrokeVertex_x( BPy_StrokeVertex *self ); +static PyObject * StrokeVertex_y( BPy_StrokeVertex *self ); +static PyObject * StrokeVertex_getPoint( BPy_StrokeVertex *self ); +static PyObject * StrokeVertex_attribute( BPy_StrokeVertex *self ); +static PyObject * StrokeVertex_curvilinearAbscissa( BPy_StrokeVertex *self ); +static PyObject * StrokeVertex_strokeLength( BPy_StrokeVertex *self ); +static PyObject * StrokeVertex_u( BPy_StrokeVertex *self ); +static PyObject * StrokeVertex_setX( BPy_StrokeVertex *self , PyObject *args); +static PyObject * StrokeVertex_setY( BPy_StrokeVertex *self , PyObject *args); +static PyObject * StrokeVertex_setPoint( BPy_StrokeVertex *self , PyObject *args); +static PyObject * StrokeVertex_setAttribute( BPy_StrokeVertex *self , PyObject *args); +static PyObject * StrokeVertex_setCurvilinearAbscissa( BPy_StrokeVertex *self , PyObject *args); +static PyObject * StrokeVertex_setStrokeLength( BPy_StrokeVertex *self , PyObject *args); + +/*----------------------StrokeVertex instance definitions ----------------------------*/ +static PyMethodDef BPy_StrokeVertex_methods[] = { +// {"__copy__", ( PyCFunction ) StrokeVertex___copy__, METH_NOARGS, "() Cloning method."}, + {"x", ( PyCFunction ) StrokeVertex_x, METH_NOARGS, "() Returns the 2D point x coordinate"}, + {"y", ( PyCFunction ) StrokeVertex_y, METH_NOARGS, "() Returns the 2D point y coordinate"}, + {"getPoint", ( PyCFunction ) StrokeVertex_getPoint, METH_NOARGS, "() Returns the 2D point coordinates as a Vec2d"}, + {"attribute", ( PyCFunction ) StrokeVertex_attribute, METH_NOARGS, "() Returns the StrokeAttribute of this StrokeVertex"}, + {"curvilinearAbscissa", ( PyCFunction ) StrokeVertex_curvilinearAbscissa, METH_NOARGS, "() Returns the curvilinear abscissa "}, + {"strokeLength", ( PyCFunction ) StrokeVertex_strokeLength, METH_NOARGS, "() Returns the length of the Stroke to which this StrokeVertex belongs"}, + {"u", ( PyCFunction ) StrokeVertex_u, METH_NOARGS, "() Returns the curvilinear abscissa of this StrokeVertex in the Stroke"}, + {"setX", ( PyCFunction ) StrokeVertex_setX, METH_VARARGS, "(double r) Sets the 2D x value "}, + {"setY", ( PyCFunction ) StrokeVertex_setY, METH_VARARGS, "(double r) Sets the 2D y value "}, + {"setPoint", ( PyCFunction ) StrokeVertex_setPoint, METH_VARARGS, "(double x, double y) / ( [x,y] ) Sets the 2D x and y values"}, + {"setAttribute", ( PyCFunction ) StrokeVertex_setAttribute, METH_VARARGS, "(StrokeAttribute sa) Sets the attribute."}, + {"setCurvilinearAbscissa", ( PyCFunction ) StrokeVertex_setCurvilinearAbscissa, METH_VARARGS, "(double r) Sets the curvilinear abscissa of this StrokeVertex in the Stroke"}, + {"setStrokeLength", ( PyCFunction ) StrokeVertex_setStrokeLength, METH_VARARGS, "(double r) Sets the Stroke's length (it's only a value stored by the Stroke Vertex, it won't change the real Stroke's length.) "}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_StrokeVertex type definition ------------------------------*/ + +PyTypeObject StrokeVertex_Type = { + PyObject_HEAD_INIT(NULL) + "StrokeVertex", /* tp_name */ + sizeof(BPy_StrokeVertex), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "StrokeVertex objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_StrokeVertex_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &CurvePoint_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)StrokeVertex___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int StrokeVertex___init__(BPy_StrokeVertex *self, PyObject *args, PyObject *kwds) +{ + + PyObject *obj1 = 0, *obj2 = 0 , *obj3 = 0; + + if (! PyArg_ParseTuple(args, "|OOO!", &obj1, &obj2, &PyFloat_Type, &obj3) ) + return -1; + + if( !obj1 ){ + self->sv = new StrokeVertex(); + + } else if( !obj2 && BPy_StrokeVertex_Check(obj1) && ((BPy_StrokeVertex *) obj1)->sv ) { + self->sv = new StrokeVertex( *(((BPy_StrokeVertex *) obj1)->sv) ); + + } else if( !obj2 && BPy_CurvePoint_Check(obj1) && ((BPy_CurvePoint *) obj1)->cp ) { + self->sv = new StrokeVertex( ((BPy_CurvePoint *) obj1)->cp ); + + } else if( !obj2 && BPy_SVertex_Check(obj1) && ((BPy_SVertex *) obj1)->sv ) { + self->sv = new StrokeVertex( ((BPy_SVertex *) obj1)->sv ); + + } else if( obj3 && BPy_StrokeVertex_Check(obj1) && BPy_StrokeVertex_Check(obj2) ) { + StrokeVertex *sv1 = ((BPy_StrokeVertex *) obj1)->sv; + StrokeVertex *sv2 = ((BPy_StrokeVertex *) obj2)->sv; + if( !sv1 || ( sv1->A() == 0 && sv1->B() == 0 ) ) { + PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid StrokeVertex object"); + return -1; + } + if( !sv2 || ( sv2->A() == 0 && sv2->B() == 0 ) ) { + PyErr_SetString(PyExc_TypeError, "argument 2 is an invalid StrokeVertex object"); + return -1; + } + self->sv = new StrokeVertex( sv1, sv2, PyFloat_AsDouble( obj3 ) ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument(s)"); + return -1; + } + + self->py_cp.cp = self->sv; + self->py_cp.py_if0D.if0D = self->sv; + self->py_cp.py_if0D.borrowed = 0; + + return 0; +} + +PyObject * StrokeVertex_x( BPy_StrokeVertex *self ) { + return PyFloat_FromDouble( self->sv->x() ); +} + +PyObject * StrokeVertex_y( BPy_StrokeVertex *self ) { + return PyFloat_FromDouble( self->sv->y() ); +} + +PyObject * StrokeVertex_getPoint( BPy_StrokeVertex *self ) { + Vec2f v( self->sv->getPoint() ); + return Vector_from_Vec2f( v ); +} + +PyObject * StrokeVertex_attribute( BPy_StrokeVertex *self ) { + return BPy_StrokeAttribute_from_StrokeAttribute( self->sv->attribute() ); +} + +PyObject * StrokeVertex_curvilinearAbscissa( BPy_StrokeVertex *self ) { + return PyFloat_FromDouble( self->sv->curvilinearAbscissa() ); +} + +PyObject * StrokeVertex_strokeLength( BPy_StrokeVertex *self ) { + return PyFloat_FromDouble( self->sv->strokeLength() ); +} + +PyObject * StrokeVertex_u( BPy_StrokeVertex *self ) { + return PyFloat_FromDouble( self->sv->u() ); +} + + +PyObject *StrokeVertex_setX( BPy_StrokeVertex *self , PyObject *args) { + double r; + + if(!( PyArg_ParseTuple(args, "d", &r) )) + return NULL; + + self->sv->setX( r ); + + Py_RETURN_NONE; +} + +PyObject *StrokeVertex_setY( BPy_StrokeVertex *self , PyObject *args) { + double r; + + if(!( PyArg_ParseTuple(args, "d", &r) )) + return NULL; + + self->sv->setY( r ); + + Py_RETURN_NONE; +} + + +PyObject *StrokeVertex_setPoint( BPy_StrokeVertex *self , PyObject *args) { + PyObject *obj1 = 0, *obj2 = 0; + + if(!( PyArg_ParseTuple(args, "O|O", &obj1, &obj2) )) + return NULL; + + if( obj1 && !obj2 ){ + Vec2f *v = Vec2f_ptr_from_PyObject(obj1); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 2D vector (either a list of 2 elements or Vector)"); + return NULL; + } + self->sv->setPoint( *v ); + delete v; + } else if( PyFloat_Check(obj1) && obj2 && PyFloat_Check(obj2) ){ + self->sv->setPoint( PyFloat_AsDouble(obj1), PyFloat_AsDouble(obj2) ); + } else { + PyErr_SetString(PyExc_TypeError, "invalid arguments"); + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject *StrokeVertex_setAttribute( BPy_StrokeVertex *self , PyObject *args) { + PyObject *py_sa; + + if(!( PyArg_ParseTuple(args, "O!", &StrokeAttribute_Type, &py_sa) )) + return NULL; + + self->sv->setAttribute(*( ((BPy_StrokeAttribute *) py_sa)->sa )); + + Py_RETURN_NONE; +} + +PyObject *StrokeVertex_setCurvilinearAbscissa( BPy_StrokeVertex *self , PyObject *args) { + double r; + + if(!( PyArg_ParseTuple(args, "d", &r) )) + return NULL; + + self->sv->setCurvilinearAbscissa( r ); + + Py_RETURN_NONE; +} + + +PyObject *StrokeVertex_setStrokeLength( BPy_StrokeVertex *self , PyObject *args) { + double r; + + if(!( PyArg_ParseTuple(args, "d", &r) )) + return NULL; + + self->sv->setStrokeLength( r ); + + Py_RETURN_NONE; +} + +// real operator[] (const int i) const +// real & operator[] (const int i) + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h new file mode 100644 index 00000000000..2a84e2480f0 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_STROKEVERTEX_H +#define FREESTYLE_PYTHON_STROKEVERTEX_H + +#include "../BPy_CurvePoint.h" +#include "../../../stroke/Stroke.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject StrokeVertex_Type; + +#define BPy_StrokeVertex_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &StrokeVertex_Type) ) + +/*---------------------------Python BPy_StrokeVertex structure definition----------*/ +typedef struct { + BPy_CurvePoint py_cp; + StrokeVertex *sv; +} BPy_StrokeVertex; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_STROKEVERTEX_H */ diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp new file mode 100644 index 00000000000..03d726830e1 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.cpp @@ -0,0 +1,122 @@ +#include "BPy_NonTVertex.h" + +#include "../../BPy_Convert.h" +#include "../BPy_SVertex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for NonTVertex___init__ instance -----------*/ +static int NonTVertex___init__(BPy_NonTVertex *self, PyObject *args, PyObject *kwds); + +static PyObject * NonTVertex_svertex( BPy_NonTVertex *self ); +static PyObject * NonTVertex_setSVertex( BPy_NonTVertex *self, PyObject *args); + +/*----------------------NonTVertex instance definitions ----------------------------*/ +static PyMethodDef BPy_NonTVertex_methods[] = { +// {"__copy__", ( PyCFunction ) NonTVertex___copy__, METH_NOARGS, "() Cloning method."}, + {"svertex", ( PyCFunction ) NonTVertex_svertex, METH_NOARGS, "() Returns the SVertex on top of which this NonTVertex is built. "}, + {"setSVertex", ( PyCFunction ) NonTVertex_setSVertex, METH_VARARGS, "(SVertex sv) Sets the SVertex on top of which this NonTVertex is built. "}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_NonTVertex type definition ------------------------------*/ + +PyTypeObject NonTVertex_Type = { + PyObject_HEAD_INIT(NULL) + "NonTVertex", /* tp_name */ + sizeof(BPy_NonTVertex), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "NonTVertex objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_NonTVertex_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &ViewVertex_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)NonTVertex___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int NonTVertex___init__(BPy_NonTVertex *self, PyObject *args, PyObject *kwds) +{ + + PyObject *obj = 0; + + if (! PyArg_ParseTuple(args, "|O!", &SVertex_Type, &obj) ) + return -1; + + if( !obj ){ + self->ntv = new NonTVertex(); + + } else if( ((BPy_SVertex *) obj)->sv ) { + self->ntv = new NonTVertex( ((BPy_SVertex *) obj)->sv ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return -1; + } + + self->py_vv.vv = self->ntv; + self->py_vv.py_if0D.if0D = self->ntv; + self->py_vv.py_if0D.borrowed = 0; + + return 0; +} + +PyObject * NonTVertex_svertex( BPy_NonTVertex *self ) { + SVertex *v = self->ntv->svertex(); + if( v ){ + return BPy_SVertex_from_SVertex( *v ); + } + + Py_RETURN_NONE; +} + +PyObject * NonTVertex_setSVertex( BPy_NonTVertex *self, PyObject *args) { + PyObject *py_sv; + + if(!( PyArg_ParseTuple(args, "O!", &SVertex_Type, &py_sv) )) + return NULL; + + self->ntv->setSVertex( ((BPy_SVertex *) py_sv)->sv ); + + Py_RETURN_NONE; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h new file mode 100644 index 00000000000..071194d2d42 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_NonTVertex.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_NONTVERTEX_H +#define FREESTYLE_PYTHON_NONTVERTEX_H + +#include "../BPy_ViewVertex.h" +#include "../../../view_map/ViewMap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject NonTVertex_Type; + +#define BPy_NonTVertex_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &NonTVertex_Type) ) + +/*---------------------------Python BPy_NonTVertex structure definition----------*/ +typedef struct { + BPy_ViewVertex py_vv; + NonTVertex *ntv; +} BPy_NonTVertex; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_NONTVERTEX_H */ diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp new file mode 100644 index 00000000000..2cfd43e818b --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.cpp @@ -0,0 +1,182 @@ +#include "BPy_TVertex.h" + +#include "../../BPy_Convert.h" +#include "../BPy_SVertex.h" +#include "../../BPy_Id.h" +#include "../../Interface1D/BPy_FEdge.h" +#include "../../Interface1D/BPy_ViewEdge.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for TVertex___init__ instance -----------*/ +static int TVertex___init__(BPy_TVertex *self, PyObject *args, PyObject *kwds); + +static PyObject * TVertex_frontSVertex( BPy_TVertex *self ); +static PyObject * TVertex_backSVertex( BPy_TVertex *self ); +static PyObject * TVertex_setFrontSVertex( BPy_TVertex *self, PyObject *args); +static PyObject * TVertex_setBackSVertex( BPy_TVertex *self, PyObject *args); +static PyObject * TVertex_setId( BPy_TVertex *self, PyObject *args); +static PyObject * TVertex_getSVertex( BPy_TVertex *self, PyObject *args); +static PyObject * TVertex_mate( BPy_TVertex *self, PyObject *args); + +/*----------------------TVertex instance definitions ----------------------------*/ +static PyMethodDef BPy_TVertex_methods[] = { +// {"__copy__", ( PyCFunction ) TVertex___copy__, METH_NOARGS, "() Cloning method."}, + {"frontSVertex", ( PyCFunction ) TVertex_frontSVertex, METH_NOARGS, "() Returns the SVertex that is closer to the viewpoint. "}, + {"backSVertex", ( PyCFunction ) TVertex_backSVertex, METH_NOARGS, "() Returns the SVertex that is further away from the viewpoint. "}, + {"setFrontSVertex", ( PyCFunction ) TVertex_setFrontSVertex, METH_VARARGS, "(SVertex sv) Sets the SVertex that is closer to the viewpoint. "}, + {"setBackSVertex", ( PyCFunction ) TVertex_setBackSVertex, METH_VARARGS, "(SVertex sv) Sets the SVertex that is further away from the viewpoint. "}, + {"setId", ( PyCFunction ) TVertex_setId, METH_VARARGS, "(Id id) Sets the Id."}, + {"getSVertex", ( PyCFunction ) TVertex_getSVertex, METH_VARARGS, "(FEdge fe) Returns the SVertex (among the 2) belonging to the FEdge iFEdge "}, + {"mate", ( PyCFunction ) TVertex_mate, METH_VARARGS, "(ViewEdge ve) Returns the mate edge of iEdgeA. For example, if iEdgeA is frontEdgeA, then frontEdgeB is returned. If iEdgeA is frontEdgeB then frontEdgeA is returned. Same for back edges"}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_TVertex type definition ------------------------------*/ + +PyTypeObject TVertex_Type = { + PyObject_HEAD_INIT(NULL) + "TVertex", /* tp_name */ + sizeof(BPy_TVertex), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "TVertex objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_TVertex_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &ViewVertex_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)TVertex___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int TVertex___init__(BPy_TVertex *self, PyObject *args, PyObject *kwds) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->tv = new TVertex(); + self->py_vv.vv = self->tv; + self->py_vv.py_if0D.if0D = self->tv; + self->py_vv.py_if0D.borrowed = 0; + + return 0; +} + + +PyObject * TVertex_frontSVertex( BPy_TVertex *self ) { + SVertex *v = self->tv->frontSVertex(); + if( v ){ + return BPy_SVertex_from_SVertex( *v ); + } + + Py_RETURN_NONE; +} + +PyObject * TVertex_backSVertex( BPy_TVertex *self ) { + SVertex *v = self->tv->backSVertex(); + if( v ){ + return BPy_SVertex_from_SVertex( *v ); + } + + Py_RETURN_NONE; +} + +PyObject * TVertex_setFrontSVertex( BPy_TVertex *self, PyObject *args) { + PyObject *py_sv; + + if(!( PyArg_ParseTuple(args, "O!", &SVertex_Type, &py_sv) )) + return NULL; + + self->tv->setFrontSVertex( ((BPy_SVertex *) py_sv)->sv ); + + Py_RETURN_NONE; +} + +PyObject * TVertex_setBackSVertex( BPy_TVertex *self, PyObject *args) { + PyObject *py_sv; + + if(!( PyArg_ParseTuple(args, "O", &SVertex_Type, &py_sv) )) + return NULL; + + self->tv->setBackSVertex( ((BPy_SVertex *) py_sv)->sv ); + + Py_RETURN_NONE; +} + +PyObject * TVertex_setId( BPy_TVertex *self, PyObject *args) { + PyObject *py_id; + + if(!( PyArg_ParseTuple(args, "O!", &Id_Type, &py_id) )) + return NULL; + + if( ((BPy_Id *) py_id)->id ) + self->tv->setId(*( ((BPy_Id *) py_id)->id )); + + Py_RETURN_NONE; +} + +PyObject * TVertex_getSVertex( BPy_TVertex *self, PyObject *args) { + PyObject *py_fe; + + if(!( PyArg_ParseTuple(args, "O!", &FEdge_Type, &py_fe) )) + return NULL; + + SVertex *sv = self->tv->getSVertex( ((BPy_FEdge *) py_fe)->fe ); + if( sv ){ + return BPy_SVertex_from_SVertex( *sv ); + } + + Py_RETURN_NONE; +} + +PyObject * TVertex_mate( BPy_TVertex *self, PyObject *args) { + PyObject *py_ve; + + if(!( PyArg_ParseTuple(args, "O!", &ViewEdge_Type, &py_ve) )) + return NULL; + + ViewEdge *ve = self->tv->mate( ((BPy_ViewEdge *) py_ve)->ve ); + if( ve ){ + return BPy_ViewEdge_from_ViewEdge( *ve ); + } + + Py_RETURN_NONE; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h new file mode 100644 index 00000000000..12fe5c0cb43 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface0D/ViewVertex/BPy_TVertex.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_TVERTEX_H +#define FREESTYLE_PYTHON_TVERTEX_H + +#include "../BPy_ViewVertex.h" +#include "../../../view_map/ViewMap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject TVertex_Type; + +#define BPy_TVertex_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &TVertex_Type) ) + +/*---------------------------Python BPy_TVertex structure definition----------*/ +typedef struct { + BPy_ViewVertex py_vv; + TVertex *tv; +} BPy_TVertex; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_TVERTEX_H */ diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp new file mode 100644 index 00000000000..a85373eae03 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp @@ -0,0 +1,343 @@ +#include "BPy_FEdge.h" + +#include "../BPy_Convert.h" +#include "../BPy_Id.h" +#include "../Interface0D/BPy_SVertex.h" +#include "../Interface1D/BPy_ViewEdge.h" +#include "../BPy_Nature.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for FEdge instance -----------*/ +static int FEdge___init__(BPy_FEdge *self, PyObject *args, PyObject *kwds); +static PyObject * FEdge___copy__( BPy_FEdge *self ); +static PyObject * FEdge_vertexA( BPy_FEdge *self ); +static PyObject * FEdge_vertexB( BPy_FEdge *self ); +static PyObject * FEdge___getitem__( BPy_FEdge *self, PyObject *args ); +static PyObject * FEdge_nextEdge( BPy_FEdge *self ); +static PyObject * FEdge_previousEdge( BPy_FEdge *self ); +static PyObject * FEdge_viewedge( BPy_FEdge *self ); +static PyObject * FEdge_isSmooth( BPy_FEdge *self ); +static PyObject * FEdge_setVertexA( BPy_FEdge *self , PyObject *args); +static PyObject * FEdge_setVertexB( BPy_FEdge *self , PyObject *args); +static PyObject * FEdge_setId( BPy_FEdge *self , PyObject *args); +static PyObject * FEdge_setNextEdge( BPy_FEdge *self , PyObject *args); +static PyObject * FEdge_setPreviousEdge( BPy_FEdge *self , PyObject *args); +static PyObject * FEdge_setSmooth( BPy_FEdge *self , PyObject *args); +static PyObject * FEdge_setNature( BPy_FEdge *self, PyObject *args ); +static PyObject * FEdge_setViewEdge( BPy_FEdge *self, PyObject *args ); +static PyObject * FEdge_verticesBegin( BPy_FEdge *self ); +static PyObject * FEdge_verticesEnd( BPy_FEdge *self ); +static PyObject * FEdge_pointsBegin( BPy_FEdge *self, PyObject *args ); +static PyObject * FEdge_pointsEnd( BPy_FEdge *self, PyObject *args ); + +/*----------------------FEdge instance definitions ----------------------------*/ +static PyMethodDef BPy_FEdge_methods[] = { + {"__copy__", ( PyCFunction ) FEdge___copy__, METH_NOARGS, "() Cloning method."}, + {"vertexA", ( PyCFunction ) FEdge_vertexA, METH_NOARGS, "() Returns the first SVertex."}, + {"vertexB", ( PyCFunction ) FEdge_vertexB, METH_NOARGS, "() Returns the second SVertex."}, + {"__getitem__", ( PyCFunction ) FEdge___getitem__, METH_VARARGS, "(int i) Returns the first SVertex if i=0, the seccond SVertex if i=1."}, + {"nextEdge", ( PyCFunction ) FEdge_nextEdge, METH_NOARGS, "() Returns the FEdge following this one in the ViewEdge. If this FEdge is the last of the ViewEdge, 0 is returned."}, + {"previousEdge", ( PyCFunction ) FEdge_previousEdge, METH_NOARGS, "Returns the Edge preceding this one in the ViewEdge. If this FEdge is the first one of the ViewEdge, 0 is returned."}, + {"viewedge", ( PyCFunction ) FEdge_viewedge, METH_NOARGS, "Returns a pointer to the ViewEdge to which this FEdge belongs to."}, + {"isSmooth", ( PyCFunction ) FEdge_isSmooth, METH_NOARGS, "() Returns true if this FEdge is a smooth FEdge."}, + {"setVertexA", ( PyCFunction ) FEdge_setVertexA, METH_VARARGS, "(SVertex v) Sets the first SVertex. ."}, + {"setVertexB", ( PyCFunction ) FEdge_setVertexB, METH_VARARGS, "(SVertex v) Sets the second SVertex. "}, + {"setId", ( PyCFunction ) FEdge_setId, METH_VARARGS, "(Id id) Sets the FEdge Id ."}, + {"setNextEdge", ( PyCFunction ) FEdge_setNextEdge, METH_VARARGS, "(FEdge e) Sets the pointer to the next FEdge. "}, + {"setPreviousEdge", ( PyCFunction ) FEdge_setPreviousEdge, METH_VARARGS, "(FEdge e) Sets the pointer to the previous FEdge. "}, + {"setSmooth", ( PyCFunction ) FEdge_setSmooth, METH_VARARGS, "(bool b) Sets the flag telling whether this FEdge is smooth or sharp. true for Smooth, false for Sharp. "}, + {"setViewEdge", ( PyCFunction ) FEdge_setViewEdge, METH_VARARGS, "(ViewEdge ve) Sets the ViewEdge to which this FEdge belongs to."}, + {"setNature", ( PyCFunction ) FEdge_setNature, METH_VARARGS, "(Nature n) Sets the nature of this FEdge. "}, + {"verticesBegin", ( PyCFunction ) FEdge_verticesBegin, METH_NOARGS, "() Returns an iterator over the 2 (!) SVertex pointing to the first SVertex."}, + {"verticesEnd", ( PyCFunction ) FEdge_verticesEnd, METH_NOARGS, "() Returns an iterator over the 2 (!) SVertex pointing after the last SVertex. "}, + {"pointsBegin", ( PyCFunction ) FEdge_pointsBegin, METH_VARARGS, "(float t=0) Returns an iterator over the FEdge points, pointing to the first point. The difference with verticesBegin() is that here we can iterate over points of the FEdge at a any given sampling t. Indeed, for each iteration, a virtual point is created."}, + {"pointsEnd", ( PyCFunction ) FEdge_pointsEnd, METH_VARARGS, "(float t=0) Returns an iterator over the FEdge points, pointing after the last point. The difference with verticesEnd() is that here we can iterate over points of the FEdge at a any given sampling t. Indeed, for each iteration, a virtual point is created."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_FEdge type definition ------------------------------*/ + +PyTypeObject FEdge_Type = { + PyObject_HEAD_INIT(NULL) + "FEdge", /* tp_name */ + sizeof(BPy_FEdge), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "FEdge objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_FEdge_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Interface1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FEdge___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int FEdge___init__(BPy_FEdge *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj1 = 0, *obj2 = 0; + + if (! PyArg_ParseTuple(args, "|OO", &obj1, &obj2) ) + return -1; + + if( !obj1 ){ + self->fe = new FEdge(); + + } else if( !obj2 && BPy_FEdge_Check(obj1) ) { + self->fe = new FEdge(*( ((BPy_FEdge *) obj1)->fe )); + + } else if( obj2 && BPy_SVertex_Check(obj1) && BPy_SVertex_Check(obj2) ) { + self->fe = new FEdge( ((BPy_SVertex *) obj1)->sv, ((BPy_SVertex *) obj2)->sv ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument(s)"); + return -1; + } + + self->py_if1D.if1D = self->fe; + self->py_if1D.borrowed = 0; + + return 0; +} + + +PyObject * FEdge___copy__( BPy_FEdge *self ) { + BPy_FEdge *py_fe; + + py_fe = (BPy_FEdge *) FEdge_Type.tp_new( &FEdge_Type, 0, 0 ); + + py_fe->fe = new FEdge( *(self->fe) ); + py_fe->py_if1D.if1D = py_fe->fe; + py_fe->py_if1D.borrowed = 0; + + return (PyObject *) py_fe; +} + +PyObject * FEdge_vertexA( BPy_FEdge *self ) { + SVertex *A = self->fe->vertexA(); + if( A ){ + return BPy_SVertex_from_SVertex( *A ); + } + + Py_RETURN_NONE; +} + +PyObject * FEdge_vertexB( BPy_FEdge *self ) { + SVertex *B = self->fe->vertexB(); + if( B ){ + return BPy_SVertex_from_SVertex( *B ); + } + + Py_RETURN_NONE; +} + + +PyObject * FEdge___getitem__( BPy_FEdge *self, PyObject *args ) { + int i; + + if(!( PyArg_ParseTuple(args, "i", &i) )) + return NULL; + if(!(i == 0 || i == 1)) { + PyErr_SetString(PyExc_IndexError, "index must be either 0 or 1"); + return NULL; + } + + SVertex *v = self->fe->operator[](i); + if( v ) + return BPy_SVertex_from_SVertex( *v ); + + Py_RETURN_NONE; +} + +PyObject * FEdge_nextEdge( BPy_FEdge *self ) { + FEdge *fe = self->fe->nextEdge(); + if( fe ) + return Any_BPy_FEdge_from_FEdge( *fe ); + + Py_RETURN_NONE; +} + +PyObject * FEdge_previousEdge( BPy_FEdge *self ) { + FEdge *fe = self->fe->previousEdge(); + if( fe ) + return Any_BPy_FEdge_from_FEdge( *fe ); + + Py_RETURN_NONE; +} + +PyObject * FEdge_viewedge( BPy_FEdge *self ) { + ViewEdge *ve = self->fe->viewedge(); + if( ve ) + return BPy_ViewEdge_from_ViewEdge( *ve ); + + Py_RETURN_NONE; +} + +PyObject * FEdge_isSmooth( BPy_FEdge *self ) { + return PyBool_from_bool( self->fe->isSmooth() ); +} + +PyObject *FEdge_setVertexA( BPy_FEdge *self , PyObject *args) { + PyObject *py_sv; + + if(!( PyArg_ParseTuple(args, "O!", &SVertex_Type, &py_sv) )) + return NULL; + + self->fe->setVertexA( ((BPy_SVertex *) py_sv)->sv ); + + Py_RETURN_NONE; +} + +PyObject *FEdge_setVertexB( BPy_FEdge *self , PyObject *args) { + PyObject *py_sv; + + if(!( PyArg_ParseTuple(args, "O", &py_sv) && BPy_SVertex_Check(py_sv) )) { + cout << "ERROR: FEdge_setVertexB" << endl; + Py_RETURN_NONE; + } + + self->fe->setVertexB( ((BPy_SVertex *) py_sv)->sv ); + + Py_RETURN_NONE; +} + +PyObject *FEdge_setId( BPy_FEdge *self , PyObject *args) { + PyObject *py_id; + + if(!( PyArg_ParseTuple(args, "O!", &Id_Type, &py_id) )) + return NULL; + + self->fe->setId(*( ((BPy_Id *) py_id)->id )); + + Py_RETURN_NONE; +} + + +PyObject *FEdge_setNextEdge( BPy_FEdge *self , PyObject *args) { + PyObject *py_fe; + + if(!( PyArg_ParseTuple(args, "O!", &FEdge_Type, &py_fe) )) + return NULL; + + self->fe->setNextEdge( ((BPy_FEdge *) py_fe)->fe ); + + Py_RETURN_NONE; +} + +PyObject *FEdge_setPreviousEdge( BPy_FEdge *self , PyObject *args) { + PyObject *py_fe; + + if(!( PyArg_ParseTuple(args, "O!", &FEdge_Type, &py_fe) )) + return NULL; + + self->fe->setPreviousEdge( ((BPy_FEdge *) py_fe)->fe ); + + Py_RETURN_NONE; +} + +PyObject * FEdge_setNature( BPy_FEdge *self, PyObject *args ) { + PyObject *py_n; + + if(!( PyArg_ParseTuple(args, "O!", &Nature_Type, &py_n) )) + return NULL; + + PyObject *i = (PyObject *) &( ((BPy_Nature *) py_n)->i ); + self->fe->setNature( PyLong_AsLong(i) ); + + Py_RETURN_NONE; +} + + +PyObject * FEdge_setViewEdge( BPy_FEdge *self, PyObject *args ) { + PyObject *py_ve; + + if(!( PyArg_ParseTuple(args, "O!", &ViewEdge_Type, &py_ve) )) + return NULL; + + ViewEdge *ve = ((BPy_ViewEdge *) py_ve)->ve; + self->fe->setViewEdge( ve ); + + Py_RETURN_NONE; +} + + + +PyObject *FEdge_setSmooth( BPy_FEdge *self , PyObject *args) { + PyObject *py_b; + + if(!( PyArg_ParseTuple(args, "O", &py_b) )) + return NULL; + + self->fe->setSmooth( bool_from_PyBool(py_b) ); + + Py_RETURN_NONE; +} + + +PyObject * FEdge_verticesBegin( BPy_FEdge *self ) { + Interface0DIterator if0D_it( self->fe->verticesBegin() ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 0 ); +} + +PyObject * FEdge_verticesEnd( BPy_FEdge *self ) { + Interface0DIterator if0D_it( self->fe->verticesEnd() ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 1 ); +} + + +PyObject * FEdge_pointsBegin( BPy_FEdge *self, PyObject *args ) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + Interface0DIterator if0D_it( self->fe->pointsBegin(f) ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 0 ); +} + +PyObject * FEdge_pointsEnd( BPy_FEdge *self, PyObject *args ) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + Interface0DIterator if0D_it( self->fe->pointsEnd(f) ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 1 ); +} +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h new file mode 100644 index 00000000000..9d13145aaf2 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_FEDGE_H +#define FREESTYLE_PYTHON_FEDGE_H + +#include "../BPy_Interface1D.h" +#include "../../view_map/Silhouette.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject FEdge_Type; + +#define BPy_FEdge_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &FEdge_Type) ) + +/*---------------------------Python BPy_FEdge structure definition----------*/ +typedef struct { + BPy_Interface1D py_if1D; + FEdge *fe; +} BPy_FEdge; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_FEDGE_H */ diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp new file mode 100644 index 00000000000..bdb95ae8889 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp @@ -0,0 +1,198 @@ +#include "BPy_FrsCurve.h" + +#include "../BPy_Convert.h" +#include "../BPy_Id.h" +#include "../Interface0D/BPy_CurvePoint.h" +#include "../Interface0D/BPy_SVertex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for FrsCurve instance -----------*/ +static int FrsCurve___init__(BPy_FrsCurve *self, PyObject *args, PyObject *kwds); +static PyObject * FrsCurve_push_vertex_back( BPy_FrsCurve *self, PyObject *args ); +static PyObject * FrsCurve_push_vertex_front( BPy_FrsCurve *self, PyObject *args ); +static PyObject * FrsCurve_empty( BPy_FrsCurve *self ); +static PyObject * FrsCurve_nSegments( BPy_FrsCurve *self ); +// point_iterator points_begin (float step=0) +static PyObject * FrsCurve_verticesBegin( BPy_FrsCurve *self ); +static PyObject * FrsCurve_verticesEnd( BPy_FrsCurve *self ); +static PyObject * FrsCurve_pointsBegin( BPy_FrsCurve *self, PyObject *args ); +static PyObject * FrsCurve_pointsEnd( BPy_FrsCurve *self, PyObject *args ); + +/*----------------------FrsCurve instance definitions ----------------------------*/ +static PyMethodDef BPy_FrsCurve_methods[] = { + {"push_vertex_back", ( PyCFunction ) FrsCurve_push_vertex_back, METH_VARARGS, "(CurvePoint cp | SVertex sv) Adds a single vertex at the front of the Curve."}, + {"push_vertex_front", ( PyCFunction ) FrsCurve_push_vertex_front, METH_VARARGS, "(CurvePoint cp | SVertex sv) Adds a single vertex at the end of the Curve."}, + {"empty", ( PyCFunction ) FrsCurve_empty, METH_NOARGS, "() Returns true is the Curve doesn't have any Vertex yet."}, + {"nSegments", ( PyCFunction ) FrsCurve_nSegments, METH_NOARGS, "() Returns the number of segments in the oplyline constituing the Curve."}, + {"verticesBegin", ( PyCFunction ) FrsCurve_verticesBegin, METH_NOARGS, "() Returns an Interface0DIterator pointing onto the first vertex of the Curve and that can iterate over the vertices of the Curve."}, + {"verticesEnd", ( PyCFunction ) FrsCurve_verticesEnd, METH_NOARGS, "() Returns an Interface0DIterator pointing after the last vertex of the Curve and that can iterate over the vertices of the Curve."}, + {"pointsBegin", ( PyCFunction ) FrsCurve_pointsBegin, METH_VARARGS, "(float t=0) Returns an Interface0DIterator pointing onto the first point of the Curve and that can iterate over the points of the Curve at any resolution t. At each iteration a virtual temporary CurvePoint is created."}, + {"pointsEnd", ( PyCFunction ) FrsCurve_pointsEnd, METH_VARARGS, "(float t=0) Returns an Interface0DIterator pointing after the last point of the Curve and that can iterate over the points of the Curve at any resolution t. At each iteration a virtual temporary CurvePoint is created."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_FrsCurve type definition ------------------------------*/ + +PyTypeObject FrsCurve_Type = { + PyObject_HEAD_INIT(NULL) + "FrsCurve", /* tp_name */ + sizeof(BPy_FrsCurve), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "FrsCurve objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_FrsCurve_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Interface1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FrsCurve___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int FrsCurve___init__(BPy_FrsCurve *self, PyObject *args, PyObject *kwds) +{ + + PyObject *obj = 0; + + if (! PyArg_ParseTuple(args, "|O", &obj) ) + return -1; + + if( !obj ){ + self->c = new Curve(); + + } else if( BPy_FrsCurve_Check(obj) ) { + self->c = new Curve(*( ((BPy_FrsCurve *) obj)->c )); + + } else if( BPy_Id_Check(obj) ) { + self->c = new Curve(*( ((BPy_Id *) obj)->id )); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return -1; + } + + self->py_if1D.if1D = self->c; + self->py_if1D.borrowed = 0; + + return 0; +} + + +PyObject * FrsCurve_push_vertex_back( BPy_FrsCurve *self, PyObject *args ) { + PyObject *obj; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + + if( BPy_CurvePoint_Check(obj) ) { + self->c->push_vertex_back( ((BPy_CurvePoint *) obj)->cp ); + } else if( BPy_SVertex_Check(obj) ) { + self->c->push_vertex_back( ((BPy_SVertex *) obj)->sv ); + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject * FrsCurve_push_vertex_front( BPy_FrsCurve *self, PyObject *args ) { + PyObject *obj; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + + if( BPy_CurvePoint_Check(obj) ) { + self->c->push_vertex_front( ((BPy_CurvePoint *) obj)->cp ); + } else if( BPy_SVertex_Check(obj) ) { + self->c->push_vertex_front( ((BPy_SVertex *) obj)->sv ); + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject * FrsCurve_empty( BPy_FrsCurve *self ) { + return PyBool_from_bool( self->c->empty() ); +} + +PyObject * FrsCurve_nSegments( BPy_FrsCurve *self ) { + return PyLong_FromLong( self->c->nSegments() ); +} + +// point_iterator points_begin (float step=0) +// not implemented + + +PyObject * FrsCurve_verticesBegin( BPy_FrsCurve *self ) { + Interface0DIterator if0D_it( self->c->verticesBegin() ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 0 ); +} + +PyObject * FrsCurve_verticesEnd( BPy_FrsCurve *self ) { + Interface0DIterator if0D_it( self->c->verticesEnd() ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 1 ); +} + + +PyObject * FrsCurve_pointsBegin( BPy_FrsCurve *self, PyObject *args ) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + Interface0DIterator if0D_it( self->c->pointsBegin(f) ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 0 ); +} + +PyObject * FrsCurve_pointsEnd( BPy_FrsCurve *self, PyObject *args ) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + Interface0DIterator if0D_it( self->c->pointsEnd(f) ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 1 ); +} + + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h new file mode 100644 index 00000000000..0829cf0ebf5 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_FRSCURVE_H +#define FREESTYLE_PYTHON_FRSCURVE_H + +#include "../BPy_Interface1D.h" +#include "../../stroke/Curve.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject FrsCurve_Type; + +#define BPy_FrsCurve_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &FrsCurve_Type) ) + +/*---------------------------Python BPy_FrsCurve structure definition----------*/ +typedef struct { + BPy_Interface1D py_if1D; + Curve *c; +} BPy_FrsCurve; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_FRSCURVE_H */ diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp new file mode 100644 index 00000000000..41fa42a6ac2 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp @@ -0,0 +1,372 @@ +#include "BPy_Stroke.h" + +#include "../BPy_Convert.h" +#include "../BPy_Id.h" +#include "../Interface0D/BPy_SVertex.h" +#include "../Interface0D/CurvePoint/BPy_StrokeVertex.h" +#include "../Iterator/BPy_StrokeVertexIterator.h" +#include "../BPy_MediumType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Stroke instance -----------*/ +static int Stroke___init__(BPy_Stroke *self, PyObject *args, PyObject *kwds); +static PyObject * Stroke___iter__(PyObject *self); + +static Py_ssize_t Stroke_length( BPy_Stroke *self ); +static PyObject * Stroke_item( BPy_Stroke *self, Py_ssize_t i ); +static PyObject * Stroke___getitem__( BPy_Stroke *self, PyObject *item ); + +static PyObject * Stroke_ComputeSampling( BPy_Stroke *self, PyObject *args ); +static PyObject * Stroke_Resample( BPy_Stroke *self, PyObject *args ); +static PyObject * Stroke_InsertVertex( BPy_Stroke *self, PyObject *args ); +static PyObject * Stroke_RemoveVertex( BPy_Stroke *self, PyObject *args ); +static PyObject * Stroke_getMediumType( BPy_Stroke *self ); +static PyObject * Stroke_getTextureId( BPy_Stroke *self ); +static PyObject * Stroke_hasTips( BPy_Stroke *self ); +static PyObject * Stroke_setId( BPy_Stroke *self , PyObject *args); +static PyObject * Stroke_setLength( BPy_Stroke *self , PyObject *args); +static PyObject * Stroke_setMediumType( BPy_Stroke *self , PyObject *args); +static PyObject * Stroke_setTextureId( BPy_Stroke *self , PyObject *args); +static PyObject * Stroke_setTips( BPy_Stroke *self , PyObject *args); +static PyObject * Stroke_strokeVerticesBegin( BPy_Stroke *self , PyObject *args); +static PyObject * Stroke_strokeVerticesEnd( BPy_Stroke *self ); +static PyObject * Stroke_strokeVerticesSize( BPy_Stroke *self ); +static PyObject * Stroke_verticesBegin( BPy_Stroke *self ); +static PyObject * Stroke_verticesEnd( BPy_Stroke *self ); +static PyObject * Stroke_pointsBegin( BPy_Stroke *self , PyObject *args); +static PyObject * Stroke_pointsEnd( BPy_Stroke *self , PyObject *args); + +/*----------------------Stroke instance definitions ----------------------------*/ +static PyMethodDef BPy_Stroke_methods[] = { + {"__getitem__", ( PyCFunction ) Stroke___getitem__, METH_O, "(int i) Returns the i-th StrokeVertex constituting the Stroke."}, + {"ComputeSampling", ( PyCFunction ) Stroke_ComputeSampling, METH_VARARGS, "(int nVertices) Compute the sampling needed to get nVertices vertices. If the specified number of vertices is less than the actual number of vertices, the actual sampling value is returned."}, + {"Resample", ( PyCFunction ) Stroke_Resample, METH_VARARGS, "(float f | int n) Resampling method. If the argument is a float, Resamples the curve with a given sampling; if this sampling is < to the actual sampling value, no resampling is done. If the argument is an integer, Resamples the curve so that it eventually has n. That means it is going to add n-vertices_size, if vertices_size is the number of points we already have. Is vertices_size >= n, no resampling is done."}, + {"RemoveVertex", ( PyCFunction ) Stroke_RemoveVertex, METH_VARARGS, "(StrokeVertex sv) Removes the stroke vertex sv from the stroke. The length and curvilinear abscissa are updated consequently."}, + {"InsertVertex", ( PyCFunction ) Stroke_InsertVertex, METH_VARARGS, "(StrokeVertex sv, StrokeVertexIterator next) Inserts the stroke vertex iVertex in the stroke before next. The length, curvilinear abscissa are updated consequently."}, + {"getMediumType", ( PyCFunction ) Stroke_getMediumType, METH_NOARGS, "() Returns the MediumType used for this Stroke."}, + {"getTextureId", ( PyCFunction ) Stroke_getTextureId, METH_NOARGS, "() Returns the id of the texture used to simulate th marks system for this Stroke."}, + {"hasTips", ( PyCFunction ) Stroke_hasTips, METH_NOARGS, "() Returns true if this Stroke uses a texture with tips, false otherwise."}, + {"setId", ( PyCFunction ) Stroke_setId, METH_VARARGS, "(Id id) Sets the Id of the Stroke."}, + {"setLength", ( PyCFunction ) Stroke_setLength, METH_VARARGS, "(float l) Sets the 2D length of the Stroke."}, + {"setMediumType", ( PyCFunction ) Stroke_setMediumType, METH_VARARGS, "(MediumType mt) Sets the medium type that must be used for this Stroke."}, + {"setTextureId", ( PyCFunction ) Stroke_setTextureId, METH_VARARGS, "(unsigned int id) Sets the texture id to be used to simulate the marks system for this Stroke."}, + {"setTips", ( PyCFunction ) Stroke_setTips, METH_VARARGS, "(bool b) Sets the flag telling whether this stroke is using a texture with tips or not."}, + {"strokeVerticesBegin", ( PyCFunction ) Stroke_strokeVerticesBegin, METH_VARARGS, "(float t=0.f) Returns a StrokeVertexIterator pointing on the first StrokeVertex of the Stroke. One can specifly a sampling value t to resample the Stroke on the fly if needed. "}, + {"strokeVerticesEnd", ( PyCFunction ) Stroke_strokeVerticesEnd, METH_NOARGS, "() Returns a StrokeVertexIterator pointing after the last StrokeVertex of the Stroke."}, + {"strokeVerticesSize", ( PyCFunction ) Stroke_strokeVerticesSize, METH_NOARGS, "() Returns the number of StrokeVertex constituing the Stroke."}, + {"verticesBegin", ( PyCFunction ) Stroke_verticesBegin, METH_NOARGS, "() Returns an Interface0DIterator pointing on the first StrokeVertex of the Stroke. "}, + {"verticesEnd", ( PyCFunction ) Stroke_verticesEnd, METH_NOARGS, "() Returns an Interface0DIterator pointing after the last StrokeVertex of the Stroke. "}, + {"pointsBegin", ( PyCFunction ) Stroke_pointsBegin, METH_VARARGS, "(float t=0.f) Returns an iterator over the Interface1D points, pointing to the first point. The difference with verticesBegin() is that here we can iterate over points of the 1D element at a any given sampling t. Indeed, for each iteration, a virtual point is created. "}, + {"pointsEnd", ( PyCFunction ) Stroke_pointsEnd, METH_VARARGS, "(float t=0.f) Returns an iterator over the Interface1D points, pointing after the last point. The difference with verticesEnd() is that here we can iterate over points of the 1D element at a any given sampling t. Indeed, for each iteration, a virtual point is created. "}, + + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_Stroke type definition ------------------------------*/ + +static PySequenceMethods Stroke_as_sequence = { + (lenfunc)Stroke_length, /* sq_length */ + NULL, /* sq_concat */ + NULL, /* sq_repeat */ + (ssizeargfunc)Stroke_item, /* sq_item */ + NULL, /* sq_slice */ + NULL, /* sq_ass_item */ + NULL, /* sq_ass_slice */ + NULL, /* sq_contains */ + NULL, /* sq_inplace_concat */ + NULL, /* sq_inplace_repeat */ +}; + +PyTypeObject Stroke_Type = { + PyObject_HEAD_INIT(NULL) + "Stroke", /* tp_name */ + sizeof(BPy_Stroke), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + &Stroke_as_sequence, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Stroke objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)Stroke___iter__, /* tp_iter */ + 0, /* tp_iternext */ + BPy_Stroke_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Interface1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Stroke___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +// Stroke () +// template<class InputVertexIterator> Stroke (InputVertexIterator iBegin, InputVertexIterator iEnd) +// +// pb: - need to be able to switch representation: InputVertexIterator <=> position +// - is it even used ? not even in SWIG version + +int Stroke___init__(BPy_Stroke *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj1 = NULL, *obj2 = NULL; + + if (! PyArg_ParseTuple(args, "|OO", &obj1, &obj2) ) + return -1; + + if( !obj1 ){ + self->s = new Stroke(); + + } else if ( !obj2 && BPy_Stroke_Check(obj1) ) { + self->s = new Stroke(*( ((BPy_Stroke *)obj1)->s )); + + } else if ( obj2 ) { + PyErr_SetString(PyExc_TypeError, + "Stroke(InputVertexIterator iBegin, InputVertexIterator iEnd) not implemented"); + return -1; + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument(s)"); + return -1; + } + + self->py_if1D.if1D = self->s; + self->py_if1D.borrowed = 0; + + return 0; +} + +PyObject * Stroke___iter__( PyObject *self ) { + StrokeInternal::StrokeVertexIterator sv_it( ((BPy_Stroke *)self)->s->strokeVerticesBegin() ); + return BPy_StrokeVertexIterator_from_StrokeVertexIterator( sv_it, 0 ); +} + +Py_ssize_t Stroke_length( BPy_Stroke *self ) { + return self->s->strokeVerticesSize(); +} + +PyObject * Stroke_item( BPy_Stroke *self, Py_ssize_t i ) { + if (i < 0 || i >= (Py_ssize_t)self->s->strokeVerticesSize()) { + PyErr_SetString(PyExc_IndexError, "subscript index out of range"); + return NULL; + } + return BPy_StrokeVertex_from_StrokeVertex( self->s->strokeVerticeAt(i) ); +} + +PyObject * Stroke___getitem__( BPy_Stroke *self, PyObject *item ) { + long i; + + if (!PyLong_Check(item)) { + PyErr_SetString(PyExc_TypeError, "subscript indices must be integers"); + return NULL; + } + i = PyLong_AsLong(item); + if (i == -1 && PyErr_Occurred()) + return NULL; + if (i < 0) { + i += self->s->strokeVerticesSize(); + } + return Stroke_item(self, i); +} + +PyObject * Stroke_ComputeSampling( BPy_Stroke *self, PyObject *args ) { + int i; + + if(!( PyArg_ParseTuple(args, "i", &i) )) + return NULL; + + return PyFloat_FromDouble( self->s->ComputeSampling( i ) ); +} + +PyObject * Stroke_Resample( BPy_Stroke *self, PyObject *args ) { + PyObject *obj; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + + if( PyLong_Check(obj) ) + self->s->Resample( (int) PyLong_AsLong(obj) ); + else if( PyFloat_Check(obj) ) + self->s->Resample( (float) PyFloat_AsDouble(obj) ); + else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject * Stroke_InsertVertex( BPy_Stroke *self, PyObject *args ) { + PyObject *py_sv = 0, *py_sv_it = 0; + + if(!( PyArg_ParseTuple(args, "O!O!", &StrokeVertex_Type, &py_sv, &StrokeVertexIterator_Type, &py_sv_it) )) + return NULL; + + StrokeVertex *sv = ((BPy_StrokeVertex *) py_sv)->sv; + StrokeInternal::StrokeVertexIterator sv_it(*( ((BPy_StrokeVertexIterator *) py_sv_it)->sv_it )); + self->s->InsertVertex( sv, sv_it ); + + Py_RETURN_NONE; +} + +PyObject * Stroke_RemoveVertex( BPy_Stroke *self, PyObject *args ) { + PyObject *py_sv; + + if(!( PyArg_ParseTuple(args, "O!", &StrokeVertex_Type, &py_sv) )) + return NULL; + + if( ((BPy_StrokeVertex *) py_sv)->sv ) + self->s->RemoveVertex( ((BPy_StrokeVertex *) py_sv)->sv ); + else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return NULL; + } + + Py_RETURN_NONE; +} + +PyObject * Stroke_getMediumType( BPy_Stroke *self ) { + return BPy_MediumType_from_MediumType( self->s->getMediumType() ); +} + +PyObject * Stroke_getTextureId( BPy_Stroke *self ) { + return PyLong_FromLong( self->s->getTextureId() ); +} + +PyObject * Stroke_hasTips( BPy_Stroke *self ) { + return PyBool_from_bool( self->s->hasTips() ); +} + + +PyObject *Stroke_setId( BPy_Stroke *self , PyObject *args) { + PyObject *py_id; + + if(!( PyArg_ParseTuple(args, "O!", &Id_Type, &py_id) )) + return NULL; + + self->s->setId(*( ((BPy_Id *) py_id)->id )); + + Py_RETURN_NONE; +} + +PyObject *Stroke_setLength( BPy_Stroke *self , PyObject *args) { + float f; + + if(!( PyArg_ParseTuple(args, "f", &f) )) + return NULL; + + self->s->setLength( f ); + + Py_RETURN_NONE; +} + +PyObject *Stroke_setMediumType( BPy_Stroke *self , PyObject *args) { + PyObject *py_mt; + + if(!( PyArg_ParseTuple(args, "O!", &MediumType_Type, &py_mt) )) + return NULL; + + self->s->setMediumType( MediumType_from_BPy_MediumType(py_mt) ); + + Py_RETURN_NONE; +} + +PyObject *Stroke_setTextureId( BPy_Stroke *self , PyObject *args) { + unsigned int i; + + if(!( PyArg_ParseTuple(args, "I", &i) )) + return NULL; + + self->s->setTextureId( i ); + + Py_RETURN_NONE; +} + +PyObject *Stroke_setTips( BPy_Stroke *self , PyObject *args) { + PyObject *py_b; + + if(!( PyArg_ParseTuple(args, "O", &py_b) )) + return NULL; + + self->s->setTips( bool_from_PyBool(py_b) ); + + Py_RETURN_NONE; +} + +PyObject * Stroke_strokeVerticesBegin( BPy_Stroke *self , PyObject *args) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + StrokeInternal::StrokeVertexIterator sv_it( self->s->strokeVerticesBegin(f) ); + return BPy_StrokeVertexIterator_from_StrokeVertexIterator( sv_it, 0 ); +} + +PyObject * Stroke_strokeVerticesEnd( BPy_Stroke *self ) { + StrokeInternal::StrokeVertexIterator sv_it( self->s->strokeVerticesEnd() ); + return BPy_StrokeVertexIterator_from_StrokeVertexIterator( sv_it, 1 ); +} + +PyObject * Stroke_strokeVerticesSize( BPy_Stroke *self ) { + return PyLong_FromLong( self->s->strokeVerticesSize() ); +} + +PyObject * Stroke_verticesBegin( BPy_Stroke *self ) { + Interface0DIterator if0D_it( self->s->verticesBegin() ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 0 ); +} + +PyObject * Stroke_verticesEnd( BPy_Stroke *self ) { + Interface0DIterator if0D_it( self->s->verticesEnd() ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 1 ); +} + +PyObject * Stroke_pointsBegin( BPy_Stroke *self , PyObject *args) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + Interface0DIterator if0D_it( self->s->pointsBegin(f) ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 0 ); +} + +PyObject * Stroke_pointsEnd( BPy_Stroke *self , PyObject *args) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + Interface0DIterator if0D_it( self->s->pointsEnd(f) ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 1 ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h new file mode 100644 index 00000000000..52c6d214b85 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_STROKE_H +#define FREESTYLE_PYTHON_STROKE_H + +#include "../BPy_Interface1D.h" +#include "../../stroke/Stroke.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Stroke_Type; + +#define BPy_Stroke_Check(v) (( (PyObject *) v)->ob_type == &Stroke_Type) + +/*---------------------------Python BPy_Stroke structure definition----------*/ +typedef struct { + BPy_Interface1D py_if1D; + Stroke *s; +} BPy_Stroke; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_STROKE_H */ diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp new file mode 100644 index 00000000000..ba3d13d70f2 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.cpp @@ -0,0 +1,352 @@ +#include "BPy_ViewEdge.h" + +#include "../BPy_Convert.h" +#include "../BPy_Id.h" +#include "../Interface0D/BPy_ViewVertex.h" +#include "../Interface1D/BPy_FEdge.h" +#include "../Interface1D/BPy_ViewEdge.h" +#include "../BPy_Nature.h" +#include "../BPy_ViewShape.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ViewEdge instance -----------*/ +static int ViewEdge___init__(BPy_ViewEdge *self, PyObject *args, PyObject *kwds); + +static PyObject * ViewEdge_A( BPy_ViewEdge *self ); +static PyObject * ViewEdge_B( BPy_ViewEdge *self ); +static PyObject * ViewEdge_fedgeA( BPy_ViewEdge *self ) ; +static PyObject * ViewEdge_fedgeB( BPy_ViewEdge *self ) ; +static PyObject * ViewEdge_viewShape( BPy_ViewEdge *self ) ; +static PyObject * ViewEdge_aShape( BPy_ViewEdge *self ) ; +static PyObject * ViewEdge_isClosed( BPy_ViewEdge *self ); +static PyObject * ViewEdge_getChainingTimeStamp( BPy_ViewEdge *self ); +static PyObject * ViewEdge_setChainingTimeStamp( BPy_ViewEdge *self, PyObject *args) ; +static PyObject * ViewEdge_setA( BPy_ViewEdge *self , PyObject *args) ; +static PyObject * ViewEdge_setB( BPy_ViewEdge *self , PyObject *args); +static PyObject * ViewEdge_setNature( BPy_ViewEdge *self, PyObject *args ); +static PyObject * ViewEdge_setFEdgeA( BPy_ViewEdge *self, PyObject *args ) ; +static PyObject * ViewEdge_setFEdgeB( BPy_ViewEdge *self, PyObject *args ) ; +static PyObject * ViewEdge_setShape( BPy_ViewEdge *self, PyObject *args ) ; +static PyObject * ViewEdge_setId( BPy_ViewEdge *self, PyObject *args ) ; +static PyObject * ViewEdge_UpdateFEdges( BPy_ViewEdge *self ); +static PyObject * ViewEdge_setaShape( BPy_ViewEdge *self, PyObject *args ); +static PyObject * ViewEdge_setQI( BPy_ViewEdge *self, PyObject *args ); +static PyObject * ViewEdge_verticesBegin( BPy_ViewEdge *self ); +static PyObject * ViewEdge_verticesEnd( BPy_ViewEdge *self ); +static PyObject * ViewEdge_pointsBegin( BPy_ViewEdge *self, PyObject *args ); +static PyObject * ViewEdge_pointsEnd( BPy_ViewEdge *self, PyObject *args ); +static PyObject * ViewEdge_qi( BPy_ViewEdge *self ); + + +/*----------------------ViewEdge instance definitions ----------------------------*/ +static PyMethodDef BPy_ViewEdge_methods[] = { + {"A", ( PyCFunction ) ViewEdge_A, METH_NOARGS, "() Returns the first ViewVertex."}, + {"B", ( PyCFunction ) ViewEdge_B, METH_NOARGS, "() Returns the second ViewVertex."}, + {"fedgeA", ( PyCFunction ) ViewEdge_fedgeA, METH_NOARGS, "() Returns the first FEdge that constitues this ViewEdge."}, + {"fedgeB", ( PyCFunction ) ViewEdge_fedgeB, METH_NOARGS, "() Returns the last FEdge that constitues this ViewEdge."}, + {"viewShape", ( PyCFunction ) ViewEdge_viewShape, METH_NOARGS, "() Returns the ViewShape to which this ViewEdge belongs to . "}, + {"aShape", ( PyCFunction ) ViewEdge_aShape, METH_NOARGS, "() Returns the shape that is occluded by the ViewShape to which this ViewEdge belongs to. If no object is occluded, 0 is returned."}, + {"isClosed", ( PyCFunction ) ViewEdge_isClosed, METH_NOARGS, "() Tells whether this ViewEdge forms a closed loop or not."}, + {"getChainingTimeStamp", ( PyCFunction ) ViewEdge_getChainingTimeStamp, METH_NOARGS, "() Returns the time stamp of this ViewEdge."}, + {"setChainingTimeStamp", ( PyCFunction ) ViewEdge_setChainingTimeStamp, METH_VARARGS, "(int ts) Sets the time stamp value."}, + {"setA", ( PyCFunction ) ViewEdge_setA, METH_VARARGS, "(ViewVertex sv) Sets the first ViewVertex of the ViewEdge."}, + {"setB", ( PyCFunction ) ViewEdge_setB, METH_VARARGS, "(ViewVertex sv) Sets the last ViewVertex of the ViewEdge."}, + {"setNature", ( PyCFunction ) ViewEdge_setNature, METH_VARARGS, "(Nature n) Sets the nature of the ViewEdge."}, + {"setFEdgeA", ( PyCFunction ) ViewEdge_setFEdgeA, METH_VARARGS, "(FEdge fe) Sets the first FEdge of the ViewEdge."}, + {"setFEdgeB", ( PyCFunction ) ViewEdge_setFEdgeB, METH_VARARGS, "(FEdge fe) Sets the last FEdge of the ViewEdge."}, + {"setShape", ( PyCFunction ) ViewEdge_setShape, METH_VARARGS, "(ViewShape vs) Sets the ViewShape to which this ViewEdge belongs to."}, + {"setId", ( PyCFunction ) ViewEdge_setId, METH_VARARGS, "(Id id) Sets the ViewEdge id."}, + {"UpdateFEdges", ( PyCFunction ) ViewEdge_UpdateFEdges, METH_NOARGS, "() Sets ViewEdge to this for all embedded fedges"}, + {"setaShape", ( PyCFunction ) ViewEdge_setaShape, METH_VARARGS, "(ViewShape vs) Sets the occluded ViewShape"}, + {"setQI", ( PyCFunction ) ViewEdge_setQI, METH_VARARGS, "(int qi) Sets the quantitative invisibility value."}, + {"verticesBegin", ( PyCFunction ) ViewEdge_verticesBegin, METH_NOARGS, "() Returns an Interface0DIterator to iterate over the SVertex constituing the embedding of this ViewEdge. The returned Interface0DIterator points to the first SVertex of the ViewEdge."}, + {"verticesEnd", ( PyCFunction ) ViewEdge_verticesEnd, METH_NOARGS, "() Returns an Interface0DIterator to iterate over the SVertex constituing the embedding of this ViewEdge. The returned Interface0DIterator points after the last SVertex of the ViewEdge."}, + {"pointsBegin", ( PyCFunction ) ViewEdge_pointsBegin, METH_VARARGS, "(float t=0) Returns an Interface0DIterator to iterate over the points of this ViewEdge at a given resolution t. The returned Interface0DIterator points on the first Point of the ViewEdge."}, + {"pointsEnd", ( PyCFunction ) ViewEdge_pointsEnd, METH_VARARGS, "(float t=0) Returns an Interface0DIterator to iterate over the points of this ViewEdge at a given resolution t. The returned Interface0DIterator points after the last Point of the ViewEdge."}, + {"qi", ( PyCFunction ) ViewEdge_qi, METH_NOARGS, "() Returns the quantitative invisibility of the ViewEdge."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_ViewEdge type definition ------------------------------*/ + +PyTypeObject ViewEdge_Type = { + PyObject_HEAD_INIT(NULL) + "ViewEdge", /* tp_name */ + sizeof(BPy_ViewEdge), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ViewEdge objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_ViewEdge_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Interface1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ViewEdge___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ViewEdge___init__(BPy_ViewEdge *self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->ve = new ViewEdge(); + self->py_if1D.if1D = self->ve; + self->py_if1D.borrowed = 0; + + return 0; +} + + +PyObject * ViewEdge_A( BPy_ViewEdge *self ) { + ViewVertex *v = self->ve->A(); + if( v ){ + return Any_BPy_ViewVertex_from_ViewVertex( *v ); + } + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_B( BPy_ViewEdge *self ) { + ViewVertex *v = self->ve->B(); + if( v ){ + return Any_BPy_ViewVertex_from_ViewVertex( *v ); + } + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_fedgeA( BPy_ViewEdge *self ) { + FEdge *A = self->ve->fedgeA(); + if( A ){ + return Any_BPy_FEdge_from_FEdge( *A ); + } + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_fedgeB( BPy_ViewEdge *self ) { + FEdge *B = self->ve->fedgeB(); + if( B ){ + return Any_BPy_FEdge_from_FEdge( *B ); + } + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_viewShape( BPy_ViewEdge *self ) { + ViewShape *vs = self->ve->viewShape(); + if( vs ){ + return BPy_ViewShape_from_ViewShape( *vs ); + } + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_aShape( BPy_ViewEdge *self ) { + ViewShape *vs = self->ve->aShape(); + if( vs ){ + return BPy_ViewShape_from_ViewShape( *vs ); + } + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_isClosed( BPy_ViewEdge *self ) { + return PyBool_from_bool( self->ve->isClosed() ); +} + +PyObject * ViewEdge_getChainingTimeStamp( BPy_ViewEdge *self ) { + return PyLong_FromLong( self->ve->getChainingTimeStamp() ); +} + +PyObject * ViewEdge_setChainingTimeStamp( BPy_ViewEdge *self, PyObject *args) { + int timestamp = 0 ; + + if( !PyArg_ParseTuple(args, "i", ×tamp) ) + return NULL; + + self->ve->setChainingTimeStamp( timestamp ); + + Py_RETURN_NONE; +} + +PyObject *ViewEdge_setA( BPy_ViewEdge *self , PyObject *args) { + PyObject *py_vv; + + if(!( PyArg_ParseTuple(args, "O!", &ViewVertex_Type, &py_vv) )) + return NULL; + + self->ve->setA( ((BPy_ViewVertex *) py_vv)->vv ); + + Py_RETURN_NONE; +} + +PyObject *ViewEdge_setB( BPy_ViewEdge *self , PyObject *args) { + PyObject *py_vv; + + if(!( PyArg_ParseTuple(args, "O!", &ViewVertex_Type, &py_vv) )) + return NULL; + + self->ve->setB( ((BPy_ViewVertex *) py_vv)->vv ); + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_setNature( BPy_ViewEdge *self, PyObject *args ) { + PyObject *py_n; + + if(!( PyArg_ParseTuple(args, "O!", &Nature_Type, &py_n) )) + return NULL; + + PyObject *i = (PyObject *) &( ((BPy_Nature *) py_n)->i ); + self->ve->setNature( PyLong_AsLong(i) ); + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_setFEdgeA( BPy_ViewEdge *self, PyObject *args ) { + PyObject *py_fe; + + if(!( PyArg_ParseTuple(args, "O!", &FEdge_Type, &py_fe) )) + return NULL; + + self->ve->setFEdgeA( ((BPy_FEdge *) py_fe)->fe ); + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_setFEdgeB( BPy_ViewEdge *self, PyObject *args ) { + PyObject *py_fe; + + if(!( PyArg_ParseTuple(args, "O!", &FEdge_Type, &py_fe) )) + return NULL; + + self->ve->setFEdgeB( ((BPy_FEdge *) py_fe)->fe ); + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_setShape( BPy_ViewEdge *self, PyObject *args ) { + PyObject *py_vs; + + if(!( PyArg_ParseTuple(args, "O", &ViewShape_Type, &py_vs) )) + return NULL; + + self->ve->setShape( ((BPy_ViewShape *) py_vs)->vs ); + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_setId( BPy_ViewEdge *self, PyObject *args ) { + PyObject *py_id; + + if(!( PyArg_ParseTuple(args, "O!", &Id_Type, &py_id) )) + return NULL; + + Id id(*( ((BPy_Id *) py_id)->id )); + self->ve->setId( id ); + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_UpdateFEdges( BPy_ViewEdge *self ) { + self->ve->UpdateFEdges(); + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_setaShape( BPy_ViewEdge *self, PyObject *args ) { + PyObject *py_vs; + + if(!( PyArg_ParseTuple(args, "O!", &ViewShape_Type, &py_vs) )) + return NULL; + + ViewShape *vs = ((BPy_ViewShape *) py_vs)->vs; + self->ve->setaShape( vs ); + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_setQI( BPy_ViewEdge *self, PyObject *args ) { + int qi; + + if(!( PyArg_ParseTuple(args, "i", &qi) )) + return NULL; + + self->ve->setQI( qi ); + + Py_RETURN_NONE; +} + +PyObject * ViewEdge_verticesBegin( BPy_ViewEdge *self ) { + Interface0DIterator if0D_it( self->ve->verticesBegin() ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 0 ); +} + +PyObject * ViewEdge_verticesEnd( BPy_ViewEdge *self ) { + Interface0DIterator if0D_it( self->ve->verticesEnd() ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 1 ); +} + + +PyObject * ViewEdge_pointsBegin( BPy_ViewEdge *self, PyObject *args ) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + Interface0DIterator if0D_it( self->ve->pointsBegin(f) ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 0 ); +} + +PyObject * ViewEdge_pointsEnd( BPy_ViewEdge *self, PyObject *args ) { + float f = 0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return NULL; + + Interface0DIterator if0D_it( self->ve->pointsEnd(f) ); + return BPy_Interface0DIterator_from_Interface0DIterator( if0D_it, 1 ); +} + +PyObject * ViewEdge_qi( BPy_ViewEdge *self ) { + return PyLong_FromLong( self->ve->qi() ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h new file mode 100644 index 00000000000..ead377377e8 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_ViewEdge.h @@ -0,0 +1,32 @@ +#ifndef FREESTYLE_PYTHON_VIEWEDGE_H +#define FREESTYLE_PYTHON_VIEWEDGE_H + +#include "../../view_map/ViewMap.h" + +#include "../BPy_Interface1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ViewEdge_Type; + +#define BPy_ViewEdge_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ViewEdge_Type) ) + +/*---------------------------Python BPy_ViewEdge structure definition----------*/ +typedef struct { + BPy_Interface1D py_if1D; + ViewEdge *ve; +} BPy_ViewEdge; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_VIEWEDGE_H */ diff --git a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp new file mode 100644 index 00000000000..250d6b1b2cc --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp @@ -0,0 +1,135 @@ +#include "BPy_Chain.h" + +#include "../../BPy_Convert.h" +#include "../../BPy_Id.h" +#include "../BPy_ViewEdge.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Chain instance -----------*/ +static int Chain___init__(BPy_Chain *self, PyObject *args, PyObject *kwds); +static PyObject * Chain_push_viewedge_back( BPy_Chain *self, PyObject *args ); +static PyObject * Chain_push_viewedge_front( BPy_Chain *self, PyObject *args ); + + +/*----------------------Chain instance definitions ----------------------------*/ +static PyMethodDef BPy_Chain_methods[] = { + {"push_viewedge_back", ( PyCFunction ) Chain_push_viewedge_back, METH_VARARGS, "(ViewEdge ve, bool orientation) Adds a ViewEdge at the end of the chain."}, + {"push_viewedge_front", ( PyCFunction ) Chain_push_viewedge_front, METH_VARARGS, "(ViewEdge ve, bool orientation) Adds a ViewEdge at the beginning of the chain."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_Chain type definition ------------------------------*/ + +PyTypeObject Chain_Type = { + PyObject_HEAD_INIT(NULL) + "Chain", /* tp_name */ + sizeof(BPy_Chain), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Chain objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_Chain_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &FrsCurve_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Chain___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int Chain___init__(BPy_Chain *self, PyObject *args, PyObject *kwds) +{ + + PyObject *obj = 0; + + if (! PyArg_ParseTuple(args, "|O", &obj) ) + return -1; + + if( !obj ){ + self->c = new Chain(); + + } else if( BPy_Chain_Check(obj) ) { + self->c = new Chain(*( ((BPy_Chain *) obj)->c )); + + } else if( BPy_Id_Check(obj) ) { + self->c = new Chain(*( ((BPy_Id *) obj)->id )); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return -1; + } + + self->py_c.c = self->c; + self->py_c.py_if1D.if1D = self->c; + self->py_c.py_if1D.borrowed = 0; + + return 0; +} + + +PyObject * Chain_push_viewedge_back( BPy_Chain *self, PyObject *args ) { + PyObject *obj1 = 0, *obj2 = 0; + + if(!( PyArg_ParseTuple(args, "O!O", &ViewEdge_Type, &obj1, &obj2) )) + return NULL; + + ViewEdge *ve = ((BPy_ViewEdge *) obj1)->ve; + bool orientation = bool_from_PyBool( obj2 ); + self->c->push_viewedge_back( ve, orientation); + + Py_RETURN_NONE; +} + +PyObject * Chain_push_viewedge_front( BPy_Chain *self, PyObject *args ) { + PyObject *obj1 = 0, *obj2 = 0; + + if(!( PyArg_ParseTuple(args, "O!O", &ViewEdge_Type, &obj1, &obj2) )) + return NULL; + + ViewEdge *ve = ((BPy_ViewEdge *) obj1)->ve; + bool orientation = bool_from_PyBool( obj2 ); + self->c->push_viewedge_front(ve, orientation); + + Py_RETURN_NONE; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h new file mode 100644 index 00000000000..19f325ef513 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_CHAIN_H +#define FREESTYLE_PYTHON_CHAIN_H + +#include "../BPy_FrsCurve.h" +#include "../../../stroke/Chain.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Chain_Type; + +#define BPy_Chain_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Chain_Type) ) + +/*---------------------------Python BPy_Chain structure definition----------*/ +typedef struct { + BPy_FrsCurve py_c; + Chain *c; +} BPy_Chain; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CHAIN_H */ diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp new file mode 100644 index 00000000000..aadb322c01d --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp @@ -0,0 +1,201 @@ +#include "BPy_FEdgeSharp.h" + +#include "../../BPy_Convert.h" +#include "../../Interface0D/BPy_SVertex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for FEdgeSharp instance -----------*/ +static int FEdgeSharp___init__(BPy_FEdgeSharp *self, PyObject *args, PyObject *kwds); + +static PyObject * FEdgeSharp_normalA( BPy_FEdgeSharp *self ) ; +static PyObject * FEdgeSharp_normalB( BPy_FEdgeSharp *self ); +static PyObject * FEdgeSharp_aMaterialIndex( BPy_FEdgeSharp *self ) ; +static PyObject * FEdgeSharp_bMaterialIndex( BPy_FEdgeSharp *self ); +static PyObject * FEdgeSharp_aMaterial( BPy_FEdgeSharp *self ); +static PyObject * FEdgeSharp_bMaterial( BPy_FEdgeSharp *self ); +static PyObject * FEdgeSharp_setNormalA( BPy_FEdgeSharp *self, PyObject *args ); +static PyObject * FEdgeSharp_setNormalB( BPy_FEdgeSharp *self, PyObject *args ); +static PyObject * FEdgeSharp_setaMaterialIndex( BPy_FEdgeSharp *self, PyObject *args ); +static PyObject * FEdgeSharp_setbMaterialIndex( BPy_FEdgeSharp *self, PyObject *args ); + +/*----------------------FEdgeSharp instance definitions ----------------------------*/ +static PyMethodDef BPy_FEdgeSharp_methods[] = { + {"normalA", ( PyCFunction ) FEdgeSharp_normalA, METH_NOARGS, "() Returns the normal to the face lying on the right of the FEdge. If this FEdge is a border, it has no Face on its right and therefore, no normal."}, + {"normalB", ( PyCFunction ) FEdgeSharp_normalB, METH_NOARGS, "() Returns the normal to the face lying on the left of the FEdge."}, + {"aMaterialIndex", ( PyCFunction ) FEdgeSharp_aMaterialIndex, METH_NOARGS, "() Returns the index of the material of the face lying on the right of the FEdge. If this FEdge is a border, it has no Face on its right and therefore, no material. "}, + {"bMaterialIndex", ( PyCFunction ) FEdgeSharp_bMaterialIndex, METH_NOARGS, "() Returns the material of the face lying on the left of the FEdge. "}, + {"aMaterial", ( PyCFunction ) FEdgeSharp_aMaterial, METH_NOARGS, "() Returns the material of the face lying on the right of the FEdge. If this FEdge is a border, it has no Face on its right and therefore, no material."}, + {"bMaterial", ( PyCFunction ) FEdgeSharp_bMaterial, METH_NOARGS, "() Returns the material of the face lying on the left of the FEdge."}, + {"setNormalA", ( PyCFunction ) FEdgeSharp_setNormalA, METH_VARARGS, "([x,y,z]) Sets the normal to the face lying on the right of the FEdge."}, + {"setNormalB", ( PyCFunction ) FEdgeSharp_setNormalB, METH_VARARGS, "([x,y,z]) Sets the normal to the face lying on the left of the FEdge. "}, + {"setaMaterialIndex", ( PyCFunction ) FEdgeSharp_setaMaterialIndex, METH_VARARGS, "(unsigned int i) Sets the index of the material lying on the right of the FEdge. "}, + {"setbMaterialIndex", ( PyCFunction ) FEdgeSharp_setbMaterialIndex, METH_VARARGS, "(unsigned int i) Sets the index of the material lying on the left of the FEdge. "}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_FEdgeSharp type definition ------------------------------*/ + +PyTypeObject FEdgeSharp_Type = { + PyObject_HEAD_INIT(NULL) + "FEdgeSharp", /* tp_name */ + sizeof(BPy_FEdgeSharp), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "FEdgeSharp objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_FEdgeSharp_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &FEdge_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FEdgeSharp___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int FEdgeSharp___init__(BPy_FEdgeSharp *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj1 = 0, *obj2 = 0; + + if (! PyArg_ParseTuple(args, "|OO", &obj1, &obj2) ) + return -1; + + if( !obj1 ){ + self->fes = new FEdgeSharp(); + + } else if( !obj2 && BPy_FEdgeSharp_Check(obj1) ) { + self->fes = new FEdgeSharp(*( ((BPy_FEdgeSharp *) obj1)->fes )); + + } else if( obj2 && BPy_SVertex_Check(obj1) && BPy_SVertex_Check(obj2) ) { + self->fes = new FEdgeSharp( ((BPy_SVertex *) obj1)->sv, ((BPy_SVertex *) obj2)->sv ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument(s)"); + return -1; + } + + self->py_fe.fe = self->fes; + self->py_fe.py_if1D.if1D = self->fes; + self->py_fe.py_if1D.borrowed = 0; + + return 0; +} + + +PyObject * FEdgeSharp_normalA( BPy_FEdgeSharp *self ) { + Vec3r v( self->fes->normalA() ); + return Vector_from_Vec3r( v ); +} + +PyObject * FEdgeSharp_normalB( BPy_FEdgeSharp *self ) { + Vec3r v( self->fes->normalB() ); + return Vector_from_Vec3r( v ); +} + +PyObject * FEdgeSharp_aMaterialIndex( BPy_FEdgeSharp *self ) { + return PyLong_FromLong( self->fes->aFrsMaterialIndex() ); +} + +PyObject * FEdgeSharp_bMaterialIndex( BPy_FEdgeSharp *self ) { + return PyLong_FromLong( self->fes->bFrsMaterialIndex() ); +} + +PyObject * FEdgeSharp_aMaterial( BPy_FEdgeSharp *self ) { + FrsMaterial m( self->fes->aFrsMaterial() ); + return BPy_FrsMaterial_from_FrsMaterial(m); +} + +PyObject * FEdgeSharp_bMaterial( BPy_FEdgeSharp *self ) { + FrsMaterial m( self->fes->aFrsMaterial() ); + return BPy_FrsMaterial_from_FrsMaterial(m); +} + +PyObject * FEdgeSharp_setNormalA( BPy_FEdgeSharp *self, PyObject *args ) { + PyObject *obj = 0; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + Vec3r *v = Vec3r_ptr_from_PyObject(obj); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); + return NULL; + } + self->fes->setNormalA( *v ); + delete v; + + Py_RETURN_NONE; +} + +PyObject * FEdgeSharp_setNormalB( BPy_FEdgeSharp *self, PyObject *args ) { + PyObject *obj = 0; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + Vec3r *v = Vec3r_ptr_from_PyObject(obj); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); + return NULL; + } + self->fes->setNormalB( *v ); + delete v; + + Py_RETURN_NONE; +} + +PyObject * FEdgeSharp_setaMaterialIndex( BPy_FEdgeSharp *self, PyObject *args ) { + unsigned int i; + + if(!( PyArg_ParseTuple(args, "I", &i) )) + return NULL; + + self->fes->setaFrsMaterialIndex( i ); + + Py_RETURN_NONE; +} + +PyObject * FEdgeSharp_setbMaterialIndex( BPy_FEdgeSharp *self, PyObject *args ) { + unsigned int i; + + if(!( PyArg_ParseTuple(args, "I", &i) )) + return NULL; + + self->fes->setbFrsMaterialIndex( i ); + + Py_RETURN_NONE; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h new file mode 100644 index 00000000000..84b01e27c21 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_FEDGESHARP_H +#define FREESTYLE_PYTHON_FEDGESHARP_H + +#include "../BPy_FEdge.h" +#include "../../../view_map/Silhouette.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject FEdgeSharp_Type; + +#define BPy_FEdgeSharp_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &FEdgeSharp_Type) ) + +/*---------------------------Python BPy_FEdgeSharp structure definition----------*/ +typedef struct { + BPy_FEdge py_fe; + FEdgeSharp *fes; +} BPy_FEdgeSharp; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_FEDGESHARP_H */ diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp new file mode 100644 index 00000000000..7cef09a950a --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp @@ -0,0 +1,152 @@ +#include "BPy_FEdgeSmooth.h" + +#include "../../BPy_Convert.h" +#include "../../Interface0D/BPy_SVertex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for FEdgeSmooth instance -----------*/ +static int FEdgeSmooth___init__(BPy_FEdgeSmooth *self, PyObject *args, PyObject *kwds); + +static PyObject * FEdgeSmooth_normal( BPy_FEdgeSmooth *self ) ; +static PyObject * FEdgeSmooth_materialIndex( BPy_FEdgeSmooth *self ) ; +static PyObject * FEdgeSmooth_material( BPy_FEdgeSmooth *self ); +static PyObject * FEdgeSmooth_setNormal( BPy_FEdgeSmooth *self, PyObject *args ); +static PyObject * FEdgeSmooth_setMaterialIndex( BPy_FEdgeSmooth *self, PyObject *args ); + + +/*----------------------FEdgeSmooth instance definitions ----------------------------*/ +static PyMethodDef BPy_FEdgeSmooth_methods[] = { + {"normal", ( PyCFunction ) FEdgeSmooth_normal, METH_NOARGS, "() Returns the normal to the Face it is running accross."}, + {"materialIndex", ( PyCFunction ) FEdgeSmooth_materialIndex, METH_NOARGS, "() Returns the index of the material of the face it is running accross. "}, + {"material", ( PyCFunction ) FEdgeSmooth_material, METH_NOARGS, "() Returns the material of the face it is running accross. "}, + {"setNormal", ( PyCFunction ) FEdgeSmooth_setNormal, METH_VARARGS, "([x,y,z]) Sets the normal to the Face it is running accross."}, + {"setMaterialIndex", ( PyCFunction ) FEdgeSmooth_setMaterialIndex, METH_VARARGS, "(unsigned int i) Sets the index of the material of the face it is running accross. "}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_FEdgeSmooth type definition ------------------------------*/ + +PyTypeObject FEdgeSmooth_Type = { + PyObject_HEAD_INIT(NULL) + "FEdgeSmooth", /* tp_name */ + sizeof(BPy_FEdgeSmooth), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "FEdgeSmooth objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_FEdgeSmooth_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &FEdge_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FEdgeSmooth___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + + +int FEdgeSmooth___init__(BPy_FEdgeSmooth *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj1 = 0, *obj2 = 0; + + if (! PyArg_ParseTuple(args, "|OO", &obj1, &obj2) ) + return -1; + + if( !obj1 ){ + self->fes = new FEdgeSmooth(); + + } else if( !obj2 && BPy_FEdgeSmooth_Check(obj1) ) { + self->fes = new FEdgeSmooth(*( ((BPy_FEdgeSmooth *) obj1)->fes )); + + } else if( obj2 && BPy_SVertex_Check(obj1) && BPy_SVertex_Check(obj2) ) { + self->fes = new FEdgeSmooth( ((BPy_SVertex *) obj1)->sv, ((BPy_SVertex *) obj2)->sv ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument(s)"); + return -1; + } + + self->py_fe.fe = self->fes; + self->py_fe.py_if1D.if1D = self->fes; + self->py_fe.py_if1D.borrowed = 0; + + return 0; +} + +PyObject * FEdgeSmooth_normal( BPy_FEdgeSmooth *self ) { + Vec3r v( self->fes->normal() ); + return Vector_from_Vec3r( v ); +} + +PyObject * FEdgeSmooth_materialIndex( BPy_FEdgeSmooth *self ) { + return PyLong_FromLong( self->fes->frs_materialIndex() ); +} + + +PyObject * FEdgeSmooth_material( BPy_FEdgeSmooth *self ) { + FrsMaterial m( self->fes->frs_material() ); + return BPy_FrsMaterial_from_FrsMaterial(m); +} + +PyObject * FEdgeSmooth_setNormal( BPy_FEdgeSmooth *self, PyObject *args ) { + PyObject *obj = 0; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + Vec3r *v = Vec3r_ptr_from_PyObject(obj); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 1 must be a 3D vector (either a list of 3 elements or Vector)"); + return NULL; + } + self->fes->setNormal( *v ); + delete v; + + Py_RETURN_NONE; +} + +PyObject * FEdgeSmooth_setMaterialIndex( BPy_FEdgeSmooth *self, PyObject *args ) { + unsigned int i; + + if(!( PyArg_ParseTuple(args, "I", &i) )) + return NULL; + + self->fes->setFrsMaterialIndex( i ); + + Py_RETURN_NONE; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h new file mode 100644 index 00000000000..d7b44bb1da7 --- /dev/null +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_FEDGESMOOTH_H +#define FREESTYLE_PYTHON_FEDGESMOOTH_H + +#include "../BPy_FEdge.h" +#include "../../../view_map/Silhouette.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject FEdgeSmooth_Type; + +#define BPy_FEdgeSmooth_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &FEdgeSmooth_Type) ) + +/*---------------------------Python BPy_FEdgeSmooth structure definition----------*/ +typedef struct { + BPy_FEdge py_fe; + FEdgeSmooth *fes; +} BPy_FEdgeSmooth; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_FEDGESMOOTH_H */ diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp new file mode 100644 index 00000000000..c9f43136376 --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp @@ -0,0 +1,129 @@ +#include "BPy_AdjacencyIterator.h" + +#include "../BPy_Convert.h" +#include "../Interface0D/BPy_ViewVertex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for AdjacencyIterator instance -----------*/ +static int AdjacencyIterator___init__(BPy_AdjacencyIterator *self, PyObject *args); +static PyObject * AdjacencyIterator_iternext(BPy_AdjacencyIterator *self); + +static PyObject * AdjacencyIterator_isIncoming(BPy_AdjacencyIterator *self); +static PyObject * AdjacencyIterator_getObject(BPy_AdjacencyIterator *self); + +/*----------------------AdjacencyIterator instance definitions ----------------------------*/ +static PyMethodDef BPy_AdjacencyIterator_methods[] = { + {"isIncoming", ( PyCFunction ) AdjacencyIterator_isIncoming, METH_NOARGS, "() Returns true if the current ViewEdge is is coming towards the iteration vertex. False otherwise."}, + {"getObject", ( PyCFunction ) AdjacencyIterator_getObject, METH_NOARGS, "() Get object referenced by the iterator"}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_AdjacencyIterator type definition ------------------------------*/ + +PyTypeObject AdjacencyIterator_Type = { + PyObject_HEAD_INIT(NULL) + "AdjacencyIterator", /* tp_name */ + sizeof(BPy_AdjacencyIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "AdjacencyIterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)AdjacencyIterator_iternext, /* tp_iternext */ + BPy_AdjacencyIterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Iterator_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)AdjacencyIterator___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int AdjacencyIterator___init__(BPy_AdjacencyIterator *self, PyObject *args ) +{ + PyObject *obj1 = 0, *obj2 = 0 , *obj3 = 0; + + if (! PyArg_ParseTuple(args, "|OOO", &obj1, &obj2, &obj3) ) + return -1; + + if( !obj1 && !obj2 && !obj3 ){ + self->a_it = new AdjacencyIterator(); + + } else if( BPy_AdjacencyIterator_Check(obj1) ) { + self->a_it = new AdjacencyIterator(*( ((BPy_AdjacencyIterator *) obj1)->a_it )); + + } else if( BPy_ViewVertex_Check(obj1) ) { + bool restrictToSelection = ( obj2 ) ? bool_from_PyBool(obj2) : true; + bool restrictToUnvisited = ( obj3 ) ? bool_from_PyBool(obj3) : true; + + self->a_it = new AdjacencyIterator( ((BPy_ViewVertex *) obj1)->vv, restrictToSelection, restrictToUnvisited ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument(s)"); + return -1; + } + + self->py_it.it = self->a_it; + + return 0; + +} + +PyObject * AdjacencyIterator_iternext(BPy_AdjacencyIterator *self) { + if (self->a_it->isEnd()) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + ViewEdge *ve = self->a_it->operator*(); + self->a_it->increment(); + return BPy_ViewEdge_from_ViewEdge( *ve ); +} + +PyObject * AdjacencyIterator_isIncoming(BPy_AdjacencyIterator *self) { + return PyBool_from_bool(self->a_it->isIncoming()); +} + +PyObject * AdjacencyIterator_getObject(BPy_AdjacencyIterator *self) { + + ViewEdge *ve = self->a_it->operator*(); + if( ve ) + return BPy_ViewEdge_from_ViewEdge( *ve ); + + Py_RETURN_NONE; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h new file mode 100644 index 00000000000..733a9f2fcab --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.h @@ -0,0 +1,32 @@ +#ifndef FREESTYLE_PYTHON_ADJACENCYITERATOR_H +#define FREESTYLE_PYTHON_ADJACENCYITERATOR_H + +#include "../../stroke/ChainingIterators.h" +#include "../BPy_Iterator.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject AdjacencyIterator_Type; + +#define BPy_AdjacencyIterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &AdjacencyIterator_Type) ) + +/*---------------------------Python BPy_AdjacencyIterator structure definition----------*/ +typedef struct { + BPy_Iterator py_it; + AdjacencyIterator *a_it; +} BPy_AdjacencyIterator; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_ADJACENCYITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp new file mode 100644 index 00000000000..dbff713b6cf --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp @@ -0,0 +1,146 @@ +#include "BPy_ChainPredicateIterator.h" + +#include "../BPy_Convert.h" +#include "../BPy_BinaryPredicate1D.h" +#include "../Interface1D/BPy_ViewEdge.h" +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ChainPredicateIterator instance -----------*/ +static int ChainPredicateIterator___init__(BPy_ChainPredicateIterator *self, PyObject *args); +static void ChainPredicateIterator___dealloc__(BPy_ChainPredicateIterator *self); + +/*-----------------------BPy_ChainPredicateIterator type definition ------------------------------*/ + +PyTypeObject ChainPredicateIterator_Type = { + PyObject_HEAD_INIT(NULL) + "ChainPredicateIterator", /* tp_name */ + sizeof(BPy_ChainPredicateIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)ChainPredicateIterator___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ChainPredicateIterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &ChainingIterator_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ChainPredicateIterator___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ChainPredicateIterator___init__(BPy_ChainPredicateIterator *self, PyObject *args ) +{ + PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0, *obj4 = 0, *obj5 = 0, *obj6 = 0; + + if (!( PyArg_ParseTuple(args, "|OOOOOO", &obj1, &obj2, &obj3, &obj4, &obj5, &obj6) )) + return -1; + + if( obj1 && BPy_ChainPredicateIterator_Check(obj1) ) { + self->cp_it = new ChainPredicateIterator(*( ((BPy_ChainPredicateIterator *) obj1)->cp_it )); + self->upred = NULL; + self->bpred = NULL; + + } else if( obj1 && BPy_UnaryPredicate1D_Check(obj1) && + obj2 && BPy_BinaryPredicate1D_Check(obj2) ) { + + if (!((BPy_UnaryPredicate1D *) obj1)->up1D) { + PyErr_SetString(PyExc_TypeError, "1st argument: invalid UnaryPredicate1D object"); + return -1; + } + if (!((BPy_BinaryPredicate1D *) obj2)->bp1D) { + PyErr_SetString(PyExc_TypeError, "2nd argument: invalid BinaryPredicate1D object"); + return -1; + } + UnaryPredicate1D *up1D = ((BPy_UnaryPredicate1D *) obj1)->up1D; + BinaryPredicate1D *bp1D = ((BPy_BinaryPredicate1D *) obj2)->bp1D; + bool restrictToSelection = ( obj3 ) ? bool_from_PyBool(obj3) : true; + bool restrictToUnvisited = ( obj4 ) ? bool_from_PyBool(obj4) : true; + ViewEdge *begin; + if ( !obj5 || obj5 == Py_None ) + begin = NULL; + else if ( BPy_ViewEdge_Check(obj5) ) + begin = ((BPy_ViewEdge *) obj5)->ve; + else { + PyErr_SetString(PyExc_TypeError, "5th argument must be either a ViewEdge object or None"); + return -1; + } + bool orientation = ( obj6 ) ? bool_from_PyBool(obj6) : true; + + self->cp_it = new ChainPredicateIterator( *up1D, *bp1D, restrictToSelection, restrictToUnvisited, begin, orientation); + self->upred = obj1; + self->bpred = obj2; + Py_INCREF( self->upred ); + Py_INCREF( self->bpred ); + + } else { + bool restrictToSelection = ( obj1 ) ? bool_from_PyBool(obj1) : true; + bool restrictToUnvisited = ( obj2 ) ? bool_from_PyBool(obj2) : true; + ViewEdge *begin; + if ( !obj3 || obj3 == Py_None ) + begin = NULL; + else if ( BPy_ViewEdge_Check(obj3) ) + begin = ((BPy_ViewEdge *) obj3)->ve; + else { + PyErr_SetString(PyExc_TypeError, "3rd argument must be either a ViewEdge object or None"); + return -1; + } + bool orientation = ( obj4 ) ? bool_from_PyBool(obj4) : true; + + self->cp_it = new ChainPredicateIterator( restrictToSelection, restrictToUnvisited, begin, orientation); + self->upred = NULL; + self->bpred = NULL; + } + + self->py_c_it.c_it = self->cp_it; + self->py_c_it.py_ve_it.ve_it = self->cp_it; + self->py_c_it.py_ve_it.py_it.it = self->cp_it; + + + return 0; + +} + +void ChainPredicateIterator___dealloc__(BPy_ChainPredicateIterator *self) +{ + Py_XDECREF( self->upred ); + Py_XDECREF( self->bpred ); + ChainingIterator_Type.tp_dealloc((PyObject *)self); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h new file mode 100644 index 00000000000..5a31ac407d5 --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.h @@ -0,0 +1,35 @@ +#ifndef FREESTYLE_PYTHON_CHAINPREDICATEITERATOR_H +#define FREESTYLE_PYTHON_CHAINPREDICATEITERATOR_H + + +#include "../../stroke/ChainingIterators.h" + +#include "BPy_ChainingIterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ChainPredicateIterator_Type; + +#define BPy_ChainPredicateIterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ChainPredicateIterator_Type) ) + +/*---------------------------Python BPy_ChainPredicateIterator structure definition----------*/ +typedef struct { + BPy_ChainingIterator py_c_it; + ChainPredicateIterator *cp_it; + PyObject *upred; + PyObject *bpred; +} BPy_ChainPredicateIterator; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CHAINPREDICATEITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp new file mode 100644 index 00000000000..e6701cfc912 --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp @@ -0,0 +1,102 @@ +#include "BPy_ChainSilhouetteIterator.h" + +#include "../BPy_Convert.h" +#include "../Interface1D/BPy_ViewEdge.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ChainSilhouetteIterator instance -----------*/ +static int ChainSilhouetteIterator___init__(BPy_ChainSilhouetteIterator *self, PyObject *args); + +/*-----------------------BPy_ChainSilhouetteIterator type definition ------------------------------*/ + +PyTypeObject ChainSilhouetteIterator_Type = { + PyObject_HEAD_INIT(NULL) + "ChainSilhouetteIterator", /* tp_name */ + sizeof(BPy_ChainSilhouetteIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ChainSilhouetteIterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &ChainingIterator_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ChainSilhouetteIterator___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +// ChainSilhouetteIterator (bool iRestrictToSelection=true, ViewEdge *begin=NULL, bool orientation=true) +// ChainSilhouetteIterator (const ChainSilhouetteIterator &brother) + +int ChainSilhouetteIterator___init__(BPy_ChainSilhouetteIterator *self, PyObject *args ) +{ + PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0; + + if (!( PyArg_ParseTuple(args, "|OOO", &obj1, &obj2, &obj3) )) + return -1; + + if( obj1 && BPy_ChainSilhouetteIterator_Check(obj1) ) { + self->cs_it = new ChainSilhouetteIterator(*( ((BPy_ChainSilhouetteIterator *) obj1)->cs_it )); + + } else { + bool restrictToSelection = ( obj1 ) ? bool_from_PyBool(obj1) : true; + ViewEdge *begin; + if ( !obj2 || obj2 == Py_None ) + begin = NULL; + else if ( BPy_ViewEdge_Check(obj2) ) + begin = ((BPy_ViewEdge *) obj2)->ve; + else { + PyErr_SetString(PyExc_TypeError, "2nd argument must be either a ViewEdge object or None"); + return -1; + } + bool orientation = ( obj3 ) ? bool_from_PyBool(obj3) : true; + + self->cs_it = new ChainSilhouetteIterator( restrictToSelection, begin, orientation); + } + + self->py_c_it.c_it = self->cs_it; + self->py_c_it.py_ve_it.ve_it = self->cs_it; + self->py_c_it.py_ve_it.py_it.it = self->cs_it; + + return 0; + +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h new file mode 100644 index 00000000000..912d397d279 --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.h @@ -0,0 +1,33 @@ +#ifndef FREESTYLE_PYTHON_CHAINSILHOUETTEITERATOR_H +#define FREESTYLE_PYTHON_CHAINSILHOUETTEITERATOR_H + + +#include "../../stroke/ChainingIterators.h" + +#include "BPy_ChainingIterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ChainSilhouetteIterator_Type; + +#define BPy_ChainSilhouetteIterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ChainSilhouetteIterator_Type) ) + +/*---------------------------Python BPy_ChainSilhouetteIterator structure definition----------*/ +typedef struct { + BPy_ChainingIterator py_c_it; + ChainSilhouetteIterator *cs_it; +} BPy_ChainSilhouetteIterator; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CHAINSILHOUETTEITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp new file mode 100644 index 00000000000..7687ce88a3f --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp @@ -0,0 +1,167 @@ +#include "BPy_ChainingIterator.h" + +#include "../BPy_Convert.h" +#include "../Interface0D/BPy_ViewVertex.h" +#include "../Interface1D/BPy_ViewEdge.h" +#include "BPy_AdjacencyIterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ChainingIterator instance -----------*/ +static int ChainingIterator___init__(BPy_ChainingIterator *self, PyObject *args); +static PyObject * ChainingIterator_init( BPy_ChainingIterator *self ); +static PyObject * ChainingIterator_traverse( BPy_ChainingIterator *self, PyObject *args ); +static PyObject * ChainingIterator_getVertex( BPy_ChainingIterator *self ); +static PyObject * ChainingIterator_isIncrementing( BPy_ChainingIterator *self ); + +static PyObject * ChainingIterator_getObject( BPy_ChainingIterator *self); + +/*----------------------ChainingIterator instance definitions ----------------------------*/ +static PyMethodDef BPy_ChainingIterator_methods[] = { + {"init", ( PyCFunction ) ChainingIterator_init, METH_NOARGS, "() Inits the iterator context. This method is called each time a new chain is started. It can be used to reset some history information that you might want to keep."}, + {"traverse", ( PyCFunction ) ChainingIterator_traverse, METH_VARARGS, "(AdjacencyIterator ai) This method iterates over the potential next ViewEdges and returns the one that will be followed next. Returns the next ViewEdge to follow or 0 when the end of the chain is reached. "}, + {"getVertex", ( PyCFunction ) ChainingIterator_getVertex, METH_NOARGS, "() Returns the vertex which is the next crossing "}, + {"isIncrementing", ( PyCFunction ) ChainingIterator_isIncrementing, METH_NOARGS, "() Returns true if the current iteration is an incrementation."}, + {"getObject", ( PyCFunction ) ChainingIterator_getObject, METH_NOARGS, "() Get object referenced by the iterator"}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_ChainingIterator type definition ------------------------------*/ + +PyTypeObject ChainingIterator_Type = { + PyObject_HEAD_INIT(NULL) + "ChainingIterator", /* tp_name */ + sizeof(BPy_ChainingIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ChainingIterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_ChainingIterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &ViewEdgeIterator_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ChainingIterator___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ChainingIterator___init__(BPy_ChainingIterator *self, PyObject *args ) +{ + PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0, *obj4 = 0; + + if (!( PyArg_ParseTuple(args, "|OOOO", &obj1, &obj2, &obj3, &obj4) )) + return -1; + + if( obj1 && BPy_ChainingIterator_Check(obj1) ) { + self->c_it = new ChainingIterator(*( ((BPy_ChainingIterator *) obj1)->c_it )); + + } else { + bool restrictToSelection = ( obj1 ) ? bool_from_PyBool(obj1) : true; + bool restrictToUnvisited = ( obj2 ) ? bool_from_PyBool(obj2) : true; + ViewEdge *begin; + if ( !obj3 || obj3 == Py_None ) + begin = NULL; + else if ( BPy_ViewEdge_Check(obj3) ) + begin = ((BPy_ViewEdge *) obj3)->ve; + else { + PyErr_SetString(PyExc_TypeError, "3rd argument must be either a ViewEdge object or None"); + return -1; + } + bool orientation = ( obj4 ) ? bool_from_PyBool(obj4) : true; + + self->c_it = new ChainingIterator( restrictToSelection, restrictToUnvisited, begin, orientation); + } + + self->py_ve_it.ve_it = self->c_it; + self->py_ve_it.py_it.it = self->c_it; + + self->c_it->py_c_it = (PyObject *) self; + + return 0; +} + +PyObject *ChainingIterator_init( BPy_ChainingIterator *self ) { + if( typeid(*(self->c_it)) == typeid(ChainingIterator) ) { + PyErr_SetString(PyExc_TypeError, "init() method not properly overridden"); + return NULL; + } + self->c_it->init(); + + Py_RETURN_NONE; +} + +PyObject *ChainingIterator_traverse( BPy_ChainingIterator *self, PyObject *args ) { + PyObject *py_a_it; + + if(!( PyArg_ParseTuple(args, "O!", &AdjacencyIterator_Type, &py_a_it) )) + return NULL; + + if( typeid(*(self->c_it)) == typeid(ChainingIterator) ) { + PyErr_SetString(PyExc_TypeError, "traverse() method not properly overridden"); + return NULL; + } + if( ((BPy_AdjacencyIterator *) py_a_it)->a_it ) + self->c_it->traverse(*( ((BPy_AdjacencyIterator *) py_a_it)->a_it )); + + Py_RETURN_NONE; +} + + +PyObject *ChainingIterator_getVertex( BPy_ChainingIterator *self ) { + ViewVertex *v = self->c_it->getVertex(); + if( v ) + return Any_BPy_ViewVertex_from_ViewVertex( *v ); + + Py_RETURN_NONE; +} + +PyObject *ChainingIterator_isIncrementing( BPy_ChainingIterator *self ) { + return PyBool_from_bool( self->c_it->isIncrementing() ); +} + +PyObject * ChainingIterator_getObject( BPy_ChainingIterator *self) { + + ViewEdge *ve = self->c_it->operator*(); + if( ve ) + return BPy_ViewEdge_from_ViewEdge( *ve ); + + Py_RETURN_NONE; +} + + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h new file mode 100644 index 00000000000..2a00aa8072f --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.h @@ -0,0 +1,33 @@ +#ifndef FREESTYLE_PYTHON_CHAININGITERATOR_H +#define FREESTYLE_PYTHON_CHAININGITERATOR_H + + +#include "../../stroke/ChainingIterators.h" + +#include "BPy_ViewEdgeIterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ChainingIterator_Type; + +#define BPy_ChainingIterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ChainingIterator_Type) ) + +/*---------------------------Python BPy_ChainingIterator structure definition----------*/ +typedef struct { + BPy_ViewEdgeIterator py_ve_it; + ChainingIterator *c_it; +} BPy_ChainingIterator; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CHAININGITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp new file mode 100644 index 00000000000..ff447e77d6e --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp @@ -0,0 +1,122 @@ +#include "BPy_CurvePointIterator.h" + +#include "../BPy_Convert.h" +#include "BPy_Interface0DIterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for CurvePointIterator instance -----------*/ +static int CurvePointIterator___init__(BPy_CurvePointIterator *self, PyObject *args); +static PyObject * CurvePointIterator_t( BPy_CurvePointIterator *self ); +static PyObject * CurvePointIterator_u( BPy_CurvePointIterator *self ); +static PyObject * CurvePointIterator_castToInterface0DIterator( BPy_CurvePointIterator *self ); + +static PyObject * CurvePointIterator_getObject(BPy_CurvePointIterator *self); + +/*----------------------CurvePointIterator instance definitions ----------------------------*/ +static PyMethodDef BPy_CurvePointIterator_methods[] = { + {"t", ( PyCFunction ) CurvePointIterator_t, METH_NOARGS, "() Returns the curvilinear abscissa."}, + {"u", ( PyCFunction ) CurvePointIterator_u, METH_NOARGS, "() Returns the point parameter in the curve 0<=u<=1."}, + {"castToInterface0DIterator", ( PyCFunction ) CurvePointIterator_castToInterface0DIterator, METH_NOARGS, "() Casts this CurvePointIterator into an Interface0DIterator. Useful for any call to a function of the type UnaryFunction0D."}, + {"getObject", ( PyCFunction ) CurvePointIterator_getObject, METH_NOARGS, "() Get object referenced by the iterator"}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_CurvePointIterator type definition ------------------------------*/ + +PyTypeObject CurvePointIterator_Type = { + PyObject_HEAD_INIT(NULL) + "CurvePointIterator", /* tp_name */ + sizeof(BPy_CurvePointIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "CurvePointIterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_CurvePointIterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Iterator_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)CurvePointIterator___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int CurvePointIterator___init__(BPy_CurvePointIterator *self, PyObject *args ) +{ + PyObject *obj = 0; + + if (! PyArg_ParseTuple(args, "|O", &obj) ) + return -1; + + if( !obj ){ + self->cp_it = new CurveInternal::CurvePointIterator(); + + } else if( BPy_CurvePointIterator_Check(obj) ) { + self->cp_it = new CurveInternal::CurvePointIterator(*( ((BPy_CurvePointIterator *) obj)->cp_it )); + + } else if( PyFloat_Check(obj) ) { + self->cp_it = new CurveInternal::CurvePointIterator( PyFloat_AsDouble(obj) ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return -1; + } + + self->py_it.it = self->cp_it; + + return 0; +} + +PyObject * CurvePointIterator_t( BPy_CurvePointIterator *self ) { + return PyFloat_FromDouble( self->cp_it->t() ); +} + +PyObject * CurvePointIterator_u( BPy_CurvePointIterator *self ) { + return PyFloat_FromDouble( self->cp_it->u() ); +} + +PyObject * CurvePointIterator_castToInterface0DIterator( BPy_CurvePointIterator *self ) { + Interface0DIterator it( self->cp_it->castToInterface0DIterator() ); + return BPy_Interface0DIterator_from_Interface0DIterator( it, 0 ); +} + +PyObject * CurvePointIterator_getObject(BPy_CurvePointIterator *self) { + return BPy_CurvePoint_from_CurvePoint( self->cp_it->operator*() ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h new file mode 100644 index 00000000000..ad04c7208bb --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.h @@ -0,0 +1,32 @@ +#ifndef FREESTYLE_PYTHON_CURVEPOINTITERATOR_H +#define FREESTYLE_PYTHON_CURVEPOINTITERATOR_H + +#include "../../stroke/CurveIterators.h" + +#include "../BPy_Iterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject CurvePointIterator_Type; + +#define BPy_CurvePointIterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &CurvePointIterator_Type) ) + +/*---------------------------Python BPy_CurvePointIterator structure definition----------*/ +typedef struct { + BPy_Iterator py_it; + CurveInternal::CurvePointIterator *cp_it; +} BPy_CurvePointIterator; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CURVEPOINTITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp new file mode 100644 index 00000000000..646eeb8fc6d --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp @@ -0,0 +1,124 @@ +#include "BPy_Interface0DIterator.h" + +#include "../BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Interface0DIterator instance -----------*/ +static int Interface0DIterator___init__(BPy_Interface0DIterator *self, PyObject *args); +static PyObject * Interface0DIterator_iternext( BPy_Interface0DIterator *self ); + +static PyObject * Interface0DIterator_t( BPy_Interface0DIterator *self ); +static PyObject * Interface0DIterator_u( BPy_Interface0DIterator *self ); + +static PyObject * Interface0DIterator_getObject(BPy_Interface0DIterator *self); + +/*----------------------Interface0DIterator instance definitions ----------------------------*/ +static PyMethodDef BPy_Interface0DIterator_methods[] = { + {"t", ( PyCFunction ) Interface0DIterator_t, METH_NOARGS, "() Returns the curvilinear abscissa."}, + {"u", ( PyCFunction ) Interface0DIterator_u, METH_NOARGS, "() Returns the point parameter in the curve 0<=u<=1."}, + {"getObject", ( PyCFunction ) Interface0DIterator_getObject, METH_NOARGS, "() Get object referenced by the iterator"}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_Interface0DIterator type definition ------------------------------*/ + +PyTypeObject Interface0DIterator_Type = { + PyObject_HEAD_INIT(NULL) + "Interface0DIterator", /* tp_name */ + sizeof(BPy_Interface0DIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Interface0DIterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)Interface0DIterator_iternext, /* tp_iternext */ + BPy_Interface0DIterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Iterator_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Interface0DIterator___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int Interface0DIterator___init__(BPy_Interface0DIterator *self, PyObject *args ) +{ + PyObject *obj = 0; + + if (!( PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj) )) + return -1; + + self->if0D_it = new Interface0DIterator(*( ((BPy_Interface0DIterator *) obj)->if0D_it )); + self->py_it.it = self->if0D_it; + self->reversed = 0; + + return 0; +} + +PyObject * Interface0DIterator_iternext( BPy_Interface0DIterator *self ) { + Interface0D *if0D; + if (self->reversed) { + if (self->if0D_it->isBegin()) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + self->if0D_it->decrement(); + if0D = self->if0D_it->operator->(); + } else { + if (self->if0D_it->isEnd()) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + if0D = self->if0D_it->operator->(); + self->if0D_it->increment(); + } + return Any_BPy_Interface0D_from_Interface0D( *if0D ); +} + +PyObject * Interface0DIterator_t( BPy_Interface0DIterator *self ) { + return PyFloat_FromDouble( self->if0D_it->t() ); +} + +PyObject * Interface0DIterator_u( BPy_Interface0DIterator *self ) { + return PyFloat_FromDouble( self->if0D_it->u() ); +} + +PyObject * Interface0DIterator_getObject(BPy_Interface0DIterator *self) { + return Any_BPy_Interface0D_from_Interface0D( self->if0D_it->operator*() ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h new file mode 100644 index 00000000000..1972763b2eb --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.h @@ -0,0 +1,33 @@ +#ifndef FREESTYLE_PYTHON_INTERFACE0DITERATOR_H +#define FREESTYLE_PYTHON_INTERFACE0DITERATOR_H + +#include "../../view_map/Interface0D.h" +#include "../BPy_Iterator.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Interface0DIterator_Type; + +#define BPy_Interface0DIterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Interface0DIterator_Type) ) + +/*---------------------------Python BPy_Interface0DIterator structure definition----------*/ +typedef struct { + BPy_Iterator py_it; + Interface0DIterator *if0D_it; + int reversed; +} BPy_Interface0DIterator; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_INTERFACE0DITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp new file mode 100644 index 00000000000..efd7e0c097a --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp @@ -0,0 +1,132 @@ +#include "BPy_SVertexIterator.h" + +#include "../BPy_Convert.h" +#include "../Interface0D/BPy_SVertex.h" +#include "../Interface1D/BPy_FEdge.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for SVertexIterator instance -----------*/ +static int SVertexIterator___init__(BPy_SVertexIterator *self, PyObject *args); + +static PyObject * SVertexIterator_t( BPy_SVertexIterator *self ); +static PyObject * SVertexIterator_u( BPy_SVertexIterator *self ); + +static PyObject * SVertexIterator_getObject( BPy_SVertexIterator *self); + +/*----------------------SVertexIterator instance definitions ----------------------------*/ +static PyMethodDef BPy_SVertexIterator_methods[] = { + {"t", ( PyCFunction ) SVertexIterator_t, METH_NOARGS, "() Returns the curvilinear abscissa."}, + {"u", ( PyCFunction ) SVertexIterator_u, METH_NOARGS, "() Returns the point parameter in the curve 0<=u<=1."}, + {"getObject", ( PyCFunction ) SVertexIterator_getObject, METH_NOARGS, "() Get object referenced by the iterator"}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_SVertexIterator type definition ------------------------------*/ + +PyTypeObject SVertexIterator_Type = { + PyObject_HEAD_INIT(NULL) + "SVertexIterator", /* tp_name */ + sizeof(BPy_SVertexIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "SVertexIterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_SVertexIterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Iterator_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)SVertexIterator___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int SVertexIterator___init__(BPy_SVertexIterator *self, PyObject *args ) +{ + PyObject *obj1 = 0, *obj2 = 0, *obj3 = 0, *obj4 = 0; + float f = 0; + + if (! PyArg_ParseTuple(args, "|OOOOf", &obj1, &obj2, &obj3, &obj4, f) ) + return -1; + + if( !obj1 ){ + self->sv_it = new ViewEdgeInternal::SVertexIterator(); + + } else if( BPy_SVertexIterator_Check(obj1) ) { + self->sv_it = new ViewEdgeInternal::SVertexIterator(*( ((BPy_SVertexIterator *) obj1)->sv_it )); + + } else if( obj1 && BPy_SVertex_Check(obj1) && + obj2 && BPy_SVertex_Check(obj2) && + obj3 && BPy_FEdge_Check(obj3) && + obj4 && BPy_FEdge_Check(obj4) ) { + + self->sv_it = new ViewEdgeInternal::SVertexIterator( + ((BPy_SVertex *) obj1)->sv, + ((BPy_SVertex *) obj2)->sv, + ((BPy_FEdge *) obj3)->fe, + ((BPy_FEdge *) obj4)->fe, + f ); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument(s)"); + return -1; + } + + self->py_it.it = self->sv_it; + + return 0; +} + +PyObject * SVertexIterator_t( BPy_SVertexIterator *self ) { + return PyFloat_FromDouble( self->sv_it->t() ); +} + +PyObject * SVertexIterator_u( BPy_SVertexIterator *self ) { + return PyFloat_FromDouble( self->sv_it->u() ); +} + +PyObject * SVertexIterator_getObject( BPy_SVertexIterator *self) { + SVertex *sv = self->sv_it->operator->(); + + if( sv ) + return BPy_SVertex_from_SVertex( *sv ); + + Py_RETURN_NONE; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h new file mode 100644 index 00000000000..b40f4d36420 --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.h @@ -0,0 +1,33 @@ +#ifndef FREESTYLE_PYTHON_SVERTEXITERATOR_H +#define FREESTYLE_PYTHON_SVERTEXITERATOR_H + +#include "../../view_map/ViewMapIterators.h" + +#include "../BPy_Iterator.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject SVertexIterator_Type; + +#define BPy_SVertexIterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &SVertexIterator_Type) ) + +/*---------------------------Python BPy_SVertexIterator structure definition----------*/ +typedef struct { + BPy_Iterator py_it; + ViewEdgeInternal::SVertexIterator *sv_it; +} BPy_SVertexIterator; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_SVERTEXITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp new file mode 100644 index 00000000000..8ca23a94461 --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp @@ -0,0 +1,146 @@ +#include "BPy_StrokeVertexIterator.h" + +#include "../BPy_Convert.h" +#include "BPy_Interface0DIterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for StrokeVertexIterator instance -----------*/ +static int StrokeVertexIterator___init__(BPy_StrokeVertexIterator *self, PyObject *args); +static PyObject * StrokeVertexIterator_iternext( BPy_StrokeVertexIterator *self ); +static PyObject * StrokeVertexIterator_t( BPy_StrokeVertexIterator *self ); +static PyObject * StrokeVertexIterator_u( BPy_StrokeVertexIterator *self ); +static PyObject * StrokeVertexIterator_castToInterface0DIterator( BPy_StrokeVertexIterator *self ); + +static PyObject * StrokeVertexIterator_getObject( BPy_StrokeVertexIterator *self); + + +/*----------------------StrokeVertexIterator instance definitions ----------------------------*/ +static PyMethodDef BPy_StrokeVertexIterator_methods[] = { + {"t", ( PyCFunction ) StrokeVertexIterator_t, METH_NOARGS, "() Returns the curvilinear abscissa."}, + {"u", ( PyCFunction ) StrokeVertexIterator_u, METH_NOARGS, "() Returns the point parameter in the curve 0<=u<=1."}, + {"castToInterface0DIterator", ( PyCFunction ) StrokeVertexIterator_castToInterface0DIterator, METH_NOARGS, "() Casts this StrokeVertexIterator into an Interface0DIterator. Useful for any call to a function of the type UnaryFunction0D."}, + {"getObject", ( PyCFunction ) StrokeVertexIterator_getObject, METH_NOARGS, "() Get object referenced by the iterator"}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_StrokeVertexIterator type definition ------------------------------*/ + +PyTypeObject StrokeVertexIterator_Type = { + PyObject_HEAD_INIT(NULL) + "StrokeVertexIterator", /* tp_name */ + sizeof(BPy_StrokeVertexIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "StrokeVertexIterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)StrokeVertexIterator_iternext, /* tp_iternext */ + BPy_StrokeVertexIterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Iterator_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)StrokeVertexIterator___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int StrokeVertexIterator___init__(BPy_StrokeVertexIterator *self, PyObject *args ) +{ + PyObject *obj = 0; + + if (! PyArg_ParseTuple(args, "|O", &obj) ) + return -1; + + if( !obj ){ + self->sv_it = new StrokeInternal::StrokeVertexIterator(); + + } else if( BPy_StrokeVertexIterator_Check(obj) ) { + self->sv_it = new StrokeInternal::StrokeVertexIterator(*( ((BPy_StrokeVertexIterator *) obj)->sv_it )); + + } else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return -1; + } + + self->py_it.it = self->sv_it; + self->reversed = 0; + + return 0; +} + +PyObject * StrokeVertexIterator_iternext( BPy_StrokeVertexIterator *self ) { + StrokeVertex *sv; + if (self->reversed) { + if (self->sv_it->isBegin()) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + self->sv_it->decrement(); + sv = self->sv_it->operator->(); + } else { + if (self->sv_it->isEnd()) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + sv = self->sv_it->operator->(); + self->sv_it->increment(); + } + return BPy_StrokeVertex_from_StrokeVertex( *sv ); +} + +PyObject * StrokeVertexIterator_t( BPy_StrokeVertexIterator *self ) { + return PyFloat_FromDouble( self->sv_it->t() ); +} + +PyObject * StrokeVertexIterator_u( BPy_StrokeVertexIterator *self ) { + return PyFloat_FromDouble( self->sv_it->u() ); +} + +PyObject * StrokeVertexIterator_castToInterface0DIterator( BPy_StrokeVertexIterator *self ) { + Interface0DIterator it( self->sv_it->castToInterface0DIterator() ); + return BPy_Interface0DIterator_from_Interface0DIterator( it, 0 ); +} + +PyObject * StrokeVertexIterator_getObject( BPy_StrokeVertexIterator *self) { + StrokeVertex *sv = self->sv_it->operator->(); + if( sv ) + return BPy_StrokeVertex_from_StrokeVertex( *sv ); + + Py_RETURN_NONE; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h new file mode 100644 index 00000000000..0c4b6e4bb6c --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.h @@ -0,0 +1,33 @@ +#ifndef FREESTYLE_PYTHON_STROKEVERTEXITERATOR_H +#define FREESTYLE_PYTHON_STROKEVERTEXITERATOR_H + +#include "../../stroke/StrokeIterators.h" + +#include "../BPy_Iterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject StrokeVertexIterator_Type; + +#define BPy_StrokeVertexIterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &StrokeVertexIterator_Type) ) + +/*---------------------------Python BPy_StrokeVertexIterator structure definition----------*/ +typedef struct { + BPy_Iterator py_it; + StrokeInternal::StrokeVertexIterator *sv_it; + int reversed; +} BPy_StrokeVertexIterator; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_STROKEVERTEXITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp new file mode 100644 index 00000000000..3d094f4cef2 --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp @@ -0,0 +1,191 @@ +#include "BPy_ViewEdgeIterator.h" + +#include "../BPy_Convert.h" +#include "../Interface1D/BPy_ViewEdge.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ViewEdgeIterator instance -----------*/ +static int ViewEdgeIterator___init__(BPy_ViewEdgeIterator *self, PyObject *args); + +static PyObject * ViewEdgeIterator_getCurrentEdge( BPy_ViewEdgeIterator *self ); +static PyObject * ViewEdgeIterator_setCurrentEdge( BPy_ViewEdgeIterator *self, PyObject *args ); +static PyObject * ViewEdgeIterator_getBegin( BPy_ViewEdgeIterator *self ); +static PyObject * ViewEdgeIterator_setBegin( BPy_ViewEdgeIterator *self, PyObject *args ); +static PyObject * ViewEdgeIterator_getOrientation( BPy_ViewEdgeIterator *self ); +static PyObject * ViewEdgeIterator_setOrientation( BPy_ViewEdgeIterator *self, PyObject *args ); +static PyObject * ViewEdgeIterator_changeOrientation( BPy_ViewEdgeIterator *self ); + +static PyObject * ViewEdgeIterator_getObject(BPy_ViewEdgeIterator *self); + + +/*----------------------ViewEdgeIterator instance definitions ----------------------------*/ +static PyMethodDef BPy_ViewEdgeIterator_methods[] = { + {"getCurrentEdge", ( PyCFunction ) ViewEdgeIterator_getCurrentEdge, METH_NOARGS, "() Returns the current pointed ViewEdge."}, + {"setCurrentEdge", ( PyCFunction ) ViewEdgeIterator_setCurrentEdge, METH_VARARGS, "(ViewEdge ve) Sets the current pointed ViewEdge. "}, + {"getBegin", ( PyCFunction ) ViewEdgeIterator_getBegin, METH_NOARGS, "() Returns the first ViewEdge used for the iteration."}, + {"setBegin", ( PyCFunction ) ViewEdgeIterator_setBegin, METH_VARARGS, "(ViewEdge ve) Sets the first ViewEdge used for the iteration."}, + {"getOrientation", ( PyCFunction ) ViewEdgeIterator_getOrientation, METH_NOARGS, "() Gets the orientation of the pointed ViewEdge in the iteration. "}, + {"setOrientation", ( PyCFunction ) ViewEdgeIterator_setOrientation, METH_VARARGS, "(bool b) Sets the orientation of the pointed ViewEdge in the iteration. "}, + {"changeOrientation", ( PyCFunction ) ViewEdgeIterator_changeOrientation, METH_NOARGS, "() Changes the current orientation."}, + {"getObject", ( PyCFunction ) ViewEdgeIterator_getObject, METH_NOARGS, "() Get object referenced by the iterator"}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_ViewEdgeIterator type definition ------------------------------*/ + +PyTypeObject ViewEdgeIterator_Type = { + PyObject_HEAD_INIT(NULL) + "ViewEdgeIterator", /* tp_name */ + sizeof(BPy_ViewEdgeIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ViewEdgeIterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_ViewEdgeIterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Iterator_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ViewEdgeIterator___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ViewEdgeIterator___init__(BPy_ViewEdgeIterator *self, PyObject *args ) +{ + PyObject *obj1 = 0, *obj2 = 0; + + if (!( PyArg_ParseTuple(args, "O|O", &obj1, &obj2) )) + return -1; + + if( obj1 && BPy_ViewEdgeIterator_Check(obj1) ) { + self->ve_it = new ViewEdgeInternal::ViewEdgeIterator(*( ((BPy_ViewEdgeIterator *) obj1)->ve_it )); + + } else { + ViewEdge *begin; + if ( !obj1 || obj1 == Py_None ) + begin = NULL; + else if ( BPy_ViewEdge_Check(obj1) ) + begin = ((BPy_ViewEdge *) obj1)->ve; + else { + PyErr_SetString(PyExc_TypeError, "1st argument must be either a ViewEdge object or None"); + return -1; + } + bool orientation = ( obj2 ) ? bool_from_PyBool(obj2) : true; + + self->ve_it = new ViewEdgeInternal::ViewEdgeIterator( begin, orientation); + + } + + self->py_it.it = self->ve_it; + + return 0; +} + + +PyObject *ViewEdgeIterator_getCurrentEdge( BPy_ViewEdgeIterator *self ) { + ViewEdge *ve = self->ve_it->getCurrentEdge(); + if( ve ) + return BPy_ViewEdge_from_ViewEdge( *ve ); + + Py_RETURN_NONE; +} + +PyObject *ViewEdgeIterator_setCurrentEdge( BPy_ViewEdgeIterator *self, PyObject *args ) { + PyObject *py_ve; + + if(!( PyArg_ParseTuple(args, "O!", &ViewEdge_Type, &py_ve) )) + return NULL; + + self->ve_it->setCurrentEdge( ((BPy_ViewEdge *) py_ve)->ve ); + + Py_RETURN_NONE; +} + + +PyObject *ViewEdgeIterator_getBegin( BPy_ViewEdgeIterator *self ) { + ViewEdge *ve = self->ve_it->getBegin(); + if( ve ) + return BPy_ViewEdge_from_ViewEdge( *ve ); + + Py_RETURN_NONE; +} + +PyObject *ViewEdgeIterator_setBegin( BPy_ViewEdgeIterator *self, PyObject *args ) { + PyObject *py_ve; + + if(!( PyArg_ParseTuple(args, "O!", &ViewEdge_Type, &py_ve) )) + return NULL; + + self->ve_it->setBegin( ((BPy_ViewEdge *) py_ve)->ve ); + + Py_RETURN_NONE; +} + +PyObject *ViewEdgeIterator_getOrientation( BPy_ViewEdgeIterator *self ) { + return PyBool_from_bool( self->ve_it->getOrientation() ); +} + +PyObject *ViewEdgeIterator_setOrientation( BPy_ViewEdgeIterator *self, PyObject *args ) { + PyObject *py_b; + + if(!( PyArg_ParseTuple(args, "O", &py_b) )) + return NULL; + + self->ve_it->setOrientation( bool_from_PyBool(py_b) ); + + Py_RETURN_NONE; +} + +PyObject *ViewEdgeIterator_changeOrientation( BPy_ViewEdgeIterator *self ) { + self->ve_it->changeOrientation(); + + Py_RETURN_NONE; +} + +PyObject * ViewEdgeIterator_getObject( BPy_ViewEdgeIterator *self) { + + ViewEdge *ve = self->ve_it->operator*(); + if( ve ) + return BPy_ViewEdge_from_ViewEdge( *ve ); + + Py_RETURN_NONE; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h new file mode 100644 index 00000000000..dce90efc8cf --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.h @@ -0,0 +1,33 @@ +#ifndef FREESTYLE_PYTHON_VIEWEDGEITERATOR_H +#define FREESTYLE_PYTHON_VIEWEDGEITERATOR_H + + +#include "../../view_map/ViewMapIterators.h" + +#include "../BPy_Iterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ViewEdgeIterator_Type; + +#define BPy_ViewEdgeIterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ViewEdgeIterator_Type) ) + +/*---------------------------Python BPy_ViewEdgeIterator structure definition----------*/ +typedef struct { + BPy_Iterator py_it; + ViewEdgeInternal::ViewEdgeIterator *ve_it; +} BPy_ViewEdgeIterator; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_VIEWEDGEITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp new file mode 100644 index 00000000000..071472dea69 --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.cpp @@ -0,0 +1,119 @@ +#include "BPy_orientedViewEdgeIterator.h" + +#include "../BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for orientedViewEdgeIterator instance -----------*/ +static int orientedViewEdgeIterator___init__(BPy_orientedViewEdgeIterator *self, PyObject *args); +static PyObject * orientedViewEdgeIterator_iternext(BPy_orientedViewEdgeIterator *self); + +static PyObject * orientedViewEdgeIterator_getObject(BPy_orientedViewEdgeIterator *self); + + +/*----------------------orientedViewEdgeIterator instance definitions ----------------------------*/ +static PyMethodDef BPy_orientedViewEdgeIterator_methods[] = { + {"getObject", ( PyCFunction ) orientedViewEdgeIterator_getObject, METH_NOARGS, "() Get object referenced by the iterator"}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_orientedViewEdgeIterator type definition ------------------------------*/ + +PyTypeObject orientedViewEdgeIterator_Type = { + PyObject_HEAD_INIT(NULL) + "orientedViewEdgeIterator", /* tp_name */ + sizeof(BPy_orientedViewEdgeIterator), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "orientedViewEdgeIterator objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)orientedViewEdgeIterator_iternext, /* tp_iternext */ + BPy_orientedViewEdgeIterator_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &Iterator_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)orientedViewEdgeIterator___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int orientedViewEdgeIterator___init__(BPy_orientedViewEdgeIterator *self, PyObject *args ) +{ + PyObject *obj = 0; + + if (!( PyArg_ParseTuple(args, "|O", &obj) )) + return -1; + + if( !obj ) + self->ove_it = new ViewVertexInternal::orientedViewEdgeIterator(); + else if( BPy_orientedViewEdgeIterator_Check(obj) ) + self->ove_it = new ViewVertexInternal::orientedViewEdgeIterator(*( ((BPy_orientedViewEdgeIterator *) obj)->ove_it )); + else { + PyErr_SetString(PyExc_TypeError, "invalid argument"); + return -1; + } + + self->py_it.it = self->ove_it; + self->reversed = 0; + + return 0; +} + +PyObject * orientedViewEdgeIterator_iternext( BPy_orientedViewEdgeIterator *self ) { + ViewVertex::directedViewEdge *dve; + if (self->reversed) { + if (self->ove_it->isBegin()) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + self->ove_it->decrement(); + dve = self->ove_it->operator->(); + } else { + if (self->ove_it->isEnd()) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + dve = self->ove_it->operator->(); + self->ove_it->increment(); + } + return BPy_directedViewEdge_from_directedViewEdge( *dve ); +} + +PyObject * orientedViewEdgeIterator_getObject( BPy_orientedViewEdgeIterator *self) { + return BPy_directedViewEdge_from_directedViewEdge( self->ove_it->operator*() ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h new file mode 100644 index 00000000000..cd9edf1e224 --- /dev/null +++ b/source/blender/freestyle/intern/python/Iterator/BPy_orientedViewEdgeIterator.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_ORIENTEDVIEWEDGEITERATOR_H +#define FREESTYLE_PYTHON_ORIENTEDVIEWEDGEITERATOR_H + +#include "../../stroke/Stroke.h" +#include "../../view_map/ViewMapIterators.h" + +#include "../BPy_Iterator.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject orientedViewEdgeIterator_Type; + +#define BPy_orientedViewEdgeIterator_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &orientedViewEdgeIterator_Type) ) + +/*---------------------------Python BPy_orientedViewEdgeIterator structure definition----------*/ +typedef struct { + BPy_Iterator py_it; + ViewVertexInternal::orientedViewEdgeIterator *ove_it; + int reversed; +} BPy_orientedViewEdgeIterator; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_ORIENTEDVIEWEDGEITERATOR_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp new file mode 100644 index 00000000000..5e898efd368 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_BackboneStretcherShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for BackboneStretcherShader instance -----------*/ +static int BackboneStretcherShader___init__( BPy_BackboneStretcherShader* self, PyObject *args); + +/*-----------------------BPy_BackboneStretcherShader type definition ------------------------------*/ + +PyTypeObject BackboneStretcherShader_Type = { + PyObject_HEAD_INIT(NULL) + "BackboneStretcherShader", /* tp_name */ + sizeof(BPy_BackboneStretcherShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "BackboneStretcherShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)BackboneStretcherShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int BackboneStretcherShader___init__( BPy_BackboneStretcherShader* self, PyObject *args) +{ + float f = 2.0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return -1; + + self->py_ss.ss = new StrokeShaders::BackboneStretcherShader(f); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h new file mode 100644 index 00000000000..35a74c0bda2 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_BACKBONESTRETCHERSHADER_H +#define FREESTYLE_PYTHON_BACKBONESTRETCHERSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject BackboneStretcherShader_Type; + +#define BPy_BackboneStretcherShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &BackboneStretcherShader_Type) ) + +/*---------------------------Python BPy_BackboneStretcherShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_BackboneStretcherShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_BACKBONESTRETCHERSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp new file mode 100644 index 00000000000..6151243acc9 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_BezierCurveShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for BezierCurveShader instance -----------*/ +static int BezierCurveShader___init__( BPy_BezierCurveShader* self, PyObject *args); + +/*-----------------------BPy_BezierCurveShader type definition ------------------------------*/ + +PyTypeObject BezierCurveShader_Type = { + PyObject_HEAD_INIT(NULL) + "BezierCurveShader", /* tp_name */ + sizeof(BPy_BezierCurveShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "BezierCurveShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)BezierCurveShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int BezierCurveShader___init__( BPy_BezierCurveShader* self, PyObject *args) +{ + float f = 4.0; + + if(!( PyArg_ParseTuple(args, "|f", &f) )) + return -1; + + self->py_ss.ss = new StrokeShaders::BezierCurveShader(f); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h new file mode 100644 index 00000000000..b94ef88acea --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_BEZIERCURVESHADER_H +#define FREESTYLE_PYTHON_BEZIERCURVESHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject BezierCurveShader_Type; + +#define BPy_BezierCurveShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &BezierCurveShader_Type) ) + +/*---------------------------Python BPy_BezierCurveShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_BezierCurveShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_BEZIERCURVESHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp new file mode 100644 index 00000000000..ffc073485d6 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp @@ -0,0 +1,84 @@ +#include "BPy_CalligraphicShader.h" + +#include "../../stroke/AdvancedStrokeShaders.h" +#include "../BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for CalligraphicShader instance -----------*/ +static int CalligraphicShader___init__( BPy_CalligraphicShader* self, PyObject *args); + +/*-----------------------BPy_CalligraphicShader type definition ------------------------------*/ + +PyTypeObject CalligraphicShader_Type = { + PyObject_HEAD_INIT(NULL) + "CalligraphicShader", /* tp_name */ + sizeof(BPy_CalligraphicShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "CalligraphicShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)CalligraphicShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int CalligraphicShader___init__( BPy_CalligraphicShader* self, PyObject *args) +{ + double d1, d2; + PyObject *obj3 = 0, *obj4 = 0; + + + if(!( PyArg_ParseTuple(args, "ddOO", &d1, &d2, &obj3, &obj4) )) + return -1; + Vec2f *v = Vec2f_ptr_from_PyObject(obj3); + if( !v ) { + PyErr_SetString(PyExc_TypeError, "argument 3 must be a 2D vector (either a list of 2 elements or Vector)"); + return -1; + } + self->py_ss.ss = new CalligraphicShader(d1, d2, *v, bool_from_PyBool(obj4) ); + delete v; + + return 0; + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h new file mode 100644 index 00000000000..c573b0184ad --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_CALLIGRAPHICSHADER_H +#define FREESTYLE_PYTHON_CALLIGRAPHICSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject CalligraphicShader_Type; + +#define BPy_CalligraphicShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &CalligraphicShader_Type) + +/*---------------------------Python BPy_CalligraphicShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_CalligraphicShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_CALLIGRAPHICSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp new file mode 100644 index 00000000000..df789bca729 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_ColorNoiseShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ColorNoiseShader instance -----------*/ +static int ColorNoiseShader___init__( BPy_ColorNoiseShader* self, PyObject *args); + +/*-----------------------BPy_ColorNoiseShader type definition ------------------------------*/ + +PyTypeObject ColorNoiseShader_Type = { + PyObject_HEAD_INIT(NULL) + "ColorNoiseShader", /* tp_name */ + sizeof(BPy_ColorNoiseShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ColorNoiseShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ColorNoiseShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ColorNoiseShader___init__( BPy_ColorNoiseShader* self, PyObject *args) +{ + float f1, f2; + + if(!( PyArg_ParseTuple(args, "ff", &f1, &f2) )) + return -1; + + self->py_ss.ss = new StrokeShaders::ColorNoiseShader(f1, f2); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h new file mode 100644 index 00000000000..694b847565e --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_COLORNOISESHADER_H +#define FREESTYLE_PYTHON_COLORNOISESHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ColorNoiseShader_Type; + +#define BPy_ColorNoiseShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ColorNoiseShader_Type) ) + +/*---------------------------Python BPy_ColorNoiseShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_ColorNoiseShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_COLORNOISESHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.cpp new file mode 100644 index 00000000000..7e35e5398bd --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.cpp @@ -0,0 +1,77 @@ +#include "BPy_ColorVariationPatternShader.h" + +#include "../../stroke/BasicStrokeShaders.h" +#include "../BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ColorVariationPatternShader instance -----------*/ +static int ColorVariationPatternShader___init__( BPy_ColorVariationPatternShader* self, PyObject *args); + +/*-----------------------BPy_ColorVariationPatternShader type definition ------------------------------*/ + +PyTypeObject ColorVariationPatternShader_Type = { + PyObject_HEAD_INIT(NULL) + "ColorVariationPatternShader", /* tp_name */ + sizeof(BPy_ColorVariationPatternShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ColorVariationPatternShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ColorVariationPatternShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ColorVariationPatternShader___init__( BPy_ColorVariationPatternShader* self, PyObject *args) +{ + const char *s; + PyObject *obj = 0; + + if(!( PyArg_ParseTuple(args, "s|O", &s, &obj) )) + return -1; + + bool b = (obj) ? bool_from_PyBool(obj) : true; + self->py_ss.ss = new StrokeShaders::ColorVariationPatternShader(s,b); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.h new file mode 100644 index 00000000000..b1898ebfecf --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_COLORVARIATIONPATTERNSHADER_H +#define FREESTYLE_PYTHON_COLORVARIATIONPATTERNSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ColorVariationPatternShader_Type; + +#define BPy_ColorVariationPatternShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ColorVariationPatternShader_Type) ) + +/*---------------------------Python BPy_ColorVariationPatternShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_ColorVariationPatternShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_COLORVARIATIONPATTERNSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp new file mode 100644 index 00000000000..7e7bed6b967 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_ConstantColorShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ConstantColorShader instance -----------*/ +static int ConstantColorShader___init__( BPy_ConstantColorShader* self, PyObject *args); + +/*-----------------------BPy_ConstantColorShader type definition ------------------------------*/ + +PyTypeObject ConstantColorShader_Type = { + PyObject_HEAD_INIT(NULL) + "ConstantColorShader", /* tp_name */ + sizeof(BPy_ConstantColorShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ConstantColorShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ConstantColorShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ConstantColorShader___init__( BPy_ConstantColorShader* self, PyObject *args) +{ + float f1, f2, f3, f4 = 1.0; + + if(!( PyArg_ParseTuple(args, "fff|f", &f1, &f2, &f3, &f4) )) + return -1; + + self->py_ss.ss = new StrokeShaders::ConstantColorShader(f1, f2, f3, f4); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h new file mode 100644 index 00000000000..30a09d852fd --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_CONSTANTCOLORSHADER_H +#define FREESTYLE_PYTHON_CONSTANTCOLORSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ConstantColorShader_Type; + +#define BPy_ConstantColorShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ConstantColorShader_Type) ) + +/*---------------------------Python BPy_ConstantColorShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_ConstantColorShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_CONSTANTCOLORSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp new file mode 100644 index 00000000000..b6519fca2c8 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_ConstantThicknessShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ConstantThicknessShader instance -----------*/ +static int ConstantThicknessShader___init__( BPy_ConstantThicknessShader* self, PyObject *args); + +/*-----------------------BPy_ConstantThicknessShader type definition ------------------------------*/ + +PyTypeObject ConstantThicknessShader_Type = { + PyObject_HEAD_INIT(NULL) + "ConstantThicknessShader", /* tp_name */ + sizeof(BPy_ConstantThicknessShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ConstantThicknessShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ConstantThicknessShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ConstantThicknessShader___init__( BPy_ConstantThicknessShader* self, PyObject *args) +{ + float f; + + if(!( PyArg_ParseTuple(args, "f", &f) )) + return -1; + + self->py_ss.ss = new StrokeShaders::ConstantThicknessShader(f); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h new file mode 100644 index 00000000000..bb7f3c0f622 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_CONSTANTTHICKNESSSHADER_H +#define FREESTYLE_PYTHON_CONSTANTTHICKNESSSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ConstantThicknessShader_Type; + +#define BPy_ConstantThicknessShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ConstantThicknessShader_Type) ) + +/*---------------------------Python BPy_ConstantThicknessShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_ConstantThicknessShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_CONSTANTTHICKNESSSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp new file mode 100644 index 00000000000..f5705812cde --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_ConstrainedIncreasingThicknessShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ConstrainedIncreasingThicknessShader instance -----------*/ +static int ConstrainedIncreasingThicknessShader___init__( BPy_ConstrainedIncreasingThicknessShader* self, PyObject *args); + +/*-----------------------BPy_ConstrainedIncreasingThicknessShader type definition ------------------------------*/ + +PyTypeObject ConstrainedIncreasingThicknessShader_Type = { + PyObject_HEAD_INIT(NULL) + "ConstrainedIncreasingThicknessShader", /* tp_name */ + sizeof(BPy_ConstrainedIncreasingThicknessShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ConstrainedIncreasingThicknessShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ConstrainedIncreasingThicknessShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ConstrainedIncreasingThicknessShader___init__( BPy_ConstrainedIncreasingThicknessShader* self, PyObject *args) +{ + float f1, f2, f3; + + if(!( PyArg_ParseTuple(args, "fff", &f1, &f2, &f3) )) + return -1; + + self->py_ss.ss = new StrokeShaders::ConstrainedIncreasingThicknessShader(f1, f2, f3); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h new file mode 100644 index 00000000000..38a8aa2bfe0 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_CONSTRAINEDINCREASINGTHICKNESSSHADER_H +#define FREESTYLE_PYTHON_CONSTRAINEDINCREASINGTHICKNESSSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ConstrainedIncreasingThicknessShader_Type; + +#define BPy_ConstrainedIncreasingThicknessShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ConstrainedIncreasingThicknessShader_Type) ) + +/*---------------------------Python BPy_ConstrainedIncreasingThicknessShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_ConstrainedIncreasingThicknessShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_CONSTRAINEDINCREASINGTHICKNESSSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp new file mode 100644 index 00000000000..3e1a7c0f858 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_GuidingLinesShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GuidingLinesShader instance -----------*/ +static int GuidingLinesShader___init__( BPy_GuidingLinesShader* self, PyObject *args); + +/*-----------------------BPy_GuidingLinesShader type definition ------------------------------*/ + +PyTypeObject GuidingLinesShader_Type = { + PyObject_HEAD_INIT(NULL) + "GuidingLinesShader", /* tp_name */ + sizeof(BPy_GuidingLinesShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GuidingLinesShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GuidingLinesShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GuidingLinesShader___init__( BPy_GuidingLinesShader* self, PyObject *args) +{ + float f; + + if(!( PyArg_ParseTuple(args, "f", &f) )) + return -1; + + self->py_ss.ss = new StrokeShaders::GuidingLinesShader(f); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h new file mode 100644 index 00000000000..e25704c33ba --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_GUIDINGLINESSHADER_H +#define FREESTYLE_PYTHON_GUIDINGLINESSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GuidingLinesShader_Type; + +#define BPy_GuidingLinesShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GuidingLinesShader_Type) ) + +/*---------------------------Python BPy_GuidingLinesShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_GuidingLinesShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_GUIDINGLINESSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp new file mode 100644 index 00000000000..c418ffe832e --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_IncreasingColorShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for IncreasingColorShader instance -----------*/ +static int IncreasingColorShader___init__( BPy_IncreasingColorShader* self, PyObject *args); + +/*-----------------------BPy_IncreasingColorShader type definition ------------------------------*/ + +PyTypeObject IncreasingColorShader_Type = { + PyObject_HEAD_INIT(NULL) + "IncreasingColorShader", /* tp_name */ + sizeof(BPy_IncreasingColorShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "IncreasingColorShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)IncreasingColorShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int IncreasingColorShader___init__( BPy_IncreasingColorShader* self, PyObject *args) +{ + float f1, f2, f3, f4, f5, f6, f7, f8; + + if(!( PyArg_ParseTuple(args, "ffffffff", &f1, &f2, &f3, &f4, &f5, &f6, &f7, &f8) )) + return -1; + + self->py_ss.ss = new StrokeShaders::IncreasingColorShader(f1, f2, f3, f4, f5, f6, f7, f8); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h new file mode 100644 index 00000000000..9bc82e98098 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_INCREASINGCOLORSHADER_H +#define FREESTYLE_PYTHON_INCREASINGCOLORSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject IncreasingColorShader_Type; + +#define BPy_IncreasingColorShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &IncreasingColorShader_Type) ) + +/*---------------------------Python BPy_IncreasingColorShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_IncreasingColorShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_INCREASINGCOLORSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp new file mode 100644 index 00000000000..e21a59b5907 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_IncreasingThicknessShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for IncreasingThicknessShader instance -----------*/ +static int IncreasingThicknessShader___init__( BPy_IncreasingThicknessShader* self, PyObject *args); + +/*-----------------------BPy_IncreasingThicknessShader type definition ------------------------------*/ + +PyTypeObject IncreasingThicknessShader_Type = { + PyObject_HEAD_INIT(NULL) + "IncreasingThicknessShader", /* tp_name */ + sizeof(BPy_IncreasingThicknessShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "IncreasingThicknessShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)IncreasingThicknessShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int IncreasingThicknessShader___init__( BPy_IncreasingThicknessShader* self, PyObject *args) +{ + float f1, f2; + + if(!( PyArg_ParseTuple(args, "ff", &f1, &f2) )) + return -1; + + self->py_ss.ss = new StrokeShaders::IncreasingThicknessShader(f1, f2); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h new file mode 100644 index 00000000000..33d883b1860 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_INCREASINGTHICKNESSSHADER_H +#define FREESTYLE_PYTHON_INCREASINGTHICKNESSSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject IncreasingThicknessShader_Type; + +#define BPy_IncreasingThicknessShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &IncreasingThicknessShader_Type) ) + +/*---------------------------Python BPy_IncreasingThicknessShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_IncreasingThicknessShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_INCREASINGTHICKNESSSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp new file mode 100644 index 00000000000..e1c4cbf2fbd --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_PolygonalizationShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for PolygonalizationShader instance -----------*/ +static int PolygonalizationShader___init__( BPy_PolygonalizationShader* self, PyObject *args); + +/*-----------------------BPy_PolygonalizationShader type definition ------------------------------*/ + +PyTypeObject PolygonalizationShader_Type = { + PyObject_HEAD_INIT(NULL) + "PolygonalizationShader", /* tp_name */ + sizeof(BPy_PolygonalizationShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "PolygonalizationShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)PolygonalizationShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int PolygonalizationShader___init__( BPy_PolygonalizationShader* self, PyObject *args) +{ + float f; + + if(!( PyArg_ParseTuple(args, "f", &f) )) + return -1; + + self->py_ss.ss = new StrokeShaders::PolygonalizationShader(f); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h new file mode 100644 index 00000000000..85bcc00e869 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_POLYGONALIZATIONSHADER_H +#define FREESTYLE_PYTHON_POLYGONALIZATIONSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject PolygonalizationShader_Type; + +#define BPy_PolygonalizationShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &PolygonalizationShader_Type) ) + +/*---------------------------Python BPy_PolygonalizationShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_PolygonalizationShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_POLYGONALIZATIONSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp new file mode 100644 index 00000000000..b3c87dfe223 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_SamplingShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for SamplingShader instance -----------*/ +static int SamplingShader___init__( BPy_SamplingShader* self, PyObject *args); + +/*-----------------------BPy_SamplingShader type definition ------------------------------*/ + +PyTypeObject SamplingShader_Type = { + PyObject_HEAD_INIT(NULL) + "SamplingShader", /* tp_name */ + sizeof(BPy_SamplingShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "SamplingShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)SamplingShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int SamplingShader___init__( BPy_SamplingShader* self, PyObject *args) +{ + float f; + + if(!( PyArg_ParseTuple(args, "f", &f) )) + return -1; + + self->py_ss.ss = new StrokeShaders::SamplingShader(f); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h new file mode 100644 index 00000000000..dfc6efb3319 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_SAMPLINGSHADER_H +#define FREESTYLE_PYTHON_SAMPLINGSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject SamplingShader_Type; + +#define BPy_SamplingShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &SamplingShader_Type) ) + +/*---------------------------Python BPy_SamplingShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_SamplingShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_SAMPLINGSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp new file mode 100644 index 00000000000..555b8166ab8 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp @@ -0,0 +1,75 @@ +#include "BPy_SmoothingShader.h" + +#include "../../stroke/AdvancedStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for SmoothingShader instance -----------*/ +static int SmoothingShader___init__( BPy_SmoothingShader* self, PyObject *args); + +/*-----------------------BPy_SmoothingShader type definition ------------------------------*/ + +PyTypeObject SmoothingShader_Type = { + PyObject_HEAD_INIT(NULL) + "SmoothingShader", /* tp_name */ + sizeof(BPy_SmoothingShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "SmoothingShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)SmoothingShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int SmoothingShader___init__( BPy_SmoothingShader* self, PyObject *args) +{ + int i1; + double d2, d3, d4, d5, d6, d7, d8; + + if(!( PyArg_ParseTuple(args, "iddddddd", &i1, &d2, &d3, &d4, &d5, &d6, &d7, &d8) )) + return -1; + + self->py_ss.ss = new SmoothingShader(i1, d2, d3, d4, d5, d6, d7, d8); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h new file mode 100644 index 00000000000..18d6ca3cc30 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHONSMOOTHINGSHADER_H +#define FREESTYLE_PYTHONSMOOTHINGSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject SmoothingShader_Type; + +#define BPy_SmoothingShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &SmoothingShader_Type) ) + +/*---------------------------Python BPy_SmoothingShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_SmoothingShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHONSMOOTHINGSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp new file mode 100644 index 00000000000..e5323ce0afc --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp @@ -0,0 +1,77 @@ +#include "BPy_SpatialNoiseShader.h" + +#include "../../stroke/AdvancedStrokeShaders.h" +#include "../BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for SpatialNoiseShader instance -----------*/ +static int SpatialNoiseShader___init__( BPy_SpatialNoiseShader* self, PyObject *args); + +/*-----------------------BPy_SpatialNoiseShader type definition ------------------------------*/ + +PyTypeObject SpatialNoiseShader_Type = { + PyObject_HEAD_INIT(NULL) + "SpatialNoiseShader", /* tp_name */ + sizeof(BPy_SpatialNoiseShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "SpatialNoiseShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)SpatialNoiseShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int SpatialNoiseShader___init__( BPy_SpatialNoiseShader* self, PyObject *args) +{ + float f1, f2; + int i3; + PyObject *obj4 = 0, *obj5 = 0; + + if(!( PyArg_ParseTuple(args, "ffiOO", &f1, &f2, &i3, &obj4, &obj5) )) + return -1; + + self->py_ss.ss = new SpatialNoiseShader(f1, f2, i3, bool_from_PyBool(obj4), bool_from_PyBool(obj5) ); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h new file mode 100644 index 00000000000..46e1c12385d --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_SPATIALNOISESHADER_H +#define FREESTYLE_PYTHON_SPATIALNOISESHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject SpatialNoiseShader_Type; + +#define BPy_SpatialNoiseShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &SpatialNoiseShader_Type) ) + +/*---------------------------Python BPy_SpatialNoiseShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_SpatialNoiseShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_SPATIALNOISESHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.cpp new file mode 100644 index 00000000000..2939602d1ae --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.cpp @@ -0,0 +1,80 @@ +#include "BPy_StrokeTextureShader.h" + +#include "../../stroke/BasicStrokeShaders.h" +#include "../BPy_Convert.h" +#include "../BPy_MediumType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for StrokeTextureShader instance -----------*/ +static int StrokeTextureShader___init__( BPy_StrokeTextureShader* self, PyObject *args); + +/*-----------------------BPy_StrokeTextureShader type definition ------------------------------*/ + +PyTypeObject StrokeTextureShader_Type = { + PyObject_HEAD_INIT(NULL) + "StrokeTextureShader", /* tp_name */ + sizeof(BPy_StrokeTextureShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "StrokeTextureShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)StrokeTextureShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int StrokeTextureShader___init__( BPy_StrokeTextureShader* self, PyObject *args) +{ + const char *s1; + PyObject *obj2 = 0, *obj3 = 0; + + if(!( PyArg_ParseTuple(args, "s|O!O", &s1, &MediumType_Type, &obj2, &obj3) )) + return -1; + + Stroke::MediumType mt = (obj2) ? MediumType_from_BPy_MediumType(obj2) : Stroke::OPAQUE_MEDIUM; + bool b = (obj3) ? bool_from_PyBool(obj3) : true; + + self->py_ss.ss = new StrokeShaders::StrokeTextureShader(s1,mt,b); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.h new file mode 100644 index 00000000000..c65506f2f14 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_STROKETEXTURESHADER_H +#define FREESTYLE_PYTHON_STROKETEXTURESHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject StrokeTextureShader_Type; + +#define BPy_StrokeTextureShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &StrokeTextureShader_Type) ) + +/*---------------------------Python BPy_StrokeTextureShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_StrokeTextureShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_STROKETEXTURESHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.cpp new file mode 100644 index 00000000000..f0fbb735be4 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_TextureAssignerShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for TextureAssignerShader instance -----------*/ +static int TextureAssignerShader___init__( BPy_TextureAssignerShader* self, PyObject *args); + +/*-----------------------BPy_TextureAssignerShader type definition ------------------------------*/ + +PyTypeObject TextureAssignerShader_Type = { + PyObject_HEAD_INIT(NULL) + "TextureAssignerShader", /* tp_name */ + sizeof(BPy_TextureAssignerShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "TextureAssignerShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)TextureAssignerShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int TextureAssignerShader___init__( BPy_TextureAssignerShader* self, PyObject *args) +{ + int i; + + if(!( PyArg_ParseTuple(args, "i", &i) )) + return -1; + + self->py_ss.ss = new StrokeShaders::TextureAssignerShader(i); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.h new file mode 100644 index 00000000000..9cffc1c1662 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_TEXTUREASSIGNERSHADER_H +#define FREESTYLE_PYTHON_TEXTUREASSIGNERSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject TextureAssignerShader_Type; + +#define BPy_TextureAssignerShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &TextureAssignerShader_Type) ) + +/*---------------------------Python BPy_TextureAssignerShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_TextureAssignerShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_TEXTUREASSIGNERSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp new file mode 100644 index 00000000000..4f3826f7c66 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_ThicknessNoiseShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ThicknessNoiseShader instance -----------*/ +static int ThicknessNoiseShader___init__( BPy_ThicknessNoiseShader* self, PyObject *args); + +/*-----------------------BPy_ThicknessNoiseShader type definition ------------------------------*/ + +PyTypeObject ThicknessNoiseShader_Type = { + PyObject_HEAD_INIT(NULL) + "ThicknessNoiseShader", /* tp_name */ + sizeof(BPy_ThicknessNoiseShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ThicknessNoiseShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ThicknessNoiseShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ThicknessNoiseShader___init__( BPy_ThicknessNoiseShader* self, PyObject *args) +{ + float f1, f2; + + if(!( PyArg_ParseTuple(args, "ff", &f1, &f2) )) + return -1; + + self->py_ss.ss = new StrokeShaders::ThicknessNoiseShader(f1, f2); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h new file mode 100644 index 00000000000..c3ef101683e --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_THICKNESSNOISESHADER_H +#define FREESTYLE_PYTHON_THICKNESSNOISESHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ThicknessNoiseShader_Type; + +#define BPy_ThicknessNoiseShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ThicknessNoiseShader_Type) ) + +/*---------------------------Python BPy_ThicknessNoiseShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_ThicknessNoiseShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_THICKNESSNOISESHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.cpp new file mode 100644 index 00000000000..d9f99f6b411 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.cpp @@ -0,0 +1,78 @@ +#include "BPy_ThicknessVariationPatternShader.h" + +#include "../../stroke/BasicStrokeShaders.h" +#include "../BPy_Convert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ThicknessVariationPatternShader instance -----------*/ +static int ThicknessVariationPatternShader___init__( BPy_ThicknessVariationPatternShader* self, PyObject *args); + +/*-----------------------BPy_ThicknessVariationPatternShader type definition ------------------------------*/ + +PyTypeObject ThicknessVariationPatternShader_Type = { + PyObject_HEAD_INIT(NULL) + "ThicknessVariationPatternShader", /* tp_name */ + sizeof(BPy_ThicknessVariationPatternShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ThicknessVariationPatternShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ThicknessVariationPatternShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ThicknessVariationPatternShader___init__( BPy_ThicknessVariationPatternShader* self, PyObject *args) +{ + const char *s1; + float f2 = 1.0, f3 = 5.0; + PyObject *obj4 = 0; + + if(!( PyArg_ParseTuple(args, "s|ffO", &s1, &f2, &f3, &obj4) )) + return -1; + + bool b = (obj4) ? bool_from_PyBool(obj4) : true; + self->py_ss.ss = new StrokeShaders::ThicknessVariationPatternShader(s1, f2, f3, b); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.h new file mode 100644 index 00000000000..302c9e005ae --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_THICKNESSVARIATIONPATTERNSHADER_H +#define FREESTYLE_PYTHON_THICKNESSVARIATIONPATTERNSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ThicknessVariationPatternShader_Type; + +#define BPy_ThicknessVariationPatternShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ThicknessVariationPatternShader_Type) ) + +/*---------------------------Python BPy_ThicknessVariationPatternShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_ThicknessVariationPatternShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_THICKNESSVARIATIONPATTERNSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp new file mode 100644 index 00000000000..c77b48e15da --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_TipRemoverShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for TipRemoverShader instance -----------*/ +static int TipRemoverShader___init__( BPy_TipRemoverShader* self, PyObject *args); + +/*-----------------------BPy_TipRemoverShader type definition ------------------------------*/ + +PyTypeObject TipRemoverShader_Type = { + PyObject_HEAD_INIT(NULL) + "TipRemoverShader", /* tp_name */ + sizeof(BPy_TipRemoverShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "streamSTipRemoverShaderhader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)TipRemoverShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int TipRemoverShader___init__( BPy_TipRemoverShader* self, PyObject *args) +{ + double d; + + if(!( PyArg_ParseTuple(args, "d", &d) )) + return -1; + + self->py_ss.ss = new StrokeShaders::TipRemoverShader(d); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h new file mode 100644 index 00000000000..a1b2e3988bc --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_TIPREMOVERSHADER_H +#define FREESTYLE_PYTHON_TIPREMOVERSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject TipRemoverShader_Type; + +#define BPy_TipRemoverShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &TipRemoverShader_Type) ) + +/*---------------------------Python BPy_TipRemoverShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_TipRemoverShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_TIPREMOVERSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.cpp new file mode 100644 index 00000000000..1571ec7c275 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.cpp @@ -0,0 +1,74 @@ +#include "BPy_fstreamShader.h" + +#include "../../stroke/AdvancedStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for fstreamShader instance -----------*/ +static int fstreamShader___init__( BPy_fstreamShader* self, PyObject *args); + +/*-----------------------BPy_fstreamShader type definition ------------------------------*/ + +PyTypeObject fstreamShader_Type = { + PyObject_HEAD_INIT(NULL) + "fstreamShader", /* tp_name */ + sizeof(BPy_fstreamShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "fstreamShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)fstreamShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int fstreamShader___init__( BPy_fstreamShader* self, PyObject *args) +{ + const char *s; + + if(!( PyArg_ParseTuple(args, "s", &s) )) + return -1; + + self->py_ss.ss = new StrokeShaders::fstreamShader(s); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.h new file mode 100644 index 00000000000..843d50505db --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_FSTREAMSHADER_H +#define FREESTYLE_PYTHON_FSTREAMSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject fstreamShader_Type; + +#define BPy_fstreamShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &fstreamShader_Type) ) + +/*---------------------------Python BPy_fstreamShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_fstreamShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_FSTREAMSHADER_H */ diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.cpp new file mode 100644 index 00000000000..3f90f6b745f --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.cpp @@ -0,0 +1,71 @@ +#include "BPy_streamShader.h" + +#include "../../stroke/BasicStrokeShaders.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for streamShader instance -----------*/ +static int streamShader___init__( BPy_streamShader* self, PyObject *args); + +/*-----------------------BPy_streamShader type definition ------------------------------*/ + +PyTypeObject streamShader_Type = { + PyObject_HEAD_INIT(NULL) + "streamShader", /* tp_name */ + sizeof(BPy_streamShader), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "streamShader objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &StrokeShader_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)streamShader___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int streamShader___init__( BPy_streamShader* self, PyObject *args) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_ss.ss = new StrokeShaders::streamShader(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.h b/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.h new file mode 100644 index 00000000000..38056d5fa59 --- /dev/null +++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.h @@ -0,0 +1,31 @@ +#ifndef FREESTYLE_PYTHON_STREAMSHADER_H +#define FREESTYLE_PYTHON_STREAMSHADER_H + +#include "../BPy_StrokeShader.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject streamShader_Type; + +#define BPy_streamShader_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &streamShader_Type) ) + +/*---------------------------Python BPy_streamShader structure definition----------*/ +typedef struct { + BPy_StrokeShader py_ss; +} BPy_streamShader; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + + +#endif /* FREESTYLE_PYTHON_STREAMSHADER_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp new file mode 100644 index 00000000000..080eaaec372 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.cpp @@ -0,0 +1,206 @@ +#include "BPy_UnaryFunction0DDouble.h" + +#include "../BPy_Convert.h" +#include "../Iterator/BPy_Interface0DIterator.h" + +#include "UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h" +#include "UnaryFunction0D_double/BPy_DensityF0D.h" +#include "UnaryFunction0D_double/BPy_GetProjectedXF0D.h" +#include "UnaryFunction0D_double/BPy_GetProjectedYF0D.h" +#include "UnaryFunction0D_double/BPy_GetProjectedZF0D.h" +#include "UnaryFunction0D_double/BPy_GetXF0D.h" +#include "UnaryFunction0D_double/BPy_GetYF0D.h" +#include "UnaryFunction0D_double/BPy_GetZF0D.h" +#include "UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h" +#include "UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h" + +#include "../Director.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0DDouble instance -----------*/ +static int UnaryFunction0DDouble___init__(BPy_UnaryFunction0DDouble* self, PyObject *args, PyObject *kwds); +static void UnaryFunction0DDouble___dealloc__(BPy_UnaryFunction0DDouble* self); +static PyObject * UnaryFunction0DDouble___repr__(BPy_UnaryFunction0DDouble* self); + +static PyObject * UnaryFunction0DDouble_getName( BPy_UnaryFunction0DDouble *self); +static PyObject * UnaryFunction0DDouble___call__( BPy_UnaryFunction0DDouble *self, PyObject *args, PyObject *kwds); + +/*----------------------UnaryFunction0DDouble instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction0DDouble_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction0DDouble_getName, METH_NOARGS, "() Returns the string of the name of the unary 0D function."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction0DDouble type definition ------------------------------*/ + +PyTypeObject UnaryFunction0DDouble_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0DDouble", /* tp_name */ + sizeof(BPy_UnaryFunction0DDouble), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0DDouble___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0DDouble___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction0DDouble___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0DDouble objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction0DDouble_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction0DDouble___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction0DDouble_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0DDouble_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0DDouble_Type ); + PyModule_AddObject(module, "UnaryFunction0DDouble", (PyObject *)&UnaryFunction0DDouble_Type); + + if( PyType_Ready( &DensityF0D_Type ) < 0 ) + return -1; + Py_INCREF( &DensityF0D_Type ); + PyModule_AddObject(module, "DensityF0D", (PyObject *)&DensityF0D_Type); + + if( PyType_Ready( &LocalAverageDepthF0D_Type ) < 0 ) + return -1; + Py_INCREF( &LocalAverageDepthF0D_Type ); + PyModule_AddObject(module, "LocalAverageDepthF0D", (PyObject *)&LocalAverageDepthF0D_Type); + + if( PyType_Ready( &Curvature2DAngleF0D_Type ) < 0 ) + return -1; + Py_INCREF( &Curvature2DAngleF0D_Type ); + PyModule_AddObject(module, "Curvature2DAngleF0D", (PyObject *)&Curvature2DAngleF0D_Type); + + if( PyType_Ready( &GetProjectedXF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetProjectedXF0D_Type ); + PyModule_AddObject(module, "GetProjectedXF0D", (PyObject *)&GetProjectedXF0D_Type); + + if( PyType_Ready( &GetProjectedYF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetProjectedYF0D_Type ); + PyModule_AddObject(module, "GetProjectedYF0D", (PyObject *)&GetProjectedYF0D_Type); + + if( PyType_Ready( &GetProjectedZF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetProjectedZF0D_Type ); + PyModule_AddObject(module, "GetProjectedZF0D", (PyObject *)&GetProjectedZF0D_Type); + + if( PyType_Ready( &GetXF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetXF0D_Type ); + PyModule_AddObject(module, "GetXF0D", (PyObject *)&GetXF0D_Type); + + if( PyType_Ready( &GetYF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetYF0D_Type ); + PyModule_AddObject(module, "GetYF0D", (PyObject *)&GetYF0D_Type); + + if( PyType_Ready( &GetZF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetZF0D_Type ); + PyModule_AddObject(module, "GetZF0D", (PyObject *)&GetZF0D_Type); + + if( PyType_Ready( &ZDiscontinuityF0D_Type ) < 0 ) + return -1; + Py_INCREF( &ZDiscontinuityF0D_Type ); + PyModule_AddObject(module, "ZDiscontinuityF0D", (PyObject *)&ZDiscontinuityF0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction0DDouble___init__(BPy_UnaryFunction0DDouble* self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->uf0D_double = new UnaryFunction0D<double>(); + self->uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +void UnaryFunction0DDouble___dealloc__(BPy_UnaryFunction0DDouble* self) +{ + if (self->uf0D_double) + delete self->uf0D_double; + UnaryFunction0D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction0DDouble___repr__(BPy_UnaryFunction0DDouble* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf0D_double->getName().c_str(), self->uf0D_double ); +} + +PyObject * UnaryFunction0DDouble_getName( BPy_UnaryFunction0DDouble *self ) +{ + return PyUnicode_FromFormat( self->uf0D_double->getName().c_str() ); +} + +PyObject * UnaryFunction0DDouble___call__( BPy_UnaryFunction0DDouble *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if(!PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj)) + return NULL; + + if( typeid(*(self->uf0D_double)) == typeid(UnaryFunction0D<double>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf0D_double->operator()(*( ((BPy_Interface0DIterator *) obj)->if0D_it)) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf0D_double->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return PyFloat_FromDouble( self->uf0D_double->result ); + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h new file mode 100644 index 00000000000..dbeb70cc082 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DDouble.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0DDOUBLE_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0DDOUBLE_H + +#include "../BPy_UnaryFunction0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0DDouble_Type; + +#define BPy_UnaryFunction0DDouble_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0DDouble_Type) ) + +/*---------------------------Python BPy_UnaryFunction0DDouble structure definition----------*/ +typedef struct { + BPy_UnaryFunction0D py_uf0D; + UnaryFunction0D<double> *uf0D_double; +} BPy_UnaryFunction0DDouble; + +/*---------------------------Python BPy_UnaryFunction0DDouble visible prototypes-----------*/ +int UnaryFunction0DDouble_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0DDOUBLE_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp new file mode 100644 index 00000000000..c050b29f65b --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.cpp @@ -0,0 +1,150 @@ +#include "BPy_UnaryFunction0DEdgeNature.h" + +#include "../BPy_Convert.h" +#include "../Iterator/BPy_Interface0DIterator.h" + +#include "UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0DEdgeNature instance -----------*/ +static int UnaryFunction0DEdgeNature___init__(BPy_UnaryFunction0DEdgeNature* self, PyObject *args, PyObject *kwds); +static void UnaryFunction0DEdgeNature___dealloc__(BPy_UnaryFunction0DEdgeNature* self); +static PyObject * UnaryFunction0DEdgeNature___repr__(BPy_UnaryFunction0DEdgeNature* self); + +static PyObject * UnaryFunction0DEdgeNature_getName( BPy_UnaryFunction0DEdgeNature *self); +static PyObject * UnaryFunction0DEdgeNature___call__( BPy_UnaryFunction0DEdgeNature *self, PyObject *args, PyObject *kwds); + +/*----------------------UnaryFunction0DEdgeNature instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction0DEdgeNature_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction0DEdgeNature_getName, METH_NOARGS, "() Returns the string of the name of the unary 0D function."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction0DEdgeNature type definition ------------------------------*/ + +PyTypeObject UnaryFunction0DEdgeNature_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0DEdgeNature", /* tp_name */ + sizeof(BPy_UnaryFunction0DEdgeNature), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0DEdgeNature___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0DEdgeNature___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction0DEdgeNature___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0DEdgeNature objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction0DEdgeNature_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction0DEdgeNature___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction0DEdgeNature_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0DEdgeNature_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0DEdgeNature_Type ); + PyModule_AddObject(module, "UnaryFunction0DEdgeNature", (PyObject *)&UnaryFunction0DEdgeNature_Type); + + if( PyType_Ready( &CurveNatureF0D_Type ) < 0 ) + return -1; + Py_INCREF( &CurveNatureF0D_Type ); + PyModule_AddObject(module, "CurveNatureF0D", (PyObject *)&CurveNatureF0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction0DEdgeNature___init__(BPy_UnaryFunction0DEdgeNature* self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->uf0D_edgenature = new UnaryFunction0D<Nature::EdgeNature>(); + self->uf0D_edgenature->py_uf0D = (PyObject *)self; + return 0; +} + +void UnaryFunction0DEdgeNature___dealloc__(BPy_UnaryFunction0DEdgeNature* self) +{ + if (self->uf0D_edgenature) + delete self->uf0D_edgenature; + UnaryFunction0D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction0DEdgeNature___repr__(BPy_UnaryFunction0DEdgeNature* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf0D_edgenature->getName().c_str(), self->uf0D_edgenature ); +} + +PyObject * UnaryFunction0DEdgeNature_getName( BPy_UnaryFunction0DEdgeNature *self ) +{ + return PyUnicode_FromFormat( self->uf0D_edgenature->getName().c_str() ); +} + +PyObject * UnaryFunction0DEdgeNature___call__( BPy_UnaryFunction0DEdgeNature *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if(!PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj)) + return NULL; + + if( typeid(*(self->uf0D_edgenature)) == typeid(UnaryFunction0D<Nature::EdgeNature>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf0D_edgenature->operator()(*( ((BPy_Interface0DIterator *) obj)->if0D_it )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf0D_edgenature->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return BPy_Nature_from_Nature( self->uf0D_edgenature->result ); + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h new file mode 100644 index 00000000000..d6959cae57f --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h @@ -0,0 +1,36 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0DEDGENATURE_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0DEDGENATURE_H + +#include "../BPy_UnaryFunction0D.h" + +#include "../../winged_edge/Nature.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0DEdgeNature_Type; + +#define BPy_UnaryFunction0DEdgeNature_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0DEdgeNature_Type) ) + +/*---------------------------Python BPy_UnaryFunction0DEdgeNature structure definition----------*/ +typedef struct { + BPy_UnaryFunction0D py_uf0D; + UnaryFunction0D<Nature::EdgeNature> *uf0D_edgenature; +} BPy_UnaryFunction0DEdgeNature; + +/*---------------------------Python BPy_UnaryFunction0DEdgeNature visible prototypes-----------*/ +int UnaryFunction0DEdgeNature_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0DEDGENATURE_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp new file mode 100644 index 00000000000..8bf9136cdc2 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.cpp @@ -0,0 +1,180 @@ +#include "BPy_UnaryFunction0DFloat.h" + +#include "../BPy_Convert.h" +#include "../Iterator/BPy_Interface0DIterator.h" + +#include "UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h" +#include "UnaryFunction0D_float/BPy_GetParameterF0D.h" +#include "UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h" +#include "UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h" +#include "UnaryFunction0D_float/BPy_ReadMapPixelF0D.h" +#include "UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0DFloat instance -----------*/ +static int UnaryFunction0DFloat___init__(BPy_UnaryFunction0DFloat* self, PyObject *args, PyObject *kwds); +static void UnaryFunction0DFloat___dealloc__(BPy_UnaryFunction0DFloat* self); +static PyObject * UnaryFunction0DFloat___repr__(BPy_UnaryFunction0DFloat* self); + +static PyObject * UnaryFunction0DFloat_getName( BPy_UnaryFunction0DFloat *self); +static PyObject * UnaryFunction0DFloat___call__( BPy_UnaryFunction0DFloat *self, PyObject *args, PyObject *kwds); + +/*----------------------UnaryFunction0DFloat instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction0DFloat_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction0DFloat_getName, METH_NOARGS, "() Returns the string of the name of the unary 0D function."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction0DFloat type definition ------------------------------*/ + +PyTypeObject UnaryFunction0DFloat_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0DFloat", /* tp_name */ + sizeof(BPy_UnaryFunction0DFloat), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0DFloat___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0DFloat___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction0DFloat___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0DFloat objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction0DFloat_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction0DFloat___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction0DFloat_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0DFloat_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0DFloat_Type ); + PyModule_AddObject(module, "UnaryFunction0DFloat", (PyObject *)&UnaryFunction0DFloat_Type); + + if( PyType_Ready( &GetCurvilinearAbscissaF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetCurvilinearAbscissaF0D_Type ); + PyModule_AddObject(module, "GetCurvilinearAbscissaF0D", (PyObject *)&GetCurvilinearAbscissaF0D_Type); + + if( PyType_Ready( &GetParameterF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetParameterF0D_Type ); + PyModule_AddObject(module, "GetParameterF0D", (PyObject *)&GetParameterF0D_Type); + + if( PyType_Ready( &GetViewMapGradientNormF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetViewMapGradientNormF0D_Type ); + PyModule_AddObject(module, "GetViewMapGradientNormF0D", (PyObject *)&GetViewMapGradientNormF0D_Type); + + if( PyType_Ready( &ReadCompleteViewMapPixelF0D_Type ) < 0 ) + return -1; + Py_INCREF( &ReadCompleteViewMapPixelF0D_Type ); + PyModule_AddObject(module, "ReadCompleteViewMapPixelF0D", (PyObject *)&ReadCompleteViewMapPixelF0D_Type); + + if( PyType_Ready( &ReadMapPixelF0D_Type ) < 0 ) + return -1; + Py_INCREF( &ReadMapPixelF0D_Type ); + PyModule_AddObject(module, "ReadMapPixelF0D", (PyObject *)&ReadMapPixelF0D_Type); + + if( PyType_Ready( &ReadSteerableViewMapPixelF0D_Type ) < 0 ) + return -1; + Py_INCREF( &ReadSteerableViewMapPixelF0D_Type ); + PyModule_AddObject(module, "ReadSteerableViewMapPixelF0D", (PyObject *)&ReadSteerableViewMapPixelF0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction0DFloat___init__(BPy_UnaryFunction0DFloat* self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->uf0D_float = new UnaryFunction0D<float>(); + self->uf0D_float->py_uf0D = (PyObject *)self; + return 0; +} + +void UnaryFunction0DFloat___dealloc__(BPy_UnaryFunction0DFloat* self) +{ + if (self->uf0D_float) + delete self->uf0D_float; + UnaryFunction0D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction0DFloat___repr__(BPy_UnaryFunction0DFloat* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf0D_float->getName().c_str(), self->uf0D_float ); +} + +PyObject * UnaryFunction0DFloat_getName( BPy_UnaryFunction0DFloat *self ) +{ + return PyUnicode_FromFormat( self->uf0D_float->getName().c_str() ); +} + +PyObject * UnaryFunction0DFloat___call__( BPy_UnaryFunction0DFloat *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if(!PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj)) + return NULL; + + if( typeid(*(self->uf0D_float)) == typeid(UnaryFunction0D<float>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf0D_float->operator()(*( ((BPy_Interface0DIterator *) obj)->if0D_it )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf0D_float->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return PyFloat_FromDouble( self->uf0D_float->result ); + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h new file mode 100644 index 00000000000..fbf207d48c7 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DFloat.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0DFLOAT_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0DFLOAT_H + +#include "../BPy_UnaryFunction0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0DFloat_Type; + +#define BPy_UnaryFunction0DFloat_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0DFloat_Type) ) + +/*---------------------------Python BPy_UnaryFunction0DFloat structure definition----------*/ +typedef struct { + BPy_UnaryFunction0D py_uf0D; + UnaryFunction0D<float> *uf0D_float; +} BPy_UnaryFunction0DFloat; + +/*---------------------------Python BPy_UnaryFunction0DFloat visible prototypes-----------*/ +int UnaryFunction0DFloat_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0DFLOAT_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp new file mode 100644 index 00000000000..25c251087a1 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.cpp @@ -0,0 +1,149 @@ +#include "BPy_UnaryFunction0DId.h" + +#include "../BPy_Convert.h" +#include "../Iterator/BPy_Interface0DIterator.h" + +#include "UnaryFunction0D_Id/BPy_ShapeIdF0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0DId instance -----------*/ +static int UnaryFunction0DId___init__(BPy_UnaryFunction0DId* self, PyObject *args, PyObject *kwds); +static void UnaryFunction0DId___dealloc__(BPy_UnaryFunction0DId* self); +static PyObject * UnaryFunction0DId___repr__(BPy_UnaryFunction0DId* self); + +static PyObject * UnaryFunction0DId_getName( BPy_UnaryFunction0DId *self); +static PyObject * UnaryFunction0DId___call__( BPy_UnaryFunction0DId *self, PyObject *args, PyObject *kwds); + +/*----------------------UnaryFunction0DId instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction0DId_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction0DId_getName, METH_NOARGS, "() Returns the string of the name of the unary 0D function."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction0DId type definition ------------------------------*/ + +PyTypeObject UnaryFunction0DId_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0DId", /* tp_name */ + sizeof(BPy_UnaryFunction0DId), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0DId___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0DId___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction0DId___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0DId objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction0DId_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction0DId___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction0DId_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0DId_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0DId_Type ); + PyModule_AddObject(module, "UnaryFunction0DId", (PyObject *)&UnaryFunction0DId_Type); + + if( PyType_Ready( &ShapeIdF0D_Type ) < 0 ) + return -1; + Py_INCREF( &ShapeIdF0D_Type ); + PyModule_AddObject(module, "ShapeIdF0D", (PyObject *)&ShapeIdF0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction0DId___init__(BPy_UnaryFunction0DId* self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->uf0D_id = new UnaryFunction0D<Id>(); + self->uf0D_id->py_uf0D = (PyObject *)self; + return 0; +} + +void UnaryFunction0DId___dealloc__(BPy_UnaryFunction0DId* self) +{ + if (self->uf0D_id) + delete self->uf0D_id; + UnaryFunction0D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction0DId___repr__(BPy_UnaryFunction0DId* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf0D_id->getName().c_str(), self->uf0D_id ); +} + +PyObject * UnaryFunction0DId_getName( BPy_UnaryFunction0DId *self ) +{ + return PyUnicode_FromFormat( self->uf0D_id->getName().c_str() ); +} + +PyObject * UnaryFunction0DId___call__( BPy_UnaryFunction0DId *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if(!PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj)) + return NULL; + + if( typeid(*(self->uf0D_id)) == typeid(UnaryFunction0D<Id>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf0D_id->operator()(*( ((BPy_Interface0DIterator *) obj)->if0D_it )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf0D_id->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return BPy_Id_from_Id( self->uf0D_id->result ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h new file mode 100644 index 00000000000..159e24e2674 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DId.h @@ -0,0 +1,36 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0DID_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0DID_H + +#include "../BPy_UnaryFunction0D.h" + +#include "../../system/Id.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0DId_Type; + +#define BPy_UnaryFunction0DId_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0DId_Type) ) + +/*---------------------------Python BPy_UnaryFunction0DId structure definition----------*/ +typedef struct { + BPy_UnaryFunction0D py_uf0D; + UnaryFunction0D<Id> *uf0D_id; +} BPy_UnaryFunction0DId; + +/*---------------------------Python BPy_UnaryFunction0DId visible prototypes-----------*/ +int UnaryFunction0DId_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0DID_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp new file mode 100644 index 00000000000..7029280fb61 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.cpp @@ -0,0 +1,150 @@ +#include "BPy_UnaryFunction0DMaterial.h" + +#include "../BPy_Convert.h" +#include "../Iterator/BPy_Interface0DIterator.h" + +#include "UnaryFunction0D_Material/BPy_MaterialF0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0DMaterial instance -----------*/ +static int UnaryFunction0DMaterial___init__(BPy_UnaryFunction0DMaterial* self, PyObject *args, PyObject *kwds); +static void UnaryFunction0DMaterial___dealloc__(BPy_UnaryFunction0DMaterial* self); +static PyObject * UnaryFunction0DMaterial___repr__(BPy_UnaryFunction0DMaterial* self); + +static PyObject * UnaryFunction0DMaterial_getName( BPy_UnaryFunction0DMaterial *self); +static PyObject * UnaryFunction0DMaterial___call__( BPy_UnaryFunction0DMaterial *self, PyObject *args, PyObject *kwds); + +/*----------------------UnaryFunction0DMaterial instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction0DMaterial_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction0DMaterial_getName, METH_NOARGS, "() Returns the string of the name of the unary 0D function."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction0DMaterial type definition ------------------------------*/ + +PyTypeObject UnaryFunction0DMaterial_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0DMaterial", /* tp_name */ + sizeof(BPy_UnaryFunction0DMaterial), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0DMaterial___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0DMaterial___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction0DMaterial___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0DMaterial objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction0DMaterial_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction0DMaterial___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction0DMaterial_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0DMaterial_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0DMaterial_Type ); + PyModule_AddObject(module, "UnaryFunction0DMaterial", (PyObject *)&UnaryFunction0DMaterial_Type); + + if( PyType_Ready( &MaterialF0D_Type ) < 0 ) + return -1; + Py_INCREF( &MaterialF0D_Type ); + PyModule_AddObject(module, "MaterialF0D", (PyObject *)&MaterialF0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction0DMaterial___init__(BPy_UnaryFunction0DMaterial* self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->uf0D_material = new UnaryFunction0D<FrsMaterial>(); + self->uf0D_material->py_uf0D = (PyObject *)self; + return 0; +} + +void UnaryFunction0DMaterial___dealloc__(BPy_UnaryFunction0DMaterial* self) +{ + if (self->uf0D_material) + delete self->uf0D_material; + UnaryFunction0D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction0DMaterial___repr__(BPy_UnaryFunction0DMaterial* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf0D_material->getName().c_str(), self->uf0D_material ); +} + +PyObject * UnaryFunction0DMaterial_getName( BPy_UnaryFunction0DMaterial *self ) +{ + return PyUnicode_FromFormat( self->uf0D_material->getName().c_str() ); +} + +PyObject * UnaryFunction0DMaterial___call__( BPy_UnaryFunction0DMaterial *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if(!PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj)) + return NULL; + + if( typeid(*(self->uf0D_material)) == typeid(UnaryFunction0D<FrsMaterial>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf0D_material->operator()(*( ((BPy_Interface0DIterator *) obj)->if0D_it )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf0D_material->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return BPy_FrsMaterial_from_FrsMaterial( self->uf0D_material->result ); + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h new file mode 100644 index 00000000000..02fb2b99ccd --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DMaterial.h @@ -0,0 +1,36 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0DMATERIAL_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0DMATERIAL_H + +#include "../BPy_UnaryFunction0D.h" + +#include "../../scene_graph/FrsMaterial.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0DMaterial_Type; + +#define BPy_UnaryFunction0DMaterial_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0DMaterial_Type) ) + +/*---------------------------Python BPy_UnaryFunction0DMaterial structure definition----------*/ +typedef struct { + BPy_UnaryFunction0D py_uf0D; + UnaryFunction0D<FrsMaterial> *uf0D_material; +} BPy_UnaryFunction0DMaterial; + +/*---------------------------Python BPy_UnaryFunction0DMaterial visible prototypes-----------*/ +int UnaryFunction0DMaterial_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0DMATERIAL_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp new file mode 100644 index 00000000000..475e134b18e --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.cpp @@ -0,0 +1,150 @@ +#include "BPy_UnaryFunction0DUnsigned.h" + +#include "../BPy_Convert.h" +#include "../Iterator/BPy_Interface0DIterator.h" + +#include "UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0DUnsigned instance -----------*/ +static int UnaryFunction0DUnsigned___init__(BPy_UnaryFunction0DUnsigned* self, PyObject *args, PyObject *kwds); +static void UnaryFunction0DUnsigned___dealloc__(BPy_UnaryFunction0DUnsigned* self); +static PyObject * UnaryFunction0DUnsigned___repr__(BPy_UnaryFunction0DUnsigned* self); + +static PyObject * UnaryFunction0DUnsigned_getName( BPy_UnaryFunction0DUnsigned *self); +static PyObject * UnaryFunction0DUnsigned___call__( BPy_UnaryFunction0DUnsigned *self, PyObject *args, PyObject *kwds); + +/*----------------------UnaryFunction0DUnsigned instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction0DUnsigned_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction0DUnsigned_getName, METH_NOARGS, "() Returns the string of the name of the unary 0D function."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction0DUnsigned type definition ------------------------------*/ + +PyTypeObject UnaryFunction0DUnsigned_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0DUnsigned", /* tp_name */ + sizeof(BPy_UnaryFunction0DUnsigned), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0DUnsigned___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0DUnsigned___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction0DUnsigned___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0DUnsigned objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction0DUnsigned_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction0DUnsigned___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction0DUnsigned_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0DUnsigned_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0DUnsigned_Type ); + PyModule_AddObject(module, "UnaryFunction0DUnsigned", (PyObject *)&UnaryFunction0DUnsigned_Type); + + if( PyType_Ready( &QuantitativeInvisibilityF0D_Type ) < 0 ) + return -1; + Py_INCREF( &QuantitativeInvisibilityF0D_Type ); + PyModule_AddObject(module, "QuantitativeInvisibilityF0D", (PyObject *)&QuantitativeInvisibilityF0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction0DUnsigned___init__(BPy_UnaryFunction0DUnsigned* self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->uf0D_unsigned = new UnaryFunction0D<unsigned int>(); + self->uf0D_unsigned->py_uf0D = (PyObject *)self; + return 0; +} + +void UnaryFunction0DUnsigned___dealloc__(BPy_UnaryFunction0DUnsigned* self) +{ + if (self->uf0D_unsigned) + delete self->uf0D_unsigned; + UnaryFunction0D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction0DUnsigned___repr__(BPy_UnaryFunction0DUnsigned* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf0D_unsigned->getName().c_str(), self->uf0D_unsigned ); +} + +PyObject * UnaryFunction0DUnsigned_getName( BPy_UnaryFunction0DUnsigned *self ) +{ + return PyUnicode_FromFormat( self->uf0D_unsigned->getName().c_str() ); +} + +PyObject * UnaryFunction0DUnsigned___call__( BPy_UnaryFunction0DUnsigned *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if(!PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj)) + return NULL; + + if( typeid(*(self->uf0D_unsigned)) == typeid(UnaryFunction0D<unsigned int>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf0D_unsigned->operator()(*( ((BPy_Interface0DIterator *) obj)->if0D_it )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf0D_unsigned->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return PyLong_FromLong( self->uf0D_unsigned->result ); + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h new file mode 100644 index 00000000000..4776ce30918 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0DUNSIGNED_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0DUNSIGNED_H + +#include "../BPy_UnaryFunction0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0DUnsigned_Type; + +#define BPy_UnaryFunction0DUnsigned_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0DUnsigned_Type) ) + +/*---------------------------Python BPy_UnaryFunction0DUnsigned structure definition----------*/ +typedef struct { + BPy_UnaryFunction0D py_uf0D; + UnaryFunction0D<unsigned int> *uf0D_unsigned; +} BPy_UnaryFunction0DUnsigned; + +/*---------------------------Python BPy_UnaryFunction0DUnsigned visible prototypes-----------*/ +int UnaryFunction0DUnsigned_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0DUNSIGNED_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp new file mode 100644 index 00000000000..eb09a9459d5 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.cpp @@ -0,0 +1,156 @@ +#include "BPy_UnaryFunction0DVec2f.h" + +#include "../BPy_Convert.h" +#include "../Iterator/BPy_Interface0DIterator.h" + +#include "UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h" +#include "UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0DVec2f instance -----------*/ +static int UnaryFunction0DVec2f___init__(BPy_UnaryFunction0DVec2f* self, PyObject *args, PyObject *kwds); +static void UnaryFunction0DVec2f___dealloc__(BPy_UnaryFunction0DVec2f* self); +static PyObject * UnaryFunction0DVec2f___repr__(BPy_UnaryFunction0DVec2f* self); + +static PyObject * UnaryFunction0DVec2f_getName( BPy_UnaryFunction0DVec2f *self); +static PyObject * UnaryFunction0DVec2f___call__( BPy_UnaryFunction0DVec2f *self, PyObject *args, PyObject *kwds); + +/*----------------------UnaryFunction0DVec2f instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction0DVec2f_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction0DVec2f_getName, METH_NOARGS, "() Returns the string of the name of the unary 0D function."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction0DVec2f type definition ------------------------------*/ + +PyTypeObject UnaryFunction0DVec2f_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0DVec2f", /* tp_name */ + sizeof(BPy_UnaryFunction0DVec2f), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0DVec2f___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0DVec2f___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction0DVec2f___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0DVec2f objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction0DVec2f_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction0DVec2f___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction0DVec2f_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0DVec2f_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0DVec2f_Type ); + PyModule_AddObject(module, "UnaryFunction0DVec2f", (PyObject *)&UnaryFunction0DVec2f_Type); + + if( PyType_Ready( &Normal2DF0D_Type ) < 0 ) + return -1; + Py_INCREF( &Normal2DF0D_Type ); + PyModule_AddObject(module, "Normal2DF0D", (PyObject *)&Normal2DF0D_Type); + + if( PyType_Ready( &VertexOrientation2DF0D_Type ) < 0 ) + return -1; + Py_INCREF( &VertexOrientation2DF0D_Type ); + PyModule_AddObject(module, "VertexOrientation2DF0D", (PyObject *)&VertexOrientation2DF0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction0DVec2f___init__(BPy_UnaryFunction0DVec2f* self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->uf0D_vec2f = new UnaryFunction0D<Vec2f>(); + self->uf0D_vec2f->py_uf0D = (PyObject *)self; + return 0; +} + +void UnaryFunction0DVec2f___dealloc__(BPy_UnaryFunction0DVec2f* self) +{ + if (self->uf0D_vec2f) + delete self->uf0D_vec2f; + UnaryFunction0D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction0DVec2f___repr__(BPy_UnaryFunction0DVec2f* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf0D_vec2f->getName().c_str(), self->uf0D_vec2f ); +} + +PyObject * UnaryFunction0DVec2f_getName( BPy_UnaryFunction0DVec2f *self ) +{ + return PyUnicode_FromFormat( self->uf0D_vec2f->getName().c_str() ); +} + +PyObject * UnaryFunction0DVec2f___call__( BPy_UnaryFunction0DVec2f *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if(!PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj)) + return NULL; + + if( typeid(*(self->uf0D_vec2f)) == typeid(UnaryFunction0D<Vec2f>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf0D_vec2f->operator()(*( ((BPy_Interface0DIterator *) obj)->if0D_it )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf0D_vec2f->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return Vector_from_Vec2f( self->uf0D_vec2f->result ); + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h new file mode 100644 index 00000000000..6628d629a41 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec2f.h @@ -0,0 +1,37 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0DVEC2F_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0DVEC2F_H + +#include "../BPy_UnaryFunction0D.h" + +#include "../../geometry/Geom.h" +using namespace Geometry; + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0DVec2f_Type; + +#define BPy_UnaryFunction0DVec2f_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0DVec2f_Type) ) + +/*---------------------------Python BPy_UnaryFunction0DVec2f structure definition----------*/ +typedef struct { + BPy_UnaryFunction0D py_uf0D; + UnaryFunction0D<Vec2f> *uf0D_vec2f; +} BPy_UnaryFunction0DVec2f; + +/*---------------------------Python BPy_UnaryFunction0DVec2f visible prototypes-----------*/ +int UnaryFunction0DVec2f_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0DVEC2F_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp new file mode 100644 index 00000000000..67610ae13a9 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.cpp @@ -0,0 +1,150 @@ +#include "BPy_UnaryFunction0DVec3f.h" + +#include "../BPy_Convert.h" +#include "../Iterator/BPy_Interface0DIterator.h" + +#include "UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0DVec3f instance -----------*/ +static int UnaryFunction0DVec3f___init__(BPy_UnaryFunction0DVec3f* self, PyObject *args, PyObject *kwds); +static void UnaryFunction0DVec3f___dealloc__(BPy_UnaryFunction0DVec3f* self); +static PyObject * UnaryFunction0DVec3f___repr__(BPy_UnaryFunction0DVec3f* self); + +static PyObject * UnaryFunction0DVec3f_getName( BPy_UnaryFunction0DVec3f *self); +static PyObject * UnaryFunction0DVec3f___call__( BPy_UnaryFunction0DVec3f *self, PyObject *args, PyObject *kwds); + +/*----------------------UnaryFunction0DVec3f instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction0DVec3f_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction0DVec3f_getName, METH_NOARGS, "() Returns the string of the name of the unary 0D function."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction0DVec3f type definition ------------------------------*/ + +PyTypeObject UnaryFunction0DVec3f_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0DVec3f", /* tp_name */ + sizeof(BPy_UnaryFunction0DVec3f), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0DVec3f___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0DVec3f___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction0DVec3f___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0DVec3f objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction0DVec3f_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction0DVec3f___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction0DVec3f_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0DVec3f_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0DVec3f_Type ); + PyModule_AddObject(module, "UnaryFunction0DVec3f", (PyObject *)&UnaryFunction0DVec3f_Type); + + if( PyType_Ready( &VertexOrientation3DF0D_Type ) < 0 ) + return -1; + Py_INCREF( &VertexOrientation3DF0D_Type ); + PyModule_AddObject(module, "VertexOrientation3DF0D", (PyObject *)&VertexOrientation3DF0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction0DVec3f___init__(BPy_UnaryFunction0DVec3f* self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->uf0D_vec3f = new UnaryFunction0D<Vec3f>(); + self->uf0D_vec3f->py_uf0D = (PyObject *)self; + return 0; +} + +void UnaryFunction0DVec3f___dealloc__(BPy_UnaryFunction0DVec3f* self) +{ + if (self->uf0D_vec3f) + delete self->uf0D_vec3f; + UnaryFunction0D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction0DVec3f___repr__(BPy_UnaryFunction0DVec3f* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf0D_vec3f->getName().c_str(), self->uf0D_vec3f ); +} + +PyObject * UnaryFunction0DVec3f_getName( BPy_UnaryFunction0DVec3f *self ) +{ + return PyUnicode_FromFormat( self->uf0D_vec3f->getName().c_str() ); +} + +PyObject * UnaryFunction0DVec3f___call__( BPy_UnaryFunction0DVec3f *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if(!PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj)) + return NULL; + + if( typeid(*(self->uf0D_vec3f)) == typeid(UnaryFunction0D<Vec3f>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf0D_vec3f->operator()(*( ((BPy_Interface0DIterator *) obj)->if0D_it )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf0D_vec3f->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return Vector_from_Vec3f( self->uf0D_vec3f->result ); + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h new file mode 100644 index 00000000000..47ec89fb179 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVec3f.h @@ -0,0 +1,37 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0DVEC3F_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0DVEC3F_H + +#include "../BPy_UnaryFunction0D.h" + +#include "../../geometry/Geom.h" +using namespace Geometry; + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0DVec3f_Type; + +#define BPy_UnaryFunction0DVec3f_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0DVec3f_Type) ) + +/*---------------------------Python BPy_UnaryFunction0DVec3f structure definition----------*/ +typedef struct { + BPy_UnaryFunction0D py_uf0D; + UnaryFunction0D<Vec3f> *uf0D_vec3f; +} BPy_UnaryFunction0DVec3f; + +/*---------------------------Python BPy_UnaryFunction0DVec3f visible prototypes-----------*/ +int UnaryFunction0DVec3f_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0DVEC3F_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp new file mode 100644 index 00000000000..5fcbff2c8de --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp @@ -0,0 +1,154 @@ +#include "BPy_UnaryFunction0DVectorViewShape.h" + +#include "../BPy_Convert.h" +#include "../Iterator/BPy_Interface0DIterator.h" + +#include "UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0DVectorViewShape instance -----------*/ +static int UnaryFunction0DVectorViewShape___init__(BPy_UnaryFunction0DVectorViewShape* self, PyObject *args, PyObject *kwds); +static void UnaryFunction0DVectorViewShape___dealloc__(BPy_UnaryFunction0DVectorViewShape* self); +static PyObject * UnaryFunction0DVectorViewShape___repr__(BPy_UnaryFunction0DVectorViewShape* self); + +static PyObject * UnaryFunction0DVectorViewShape_getName( BPy_UnaryFunction0DVectorViewShape *self); +static PyObject * UnaryFunction0DVectorViewShape___call__( BPy_UnaryFunction0DVectorViewShape *self, PyObject *args, PyObject *kwds); + +/*----------------------UnaryFunction0DVectorViewShape instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction0DVectorViewShape_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction0DVectorViewShape_getName, METH_NOARGS, "() Returns the string of the name of the unary 0D function."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction0DVectorViewShape type definition ------------------------------*/ + +PyTypeObject UnaryFunction0DVectorViewShape_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0DVectorViewShape", /* tp_name */ + sizeof(BPy_UnaryFunction0DVectorViewShape), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0DVectorViewShape___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0DVectorViewShape___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction0DVectorViewShape___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0DVectorViewShape objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction0DVectorViewShape_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction0DVectorViewShape___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction0DVectorViewShape_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0DVectorViewShape_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0DVectorViewShape_Type ); + PyModule_AddObject(module, "UnaryFunction0DVectorViewShape", (PyObject *)&UnaryFunction0DVectorViewShape_Type); + + if( PyType_Ready( &GetOccludersF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetOccludersF0D_Type ); + PyModule_AddObject(module, "GetOccludersF0D", (PyObject *)&GetOccludersF0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction0DVectorViewShape___init__(BPy_UnaryFunction0DVectorViewShape* self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->uf0D_vectorviewshape = new UnaryFunction0D< std::vector<ViewShape*> >(); + self->uf0D_vectorviewshape->py_uf0D = (PyObject *)self; + return 0; +} + +void UnaryFunction0DVectorViewShape___dealloc__(BPy_UnaryFunction0DVectorViewShape* self) +{ + if (self->uf0D_vectorviewshape) + delete self->uf0D_vectorviewshape; + UnaryFunction0D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction0DVectorViewShape___repr__(BPy_UnaryFunction0DVectorViewShape* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf0D_vectorviewshape->getName().c_str(), self->uf0D_vectorviewshape ); +} + +PyObject * UnaryFunction0DVectorViewShape_getName( BPy_UnaryFunction0DVectorViewShape *self ) +{ + return PyUnicode_FromFormat( self->uf0D_vectorviewshape->getName().c_str() ); +} + +PyObject * UnaryFunction0DVectorViewShape___call__( BPy_UnaryFunction0DVectorViewShape *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if(!PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj)) + return NULL; + + if( typeid(*(self->uf0D_vectorviewshape)) == typeid(UnaryFunction0D< std::vector<ViewShape*> >) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf0D_vectorviewshape->operator()(*( ((BPy_Interface0DIterator *) obj)->if0D_it )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf0D_vectorviewshape->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + PyObject *list = PyList_New(0); + + for( unsigned int i = 0; i < self->uf0D_vectorviewshape->result.size(); i++) + PyList_Append(list, BPy_ViewShape_from_ViewShape(*( self->uf0D_vectorviewshape->result[i] )) ); + + return list; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h new file mode 100644 index 00000000000..77f96e96f20 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h @@ -0,0 +1,37 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0DVECTORVIEWSHAPE_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0DVECTORVIEWSHAPE_H + +#include "../BPy_UnaryFunction0D.h" + +#include <vector> +#include "../../view_map/ViewMap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0DVectorViewShape_Type; + +#define BPy_UnaryFunction0DVectorViewShape_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0DVectorViewShape_Type) ) + +/*---------------------------Python BPy_UnaryFunction0DVectorViewShape structure definition----------*/ +typedef struct { + BPy_UnaryFunction0D py_uf0D; + UnaryFunction0D< std::vector<ViewShape*> > *uf0D_vectorviewshape; +} BPy_UnaryFunction0DVectorViewShape; + +/*---------------------------Python BPy_UnaryFunction0DVectorViewShape visible prototypes-----------*/ +int UnaryFunction0DVectorViewShape_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0DVECTORVIEWSHAPE_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp new file mode 100644 index 00000000000..095ee066987 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.cpp @@ -0,0 +1,156 @@ +#include "BPy_UnaryFunction0DViewShape.h" + +#include "../BPy_Convert.h" +#include "../Iterator/BPy_Interface0DIterator.h" + +#include "UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h" +#include "UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction0DViewShape instance -----------*/ +static int UnaryFunction0DViewShape___init__(BPy_UnaryFunction0DViewShape* self, PyObject *args, PyObject *kwds); +static void UnaryFunction0DViewShape___dealloc__(BPy_UnaryFunction0DViewShape* self); +static PyObject * UnaryFunction0DViewShape___repr__(BPy_UnaryFunction0DViewShape* self); + +static PyObject * UnaryFunction0DViewShape_getName( BPy_UnaryFunction0DViewShape *self); +static PyObject * UnaryFunction0DViewShape___call__( BPy_UnaryFunction0DViewShape *self, PyObject *args, PyObject *kwds); + +/*----------------------UnaryFunction0DViewShape instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction0DViewShape_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction0DViewShape_getName, METH_NOARGS, "() Returns the string of the name of the unary 0D function."}, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction0DViewShape type definition ------------------------------*/ + +PyTypeObject UnaryFunction0DViewShape_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "UnaryFunction0DViewShape", /* tp_name */ + sizeof(BPy_UnaryFunction0DViewShape), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction0DViewShape___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction0DViewShape___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction0DViewShape___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction0DViewShape objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction0DViewShape_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction0DViewShape___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction0DViewShape_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction0DViewShape_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction0DViewShape_Type ); + PyModule_AddObject(module, "UnaryFunction0DViewShape", (PyObject *)&UnaryFunction0DViewShape_Type); + + if( PyType_Ready( &GetOccludeeF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetOccludeeF0D_Type ); + PyModule_AddObject(module, "GetOccludeeF0D", (PyObject *)&GetOccludeeF0D_Type); + + if( PyType_Ready( &GetShapeF0D_Type ) < 0 ) + return -1; + Py_INCREF( &GetShapeF0D_Type ); + PyModule_AddObject(module, "GetShapeF0D", (PyObject *)&GetShapeF0D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction0DViewShape___init__(BPy_UnaryFunction0DViewShape* self, PyObject *args, PyObject *kwds) +{ + if ( !PyArg_ParseTuple(args, "") ) + return -1; + self->uf0D_viewshape = new UnaryFunction0D<ViewShape*>(); + self->uf0D_viewshape->py_uf0D = (PyObject *)self; + return 0; +} + +void UnaryFunction0DViewShape___dealloc__(BPy_UnaryFunction0DViewShape* self) +{ + if (self->uf0D_viewshape) + delete self->uf0D_viewshape; + UnaryFunction0D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction0DViewShape___repr__(BPy_UnaryFunction0DViewShape* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf0D_viewshape->getName().c_str(), self->uf0D_viewshape ); +} + +PyObject * UnaryFunction0DViewShape_getName( BPy_UnaryFunction0DViewShape *self ) +{ + return PyUnicode_FromFormat( self->uf0D_viewshape->getName().c_str() ); +} + +PyObject * UnaryFunction0DViewShape___call__( BPy_UnaryFunction0DViewShape *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if(!PyArg_ParseTuple(args, "O!", &Interface0DIterator_Type, &obj)) + return NULL; + + if( typeid(*(self->uf0D_viewshape)) == typeid(UnaryFunction0D<ViewShape*>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf0D_viewshape->operator()(*( ((BPy_Interface0DIterator *) obj)->if0D_it )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf0D_viewshape->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return BPy_ViewShape_from_ViewShape( *(self->uf0D_viewshape->result) ); + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h new file mode 100644 index 00000000000..68c888eb36b --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DViewShape.h @@ -0,0 +1,36 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION0DVIEWSHAPE_H +#define FREESTYLE_PYTHON_UNARYFUNCTION0DVIEWSHAPE_H + +#include "../BPy_UnaryFunction0D.h" + +#include "../../view_map/ViewMap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction0DViewShape_Type; + +#define BPy_UnaryFunction0DViewShape_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction0DViewShape_Type) ) + +/*---------------------------Python BPy_UnaryFunction0DViewShape structure definition----------*/ +typedef struct { + BPy_UnaryFunction0D py_uf0D; + UnaryFunction0D<ViewShape*> *uf0D_viewshape; +} BPy_UnaryFunction0DViewShape; + +/*---------------------------Python BPy_UnaryFunction0DViewShape visible prototypes-----------*/ +int UnaryFunction0DViewShape_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION0DVIEWSHAPE_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp new file mode 100644 index 00000000000..059bd93bab1 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_ShapeIdF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ShapeIdF0D instance -----------*/ +static int ShapeIdF0D___init__(BPy_ShapeIdF0D* self, PyObject *args); + +/*-----------------------BPy_ShapeIdF0D type definition ------------------------------*/ + +PyTypeObject ShapeIdF0D_Type = { + PyObject_HEAD_INIT(NULL) + "ShapeIdF0D", /* tp_name */ + sizeof(BPy_ShapeIdF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ShapeIdF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DId_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ShapeIdF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ShapeIdF0D___init__( BPy_ShapeIdF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_id.uf0D_id = new Functions0D::ShapeIdF0D(); + self->py_uf0D_id.uf0D_id->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h new file mode 100644 index 00000000000..11995bb4e88 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_SHAPEIDF0D_H +#define FREESTYLE_PYTHON_SHAPEIDF0D_H + +#include "../BPy_UnaryFunction0DId.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ShapeIdF0D_Type; + +#define BPy_ShapeIdF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ShapeIdF0D_Type) ) + +/*---------------------------Python BPy_ShapeIdF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DId py_uf0D_id; +} BPy_ShapeIdF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_SHAPEIDF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp new file mode 100644 index 00000000000..6b6668503dc --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_MaterialF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for MaterialF0D instance -----------*/ +static int MaterialF0D___init__(BPy_MaterialF0D* self, PyObject *args); + +/*-----------------------BPy_MaterialF0D type definition ------------------------------*/ + +PyTypeObject MaterialF0D_Type = { + PyObject_HEAD_INIT(NULL) + "MaterialF0D", /* tp_name */ + sizeof(BPy_MaterialF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "MaterialF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DMaterial_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)MaterialF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int MaterialF0D___init__( BPy_MaterialF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_material.uf0D_material = new Functions0D::MaterialF0D(); + self->py_uf0D_material.uf0D_material->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h new file mode 100644 index 00000000000..1ae30484ba5 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_MATERIALF0D_H +#define FREESTYLE_PYTHON_MATERIALF0D_H + +#include "../BPy_UnaryFunction0DMaterial.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject MaterialF0D_Type; + +#define BPy_MaterialF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &MaterialF0D_Type) ) + +/*---------------------------Python BPy_MaterialF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DMaterial py_uf0D_material; +} BPy_MaterialF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_MATERIALF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp new file mode 100644 index 00000000000..da4bd4018e7 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_CurveNatureF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for CurveNatureF0D instance -----------*/ + static int CurveNatureF0D___init__(BPy_CurveNatureF0D* self, PyObject *args); + +/*-----------------------BPy_CurveNatureF0D type definition ------------------------------*/ + +PyTypeObject CurveNatureF0D_Type = { + PyObject_HEAD_INIT(NULL) + "CurveNatureF0D", /* tp_name */ + sizeof(BPy_CurveNatureF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "CurveNatureF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DEdgeNature_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)CurveNatureF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int CurveNatureF0D___init__( BPy_CurveNatureF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_edgenature.uf0D_edgenature = new Functions0D::CurveNatureF0D(); + self->py_uf0D_edgenature.uf0D_edgenature->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h new file mode 100644 index 00000000000..63b3050c474 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_CURVENATUREF0D_H +#define FREESTYLE_PYTHON_CURVENATUREF0D_H + +#include "../BPy_UnaryFunction0DEdgeNature.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject CurveNatureF0D_Type; + +#define BPy_CurveNatureF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &CurveNatureF0D_Type) ) + +/*---------------------------Python BPy_CurveNatureF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DEdgeNature py_uf0D_edgenature; +} BPy_CurveNatureF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CURVENATUREF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp new file mode 100644 index 00000000000..eed80894e1b --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_Normal2DF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Normal2DF0D instance -----------*/ +static int Normal2DF0D___init__(BPy_Normal2DF0D* self, PyObject *args); + +/*-----------------------BPy_Normal2DF0D type definition ------------------------------*/ + +PyTypeObject Normal2DF0D_Type = { + PyObject_HEAD_INIT(NULL) + "Normal2DF0D", /* tp_name */ + sizeof(BPy_Normal2DF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Normal2DF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DVec2f_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Normal2DF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int Normal2DF0D___init__( BPy_Normal2DF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_vec2f.uf0D_vec2f = new Functions0D::Normal2DF0D(); + self->py_uf0D_vec2f.uf0D_vec2f->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h new file mode 100644 index 00000000000..0b3be2df428 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_NORMAL2DF0D_H +#define FREESTYLE_PYTHON_NORMAL2DF0D_H + +#include "../BPy_UnaryFunction0DVec2f.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Normal2DF0D_Type; + +#define BPy_Normal2DF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Normal2DF0D_Type) ) + +/*---------------------------Python BPy_Normal2DF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DVec2f py_uf0D_vec2f; +} BPy_Normal2DF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_NORMAL2DF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp new file mode 100644 index 00000000000..e2ab7f3c411 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_VertexOrientation2DF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for VertexOrientation2DF0D instance -----------*/ +static int VertexOrientation2DF0D___init__(BPy_VertexOrientation2DF0D* self, PyObject *args); + +/*-----------------------BPy_VertexOrientation2DF0D type definition ------------------------------*/ + +PyTypeObject VertexOrientation2DF0D_Type = { + PyObject_HEAD_INIT(NULL) + "VertexOrientation2DF0D", /* tp_name */ + sizeof(BPy_VertexOrientation2DF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "VertexOrientation2DF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DVec2f_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)VertexOrientation2DF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int VertexOrientation2DF0D___init__( BPy_VertexOrientation2DF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_vec2f.uf0D_vec2f = new Functions0D::VertexOrientation2DF0D(); + self->py_uf0D_vec2f.uf0D_vec2f->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h new file mode 100644 index 00000000000..1cce9b592ba --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_VERTEXORIENTATION2DF0D_H +#define FREESTYLE_PYTHON_VERTEXORIENTATION2DF0D_H + +#include "../BPy_UnaryFunction0DVec2f.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject VertexOrientation2DF0D_Type; + +#define BPy_VertexOrientation2DF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &VertexOrientation2DF0D_Type) ) + +/*---------------------------Python BPy_VertexOrientation2DF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DVec2f py_uf0D_vec2f; +} BPy_VertexOrientation2DF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_VERTEXORIENTATION2DF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp new file mode 100644 index 00000000000..3adbb97188c --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_VertexOrientation3DF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for VertexOrientation3DF0D instance -----------*/ +static int VertexOrientation3DF0D___init__(BPy_VertexOrientation3DF0D* self, PyObject *args); + +/*-----------------------BPy_VertexOrientation3DF0D type definition ------------------------------*/ + +PyTypeObject VertexOrientation3DF0D_Type = { + PyObject_HEAD_INIT(NULL) + "VertexOrientation3DF0D", /* tp_name */ + sizeof(BPy_VertexOrientation3DF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "VertexOrientation3DF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DVec3f_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)VertexOrientation3DF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int VertexOrientation3DF0D___init__( BPy_VertexOrientation3DF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_vec3f.uf0D_vec3f = new Functions0D::VertexOrientation3DF0D(); + self->py_uf0D_vec3f.uf0D_vec3f->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h new file mode 100644 index 00000000000..80cac529f0b --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_VERTEXORIENTATION3DF0D_H +#define FREESTYLE_PYTHON_VERTEXORIENTATION3DF0D_H + +#include "../BPy_UnaryFunction0DVec3f.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject VertexOrientation3DF0D_Type; + +#define BPy_VertexOrientation3DF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &VertexOrientation3DF0D_Type) ) + +/*---------------------------Python BPy_VertexOrientation3DF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DVec3f py_uf0D_vec3f; +} BPy_VertexOrientation3DF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_VERTEXORIENTATION3DF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp new file mode 100644 index 00000000000..e346efafb28 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetOccludeeF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetOccludeeF0D instance -----------*/ +static int GetOccludeeF0D___init__(BPy_GetOccludeeF0D* self, PyObject *args); + +/*-----------------------BPy_GetOccludeeF0D type definition ------------------------------*/ + +PyTypeObject GetOccludeeF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetOccludeeF0D", /* tp_name */ + sizeof(BPy_GetOccludeeF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetOccludeeF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DViewShape_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetOccludeeF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetOccludeeF0D___init__( BPy_GetOccludeeF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_viewshape.uf0D_viewshape = new Functions0D::GetOccludeeF0D(); + self->py_uf0D_viewshape.uf0D_viewshape->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h new file mode 100644 index 00000000000..fd4f7d92bbb --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETOCCLUDEEF0D_H +#define FREESTYLE_PYTHON_GETOCCLUDEEF0D_H + +#include "../BPy_UnaryFunction0DViewShape.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetOccludeeF0D_Type; + +#define BPy_GetOccludeeF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetOccludeeF0D_Type) ) + +/*---------------------------Python BPy_GetOccludeeF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DViewShape py_uf0D_viewshape; +} BPy_GetOccludeeF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETOCCLUDEEF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp new file mode 100644 index 00000000000..497bac57dc9 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetShapeF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetShapeF0D instance -----------*/ +static int GetShapeF0D___init__(BPy_GetShapeF0D* self, PyObject *args); + +/*-----------------------BPy_GetShapeF0D type definition ------------------------------*/ + +PyTypeObject GetShapeF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetShapeF0D", /* tp_name */ + sizeof(BPy_GetShapeF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetShapeF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DViewShape_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetShapeF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetShapeF0D___init__( BPy_GetShapeF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_viewshape.uf0D_viewshape = new Functions0D::GetShapeF0D(); + self->py_uf0D_viewshape.uf0D_viewshape->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h new file mode 100644 index 00000000000..040c753968d --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETSHAPEF0D_H +#define FREESTYLE_PYTHON_GETSHAPEF0D_H + +#include "../BPy_UnaryFunction0DViewShape.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetShapeF0D_Type; + +#define BPy_GetShapeF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetShapeF0D_Type) ) + +/*---------------------------Python BPy_GetShapeF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DViewShape py_uf0D_viewshape; +} BPy_GetShapeF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETSHAPEF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp new file mode 100644 index 00000000000..cc10bcd0e4a --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_Curvature2DAngleF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Curvature2DAngleF0D instance -----------*/ +static int Curvature2DAngleF0D___init__(BPy_Curvature2DAngleF0D* self, PyObject *args); + +/*-----------------------BPy_Curvature2DAngleF0D type definition ------------------------------*/ + +PyTypeObject Curvature2DAngleF0D_Type = { + PyObject_HEAD_INIT(NULL) + "Curvature2DAngleF0D", /* tp_name */ + sizeof(BPy_Curvature2DAngleF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Curvature2DAngleF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Curvature2DAngleF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int Curvature2DAngleF0D___init__( BPy_Curvature2DAngleF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_double.uf0D_double = new Functions0D::Curvature2DAngleF0D(); + self->py_uf0D_double.uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h new file mode 100644 index 00000000000..810ba04db8a --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_CURVATURE2DANGLEF0D_H +#define FREESTYLE_PYTHON_CURVATURE2DANGLEF0D_H + +#include "../BPy_UnaryFunction0DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Curvature2DAngleF0D_Type; + +#define BPy_Curvature2DAngleF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Curvature2DAngleF0D_Type) ) + +/*---------------------------Python BPy_Curvature2DAngleF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DDouble py_uf0D_double; +} BPy_Curvature2DAngleF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CURVATURE2DANGLEF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp new file mode 100644 index 00000000000..80dbba1ece0 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp @@ -0,0 +1,74 @@ +#include "BPy_DensityF0D.h" + +#include "../../../stroke/AdvancedFunctions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for DensityF0D instance -----------*/ +static int DensityF0D___init__(BPy_DensityF0D* self, PyObject *args); + +/*-----------------------BPy_DensityF0D type definition ------------------------------*/ + +PyTypeObject DensityF0D_Type = { + PyObject_HEAD_INIT(NULL) + "DensityF0D", /* tp_name */ + sizeof(BPy_DensityF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "DensityF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)DensityF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int DensityF0D___init__( BPy_DensityF0D* self, PyObject *args) +{ + double d = 2; + + if( !PyArg_ParseTuple(args, "|d", &d) ) + return -1; + self->py_uf0D_double.uf0D_double = new Functions0D::DensityF0D(d); + self->py_uf0D_double.uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h new file mode 100644 index 00000000000..17ea95a771c --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_DENSITYF0D_H +#define FREESTYLE_PYTHON_DENSITYF0D_H + +#include "../BPy_UnaryFunction0DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject DensityF0D_Type; + +#define BPy_DensityF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &DensityF0D_Type) ) + +/*---------------------------Python BPy_DensityF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DDouble py_uf0D_double; +} BPy_DensityF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_DENSITYF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp new file mode 100644 index 00000000000..e71dc8c226b --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetProjectedXF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetProjectedXF0D instance -----------*/ +static int GetProjectedXF0D___init__(BPy_GetProjectedXF0D* self, PyObject *args); + +/*-----------------------BPy_GetProjectedXF0D type definition ------------------------------*/ + +PyTypeObject GetProjectedXF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetProjectedXF0D", /* tp_name */ + sizeof(BPy_GetProjectedXF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetProjectedXF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetProjectedXF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetProjectedXF0D___init__( BPy_GetProjectedXF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_double.uf0D_double = new Functions0D::GetProjectedXF0D(); + self->py_uf0D_double.uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h new file mode 100644 index 00000000000..da73623cbf0 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETPROJECTEDXF0D_H +#define FREESTYLE_PYTHON_GETPROJECTEDXF0D_H + +#include "../BPy_UnaryFunction0DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetProjectedXF0D_Type; + +#define BPy_GetProjectedXF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetProjectedXF0D_Type) ) + +/*---------------------------Python BPy_GetProjectedXF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DDouble py_uf0D_double; +} BPy_GetProjectedXF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETPROJECTEDXF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp new file mode 100644 index 00000000000..77750a03b91 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetProjectedYF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetProjectedYF0D instance -----------*/ +static int GetProjectedYF0D___init__(BPy_GetProjectedYF0D* self, PyObject *args); + +/*-----------------------BPy_GetProjectedYF0D type definition ------------------------------*/ + +PyTypeObject GetProjectedYF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetProjectedYF0D", /* tp_name */ + sizeof(BPy_GetProjectedYF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetProjectedYF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetProjectedYF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetProjectedYF0D___init__( BPy_GetProjectedYF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_double.uf0D_double = new Functions0D::GetProjectedYF0D(); + self->py_uf0D_double.uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h new file mode 100644 index 00000000000..3a26e093747 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETPROJECTEDYF0D_H +#define FREESTYLE_PYTHON_GETPROJECTEDYF0D_H + +#include "../BPy_UnaryFunction0DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetProjectedYF0D_Type; + +#define BPy_GetProjectedYF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetProjectedYF0D_Type) ) + +/*---------------------------Python BPy_GetProjectedYF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DDouble py_uf0D_double; +} BPy_GetProjectedYF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETPROJECTEDYF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp new file mode 100644 index 00000000000..b67fb019934 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetProjectedZF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetProjectedZF0D instance -----------*/ +static int GetProjectedZF0D___init__(BPy_GetProjectedZF0D* self, PyObject *args); + +/*-----------------------BPy_GetProjectedZF0D type definition ------------------------------*/ + +PyTypeObject GetProjectedZF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetProjectedZF0D", /* tp_name */ + sizeof(BPy_GetProjectedZF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetProjectedZF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetProjectedZF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetProjectedZF0D___init__( BPy_GetProjectedZF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_double.uf0D_double = new Functions0D::GetProjectedZF0D(); + self->py_uf0D_double.uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h new file mode 100644 index 00000000000..aa41b70c660 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETPROJECTEDZF0D_H +#define FREESTYLE_PYTHON_GETPROJECTEDZF0D_H + +#include "../BPy_UnaryFunction0DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetProjectedZF0D_Type; + +#define BPy_GetProjectedZF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetProjectedZF0D_Type) ) + +/*---------------------------Python BPy_GetProjectedZF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DDouble py_uf0D_double; +} BPy_GetProjectedZF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETPROJECTEDZF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp new file mode 100644 index 00000000000..1e56498436a --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetXF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetXF0D instance -----------*/ +static int GetXF0D___init__(BPy_GetXF0D* self, PyObject *args); + +/*-----------------------BPy_GetXF0D type definition ------------------------------*/ + +PyTypeObject GetXF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetXF0D", /* tp_name */ + sizeof(BPy_GetXF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetXF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetXF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetXF0D___init__( BPy_GetXF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_double.uf0D_double = new Functions0D::GetXF0D(); + self->py_uf0D_double.uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h new file mode 100644 index 00000000000..69e9a892f4a --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETXF0D_H +#define FREESTYLE_PYTHON_GETXF0D_H + +#include "../BPy_UnaryFunction0DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetXF0D_Type; + +#define BPy_GetXF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetXF0D_Type) ) + +/*---------------------------Python BPy_GetXF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DDouble py_uf0D_double; +} BPy_GetXF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETXF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp new file mode 100644 index 00000000000..6459ec09345 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetYF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetYF0D instance -----------*/ +static int GetYF0D___init__(BPy_GetYF0D* self, PyObject *args); + +/*-----------------------BPy_GetYF0D type definition ------------------------------*/ + +PyTypeObject GetYF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetYF0D", /* tp_name */ + sizeof(BPy_GetYF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetYF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetYF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetYF0D___init__( BPy_GetYF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_double.uf0D_double = new Functions0D::GetYF0D(); + self->py_uf0D_double.uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h new file mode 100644 index 00000000000..0601f38585f --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETYF0D_H +#define FREESTYLE_PYTHON_GETYF0D_H + +#include "../BPy_UnaryFunction0DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetYF0D_Type; + +#define BPy_GetYF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetYF0D_Type) ) + +/*---------------------------Python BPy_GetYF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DDouble py_uf0D_double; +} BPy_GetYF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETYF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp new file mode 100644 index 00000000000..c3783e29d2c --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetZF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetZF0D instance -----------*/ +static int GetZF0D___init__(BPy_GetZF0D* self, PyObject *args); + +/*-----------------------BPy_GetZF0D type definition ------------------------------*/ + +PyTypeObject GetZF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetZF0D", /* tp_name */ + sizeof(BPy_GetZF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetZF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetZF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetZF0D___init__( BPy_GetZF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_double.uf0D_double = new Functions0D::GetZF0D(); + self->py_uf0D_double.uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h new file mode 100644 index 00000000000..eac52426600 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETZF0D_H +#define FREESTYLE_PYTHON_GETZF0D_H + +#include "../BPy_UnaryFunction0DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetZF0D_Type; + +#define BPy_GetZF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetZF0D_Type) ) + +/*---------------------------Python BPy_GetZF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DDouble py_uf0D_double; +} BPy_GetZF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETZF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp new file mode 100644 index 00000000000..46b882350c6 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp @@ -0,0 +1,74 @@ +#include "BPy_LocalAverageDepthF0D.h" + +#include "../../../stroke/AdvancedFunctions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for LocalAverageDepthF0D instance -----------*/ +static int LocalAverageDepthF0D___init__(BPy_LocalAverageDepthF0D* self, PyObject *args); + +/*-----------------------BPy_LocalAverageDepthF0D type definition ------------------------------*/ + +PyTypeObject LocalAverageDepthF0D_Type = { + PyObject_HEAD_INIT(NULL) + "LocalAverageDepthF0D", /* tp_name */ + sizeof(BPy_LocalAverageDepthF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "LocalAverageDepthF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)LocalAverageDepthF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int LocalAverageDepthF0D___init__( BPy_LocalAverageDepthF0D* self, PyObject *args) +{ + double d = 5.0; + + if( !PyArg_ParseTuple(args, "|d", &d) ) + return -1; + self->py_uf0D_double.uf0D_double = new Functions0D::LocalAverageDepthF0D(d); + self->py_uf0D_double.uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h new file mode 100644 index 00000000000..7385e1d24c1 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF0D_H +#define FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF0D_H + +#include "../BPy_UnaryFunction0DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject LocalAverageDepthF0D_Type; + +#define BPy_LocalAverageDepthF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &LocalAverageDepthF0D_Type) ) + +/*---------------------------Python BPy_LocalAverageDepthF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DDouble py_uf0D_double; +} BPy_LocalAverageDepthF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp new file mode 100644 index 00000000000..b4bf89a425a --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_ZDiscontinuityF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ZDiscontinuityF0D instance -----------*/ +static int ZDiscontinuityF0D___init__(BPy_ZDiscontinuityF0D* self, PyObject *args); + +/*-----------------------BPy_ZDiscontinuityF0D type definition ------------------------------*/ + +PyTypeObject ZDiscontinuityF0D_Type = { + PyObject_HEAD_INIT(NULL) + "ZDiscontinuityF0D", /* tp_name */ + sizeof(BPy_ZDiscontinuityF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ZDiscontinuityF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ZDiscontinuityF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ZDiscontinuityF0D___init__( BPy_ZDiscontinuityF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_double.uf0D_double = new Functions0D::ZDiscontinuityF0D(); + self->py_uf0D_double.uf0D_double->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h new file mode 100644 index 00000000000..a26ba4fdbd6 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_ZDISCONTINUITYF0D_H +#define FREESTYLE_PYTHON_ZDISCONTINUITYF0D_H + +#include "../BPy_UnaryFunction0DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ZDiscontinuityF0D_Type; + +#define BPy_ZDiscontinuityF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ZDiscontinuityF0D_Type) ) + +/*---------------------------Python BPy_ZDiscontinuityF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DDouble py_uf0D_double; +} BPy_ZDiscontinuityF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_ZDISCONTINUITYF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp new file mode 100644 index 00000000000..597280f00c2 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetCurvilinearAbscissaF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetCurvilinearAbscissaF0D instance -----------*/ +static int GetCurvilinearAbscissaF0D___init__(BPy_GetCurvilinearAbscissaF0D* self, PyObject *args); + +/*-----------------------BPy_GetCurvilinearAbscissaF0D type definition ------------------------------*/ + +PyTypeObject GetCurvilinearAbscissaF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetCurvilinearAbscissaF0D", /* tp_name */ + sizeof(BPy_GetCurvilinearAbscissaF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetCurvilinearAbscissaF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DFloat_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetCurvilinearAbscissaF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetCurvilinearAbscissaF0D___init__( BPy_GetCurvilinearAbscissaF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_float.uf0D_float = new Functions0D::GetCurvilinearAbscissaF0D(); + self->py_uf0D_float.uf0D_float->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h new file mode 100644 index 00000000000..0cb56fcec70 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETCURVILINEARABSCISSAF0D_H +#define FREESTYLE_PYTHON_GETCURVILINEARABSCISSAF0D_H + +#include "../BPy_UnaryFunction0DFloat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetCurvilinearAbscissaF0D_Type; + +#define BPy_GetCurvilinearAbscissaF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetCurvilinearAbscissaF0D_Type) ) + +/*---------------------------Python BPy_GetCurvilinearAbscissaF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DFloat py_uf0D_float; +} BPy_GetCurvilinearAbscissaF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETCURVILINEARABSCISSAF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp new file mode 100644 index 00000000000..21f116c0850 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetParameterF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetParameterF0D instance -----------*/ +static int GetParameterF0D___init__(BPy_GetParameterF0D* self, PyObject *args); + +/*-----------------------BPy_GetParameterF0D type definition ------------------------------*/ + +PyTypeObject GetParameterF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetParameterF0D", /* tp_name */ + sizeof(BPy_GetParameterF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetParameterF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DFloat_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetParameterF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetParameterF0D___init__( BPy_GetParameterF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_float.uf0D_float = new Functions0D::GetParameterF0D(); + self->py_uf0D_float.uf0D_float->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h new file mode 100644 index 00000000000..4817e5cec86 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETPARAMETERF0D_H +#define FREESTYLE_PYTHON_GETPARAMETERF0D_H + +#include "../BPy_UnaryFunction0DFloat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetParameterF0D_Type; + +#define BPy_GetParameterF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetParameterF0D_Type) ) + +/*---------------------------Python BPy_GetParameterF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DFloat py_uf0D_float; +} BPy_GetParameterF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETPARAMETERF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp new file mode 100644 index 00000000000..787ba12dfcc --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp @@ -0,0 +1,74 @@ +#include "BPy_GetViewMapGradientNormF0D.h" + +#include "../../../stroke/AdvancedFunctions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetViewMapGradientNormF0D instance -----------*/ +static int GetViewMapGradientNormF0D___init__(BPy_GetViewMapGradientNormF0D* self, PyObject *args); + +/*-----------------------BPy_GetViewMapGradientNormF0D type definition ------------------------------*/ + +PyTypeObject GetViewMapGradientNormF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetViewMapGradientNormF0D", /* tp_name */ + sizeof(BPy_GetViewMapGradientNormF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetViewMapGradientNormF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DFloat_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetViewMapGradientNormF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetViewMapGradientNormF0D___init__( BPy_GetViewMapGradientNormF0D* self, PyObject *args) +{ + int i; + + if( !PyArg_ParseTuple(args, "i", &i) ) + return -1; + self->py_uf0D_float.uf0D_float = new Functions0D::GetViewMapGradientNormF0D(i); + self->py_uf0D_float.uf0D_float->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h new file mode 100644 index 00000000000..c072ba7f408 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF0D_H +#define FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF0D_H + +#include "../BPy_UnaryFunction0DFloat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetViewMapGradientNormF0D_Type; + +#define BPy_GetViewMapGradientNormF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetViewMapGradientNormF0D_Type) ) + +/*---------------------------Python BPy_GetViewMapGradientNormF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DFloat py_uf0D_float; +} BPy_GetViewMapGradientNormF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp new file mode 100644 index 00000000000..877dd9c7e04 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp @@ -0,0 +1,74 @@ +#include "BPy_ReadCompleteViewMapPixelF0D.h" + +#include "../../../stroke/AdvancedFunctions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ReadCompleteViewMapPixelF0D instance -----------*/ + static int ReadCompleteViewMapPixelF0D___init__(BPy_ReadCompleteViewMapPixelF0D* self, PyObject *args); + +/*-----------------------BPy_ReadCompleteViewMapPixelF0D type definition ------------------------------*/ + +PyTypeObject ReadCompleteViewMapPixelF0D_Type = { + PyObject_HEAD_INIT(NULL) + "ReadCompleteViewMapPixelF0D", /* tp_name */ + sizeof(BPy_ReadCompleteViewMapPixelF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ReadCompleteViewMapPixelF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DFloat_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ReadCompleteViewMapPixelF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ReadCompleteViewMapPixelF0D___init__( BPy_ReadCompleteViewMapPixelF0D* self, PyObject *args) +{ + int i; + + if( !PyArg_ParseTuple(args, "i", &i) ) + return -1; + self->py_uf0D_float.uf0D_float = new Functions0D::ReadCompleteViewMapPixelF0D(i); + self->py_uf0D_float.uf0D_float->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h new file mode 100644 index 00000000000..6a10e6c06a4 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_READCOMPLETEVIEWMAPPIXELF0D_H +#define FREESTYLE_PYTHON_READCOMPLETEVIEWMAPPIXELF0D_H + +#include "../BPy_UnaryFunction0DFloat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ReadCompleteViewMapPixelF0D_Type; + +#define BPy_ReadCompleteViewMapPixelF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ReadCompleteViewMapPixelF0D_Type) ) + +/*---------------------------Python BPy_ReadCompleteViewMapPixelF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DFloat py_uf0D_float; +} BPy_ReadCompleteViewMapPixelF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_READCOMPLETEVIEWMAPPIXELF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp new file mode 100644 index 00000000000..45316e322c3 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp @@ -0,0 +1,75 @@ +#include "BPy_ReadMapPixelF0D.h" + +#include "../../../stroke/AdvancedFunctions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ReadMapPixelF0D instance -----------*/ +static int ReadMapPixelF0D___init__(BPy_ReadMapPixelF0D* self, PyObject *args); + +/*-----------------------BPy_ReadMapPixelF0D type definition ------------------------------*/ + +PyTypeObject ReadMapPixelF0D_Type = { + PyObject_HEAD_INIT(NULL) + "ReadMapPixelF0D", /* tp_name */ + sizeof(BPy_ReadMapPixelF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ReadMapPixelF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DFloat_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ReadMapPixelF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ReadMapPixelF0D___init__( BPy_ReadMapPixelF0D* self, PyObject *args) +{ + const char *s; + int i; + + if( !PyArg_ParseTuple(args, "si", &s, &i) ) + return -1; + self->py_uf0D_float.uf0D_float = new Functions0D::ReadMapPixelF0D(s,i); + self->py_uf0D_float.uf0D_float->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h new file mode 100644 index 00000000000..9aed0cd82bf --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_READMAPPIXELF0D_H +#define FREESTYLE_PYTHON_READMAPPIXELF0D_H + +#include "../BPy_UnaryFunction0DFloat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ReadMapPixelF0D_Type; + +#define BPy_ReadMapPixelF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ReadMapPixelF0D_Type) ) + +/*---------------------------Python BPy_ReadMapPixelF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DFloat py_uf0D_float; +} BPy_ReadMapPixelF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_READMAPPIXELF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp new file mode 100644 index 00000000000..84369658b76 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp @@ -0,0 +1,75 @@ +#include "BPy_ReadSteerableViewMapPixelF0D.h" + +#include "../../../stroke/AdvancedFunctions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ReadSteerableViewMapPixelF0D instance -----------*/ +static int ReadSteerableViewMapPixelF0D___init__(BPy_ReadSteerableViewMapPixelF0D* self, PyObject *args); + +/*-----------------------BPy_ReadSteerableViewMapPixelF0D type definition ------------------------------*/ + +PyTypeObject ReadSteerableViewMapPixelF0D_Type = { + PyObject_HEAD_INIT(NULL) + "ReadSteerableViewMapPixelF0D", /* tp_name */ + sizeof(BPy_ReadSteerableViewMapPixelF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ReadSteerableViewMapPixelF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DFloat_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ReadSteerableViewMapPixelF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ReadSteerableViewMapPixelF0D___init__( BPy_ReadSteerableViewMapPixelF0D* self, PyObject *args) +{ + unsigned int u; + int i; + + if( !PyArg_ParseTuple(args, "Ii", &u, &i) ) + return -1; + self->py_uf0D_float.uf0D_float = new Functions0D::ReadSteerableViewMapPixelF0D(u,i); + self->py_uf0D_float.uf0D_float->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h new file mode 100644 index 00000000000..a881a10f72d --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_READSTEERABLEVIEWMAPPIXELF0D_H +#define FREESTYLE_PYTHON_READSTEERABLEVIEWMAPPIXELF0D_H + +#include "../BPy_UnaryFunction0DFloat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ReadSteerableViewMapPixelF0D_Type; + +#define BPy_ReadSteerableViewMapPixelF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ReadSteerableViewMapPixelF0D_Type) ) + +/*---------------------------Python BPy_ReadSteerableViewMapPixelF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DFloat py_uf0D_float; +} BPy_ReadSteerableViewMapPixelF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_READSTEERABLEVIEWMAPPIXELF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp new file mode 100644 index 00000000000..5dce83febe3 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_QuantitativeInvisibilityF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for QuantitativeInvisibilityF0D instance -----------*/ +static int QuantitativeInvisibilityF0D___init__(BPy_QuantitativeInvisibilityF0D* self, PyObject *args); + +/*-----------------------BPy_QuantitativeInvisibilityF0D type definition ------------------------------*/ + +PyTypeObject QuantitativeInvisibilityF0D_Type = { + PyObject_HEAD_INIT(NULL) + "QuantitativeInvisibilityF0D", /* tp_name */ + sizeof(BPy_QuantitativeInvisibilityF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "QuantitativeInvisibilityF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DUnsigned_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)QuantitativeInvisibilityF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int QuantitativeInvisibilityF0D___init__( BPy_QuantitativeInvisibilityF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_unsigned.uf0D_unsigned = new Functions0D::QuantitativeInvisibilityF0D(); + self->py_uf0D_unsigned.uf0D_unsigned->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h new file mode 100644 index 00000000000..39b73343608 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF0D_H +#define FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF0D_H + +#include "../BPy_UnaryFunction0DUnsigned.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject QuantitativeInvisibilityF0D_Type; + +#define BPy_QuantitativeInvisibilityF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &QuantitativeInvisibilityF0D_Type) ) + +/*---------------------------Python BPy_QuantitativeInvisibilityF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DUnsigned py_uf0D_unsigned; +} BPy_QuantitativeInvisibilityF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp new file mode 100644 index 00000000000..49264db8650 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp @@ -0,0 +1,72 @@ +#include "BPy_GetOccludersF0D.h" + +#include "../../../view_map/Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetOccludersF0D instance -----------*/ +static int GetOccludersF0D___init__(BPy_GetOccludersF0D* self, PyObject *args); + +/*-----------------------BPy_GetOccludersF0D type definition ------------------------------*/ + +PyTypeObject GetOccludersF0D_Type = { + PyObject_HEAD_INIT(NULL) + "GetOccludersF0D", /* tp_name */ + sizeof(BPy_GetOccludersF0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetOccludersF0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction0DVectorViewShape_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetOccludersF0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetOccludersF0D___init__( BPy_GetOccludersF0D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf0D_vectorviewshape.uf0D_vectorviewshape = new Functions0D::GetOccludersF0D(); + self->py_uf0D_vectorviewshape.uf0D_vectorviewshape->py_uf0D = (PyObject *)self; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h new file mode 100644 index 00000000000..0e92158a2e7 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETOCCLUDERSF0D_H +#define FREESTYLE_PYTHON_GETOCCLUDERSF0D_H + +#include "../BPy_UnaryFunction0DVectorViewShape.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetOccludersF0D_Type; + +#define BPy_GetOccludersF0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetOccludersF0D_Type) ) + +/*---------------------------Python BPy_GetOccludersF0D structure definition----------*/ +typedef struct { + BPy_UnaryFunction0DVectorViewShape py_uf0D_vectorviewshape; +} BPy_GetOccludersF0D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETOCCLUDERSF0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp new file mode 100644 index 00000000000..b6053ac1cb2 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.cpp @@ -0,0 +1,259 @@ +#include "BPy_UnaryFunction1DDouble.h" + +#include "../BPy_Convert.h" +#include "../BPy_Interface1D.h" +#include "../BPy_IntegrationType.h" + +#include "UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h" +#include "UnaryFunction1D_double/BPy_DensityF1D.h" +#include "UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h" +#include "UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h" +#include "UnaryFunction1D_double/BPy_GetProjectedXF1D.h" +#include "UnaryFunction1D_double/BPy_GetProjectedYF1D.h" +#include "UnaryFunction1D_double/BPy_GetProjectedZF1D.h" +#include "UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h" +#include "UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h" +#include "UnaryFunction1D_double/BPy_GetXF1D.h" +#include "UnaryFunction1D_double/BPy_GetYF1D.h" +#include "UnaryFunction1D_double/BPy_GetZF1D.h" +#include "UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h" +#include "UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction1DDouble instance -----------*/ +static int UnaryFunction1DDouble___init__(BPy_UnaryFunction1DDouble* self, PyObject *args); +static void UnaryFunction1DDouble___dealloc__(BPy_UnaryFunction1DDouble* self); +static PyObject * UnaryFunction1DDouble___repr__(BPy_UnaryFunction1DDouble* self); + +static PyObject * UnaryFunction1DDouble_getName( BPy_UnaryFunction1DDouble *self); +static PyObject * UnaryFunction1DDouble___call__( BPy_UnaryFunction1DDouble *self, PyObject *args, PyObject *kwds); +static PyObject * UnaryFunction1DDouble_setIntegrationType(BPy_UnaryFunction1DDouble* self, PyObject *args); +static PyObject * UnaryFunction1DDouble_getIntegrationType(BPy_UnaryFunction1DDouble* self); + +/*----------------------UnaryFunction1DDouble instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction1DDouble_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction1DDouble_getName, METH_NOARGS, "() Returns the string of the name of the unary 1D function."}, + {"setIntegrationType", ( PyCFunction ) UnaryFunction1DDouble_setIntegrationType, METH_VARARGS, "(IntegrationType i) Sets the integration method" }, + {"getIntegrationType", ( PyCFunction ) UnaryFunction1DDouble_getIntegrationType, METH_NOARGS, "() Returns the integration method." }, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction1DDouble type definition ------------------------------*/ + +PyTypeObject UnaryFunction1DDouble_Type = { + PyObject_HEAD_INIT(NULL) + "UnaryFunction1DDouble", /* tp_name */ + sizeof(BPy_UnaryFunction1DDouble), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction1DDouble___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction1DDouble___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction1DDouble___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction1DDouble objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction1DDouble_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction1DDouble___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction1DDouble_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction1DDouble_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction1DDouble_Type ); + PyModule_AddObject(module, "UnaryFunction1DDouble", (PyObject *)&UnaryFunction1DDouble_Type); + + if( PyType_Ready( &DensityF1D_Type ) < 0 ) + return -1; + Py_INCREF( &DensityF1D_Type ); + PyModule_AddObject(module, "DensityF1D", (PyObject *)&DensityF1D_Type); + + if( PyType_Ready( &Curvature2DAngleF1D_Type ) < 0 ) + return -1; + Py_INCREF( &Curvature2DAngleF1D_Type ); + PyModule_AddObject(module, "Curvature2DAngleF1D", (PyObject *)&Curvature2DAngleF1D_Type); + + if( PyType_Ready( &GetCompleteViewMapDensityF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetCompleteViewMapDensityF1D_Type ); + PyModule_AddObject(module, "GetCompleteViewMapDensityF1D", (PyObject *)&GetCompleteViewMapDensityF1D_Type); + + if( PyType_Ready( &GetDirectionalViewMapDensityF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetDirectionalViewMapDensityF1D_Type ); + PyModule_AddObject(module, "GetDirectionalViewMapDensityF1D", (PyObject *)&GetDirectionalViewMapDensityF1D_Type); + + if( PyType_Ready( &GetProjectedXF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetProjectedXF1D_Type ); + PyModule_AddObject(module, "GetProjectedXF1D", (PyObject *)&GetProjectedXF1D_Type); + + if( PyType_Ready( &GetProjectedYF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetProjectedYF1D_Type ); + PyModule_AddObject(module, "GetProjectedYF1D", (PyObject *)&GetProjectedYF1D_Type); + + if( PyType_Ready( &GetProjectedZF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetProjectedZF1D_Type ); + PyModule_AddObject(module, "GetProjectedZF1D", (PyObject *)&GetProjectedZF1D_Type); + + if( PyType_Ready( &GetSteerableViewMapDensityF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetSteerableViewMapDensityF1D_Type ); + PyModule_AddObject(module, "GetSteerableViewMapDensityF1D", (PyObject *)&GetSteerableViewMapDensityF1D_Type); + + if( PyType_Ready( &GetViewMapGradientNormF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetViewMapGradientNormF1D_Type ); + PyModule_AddObject(module, "GetViewMapGradientNormF1D", (PyObject *)&GetViewMapGradientNormF1D_Type); + + if( PyType_Ready( &GetXF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetXF1D_Type ); + PyModule_AddObject(module, "GetXF1D", (PyObject *)&GetXF1D_Type); + + if( PyType_Ready( &GetYF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetYF1D_Type ); + PyModule_AddObject(module, "GetYF1D", (PyObject *)&GetYF1D_Type); + + if( PyType_Ready( &GetZF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetZF1D_Type ); + PyModule_AddObject(module, "GetZF1D", (PyObject *)&GetZF1D_Type); + + if( PyType_Ready( &LocalAverageDepthF1D_Type ) < 0 ) + return -1; + Py_INCREF( &LocalAverageDepthF1D_Type ); + PyModule_AddObject(module, "LocalAverageDepthF1D", (PyObject *)&LocalAverageDepthF1D_Type); + + if( PyType_Ready( &ZDiscontinuityF1D_Type ) < 0 ) + return -1; + Py_INCREF( &ZDiscontinuityF1D_Type ); + PyModule_AddObject(module, "ZDiscontinuityF1D", (PyObject *)&ZDiscontinuityF1D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction1DDouble___init__(BPy_UnaryFunction1DDouble* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + if( !obj ) + self->uf1D_double = new UnaryFunction1D<double>(); + else { + self->uf1D_double = new UnaryFunction1D<double>( IntegrationType_from_BPy_IntegrationType(obj) ); + } + + self->uf1D_double->py_uf1D = (PyObject *)self; + + return 0; +} + +void UnaryFunction1DDouble___dealloc__(BPy_UnaryFunction1DDouble* self) +{ + if (self->uf1D_double) + delete self->uf1D_double; + UnaryFunction1D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction1DDouble___repr__(BPy_UnaryFunction1DDouble* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf1D_double->getName().c_str(), self->uf1D_double ); +} + +PyObject * UnaryFunction1DDouble_getName( BPy_UnaryFunction1DDouble *self ) +{ + return PyUnicode_FromFormat( self->uf1D_double->getName().c_str() ); +} + +PyObject * UnaryFunction1DDouble___call__( BPy_UnaryFunction1DDouble *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!", &Interface1D_Type, &obj) ) + return NULL; + + if( typeid(*(self->uf1D_double)) == typeid(UnaryFunction1D<double>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf1D_double->operator()(*( ((BPy_Interface1D *) obj)->if1D )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf1D_double->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return PyFloat_FromDouble( self->uf1D_double->result ); + +} + +PyObject * UnaryFunction1DDouble_setIntegrationType(BPy_UnaryFunction1DDouble* self, PyObject *args) +{ + PyObject *obj; + + if( !PyArg_ParseTuple(args, "O!", &IntegrationType_Type, &obj) ) + return NULL; + + self->uf1D_double->setIntegrationType( IntegrationType_from_BPy_IntegrationType(obj) ); + Py_RETURN_NONE; +} + +PyObject * UnaryFunction1DDouble_getIntegrationType(BPy_UnaryFunction1DDouble* self) { + return BPy_IntegrationType_from_IntegrationType( self->uf1D_double->getIntegrationType() ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h new file mode 100644 index 00000000000..9a9170cfe17 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DDouble.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION1DDOUBLE_H +#define FREESTYLE_PYTHON_UNARYFUNCTION1DDOUBLE_H + +#include "../BPy_UnaryFunction1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction1DDouble_Type; + +#define BPy_UnaryFunction1DDouble_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction1DDouble_Type) ) + +/*---------------------------Python BPy_UnaryFunction1DDouble structure definition----------*/ +typedef struct { + BPy_UnaryFunction1D py_uf1D; + UnaryFunction1D<double> *uf1D_double; +} BPy_UnaryFunction1DDouble; + +/*---------------------------Python BPy_UnaryFunction1DDouble visible prototypes-----------*/ +int UnaryFunction1DDouble_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION1DDOUBLE_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp new file mode 100644 index 00000000000..c7eb84e3943 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.cpp @@ -0,0 +1,178 @@ +#include "BPy_UnaryFunction1DEdgeNature.h" + +#include "../BPy_Convert.h" +#include "../BPy_Interface1D.h" +#include "../BPy_IntegrationType.h" + +#include "UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction1DEdgeNature instance -----------*/ +static int UnaryFunction1DEdgeNature___init__(BPy_UnaryFunction1DEdgeNature* self, PyObject *args); +static void UnaryFunction1DEdgeNature___dealloc__(BPy_UnaryFunction1DEdgeNature* self); +static PyObject * UnaryFunction1DEdgeNature___repr__(BPy_UnaryFunction1DEdgeNature* self); + +static PyObject * UnaryFunction1DEdgeNature_getName( BPy_UnaryFunction1DEdgeNature *self); +static PyObject * UnaryFunction1DEdgeNature___call__( BPy_UnaryFunction1DEdgeNature *self, PyObject *args, PyObject *kwds); +static PyObject * UnaryFunction1DEdgeNature_setIntegrationType(BPy_UnaryFunction1DEdgeNature* self, PyObject *args); +static PyObject * UnaryFunction1DEdgeNature_getIntegrationType(BPy_UnaryFunction1DEdgeNature* self); + +/*----------------------UnaryFunction1DEdgeNature instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction1DEdgeNature_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction1DEdgeNature_getName, METH_NOARGS, "() Returns the string of the name of the unary 1D function."}, + {"setIntegrationType", ( PyCFunction ) UnaryFunction1DEdgeNature_setIntegrationType, METH_VARARGS, "(IntegrationType i) Sets the integration method" }, + {"getIntegrationType", ( PyCFunction ) UnaryFunction1DEdgeNature_getIntegrationType, METH_NOARGS, "() Returns the integration method." }, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction1DEdgeNature type definition ------------------------------*/ + +PyTypeObject UnaryFunction1DEdgeNature_Type = { + PyObject_HEAD_INIT(NULL) + "UnaryFunction1DEdgeNature", /* tp_name */ + sizeof(BPy_UnaryFunction1DEdgeNature), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction1DEdgeNature___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction1DEdgeNature___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction1DEdgeNature___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction1DEdgeNature objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction1DEdgeNature_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction1DEdgeNature___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction1DEdgeNature_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction1DEdgeNature_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction1DEdgeNature_Type ); + PyModule_AddObject(module, "UnaryFunction1DEdgeNature", (PyObject *)&UnaryFunction1DEdgeNature_Type); + + if( PyType_Ready( &CurveNatureF1D_Type ) < 0 ) + return -1; + Py_INCREF( &CurveNatureF1D_Type ); + PyModule_AddObject(module, "CurveNatureF1D", (PyObject *)&CurveNatureF1D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction1DEdgeNature___init__(BPy_UnaryFunction1DEdgeNature* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + if( !obj ) + self->uf1D_edgenature = new UnaryFunction1D<Nature::EdgeNature>(); + else { + self->uf1D_edgenature = new UnaryFunction1D<Nature::EdgeNature>( IntegrationType_from_BPy_IntegrationType(obj) ); + } + + self->uf1D_edgenature->py_uf1D = (PyObject *)self; + + return 0; +} +void UnaryFunction1DEdgeNature___dealloc__(BPy_UnaryFunction1DEdgeNature* self) +{ + if (self->uf1D_edgenature) + delete self->uf1D_edgenature; + UnaryFunction1D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction1DEdgeNature___repr__(BPy_UnaryFunction1DEdgeNature* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf1D_edgenature->getName().c_str(), self->uf1D_edgenature ); +} + +PyObject * UnaryFunction1DEdgeNature_getName( BPy_UnaryFunction1DEdgeNature *self ) +{ + return PyUnicode_FromFormat( self->uf1D_edgenature->getName().c_str() ); +} + +PyObject * UnaryFunction1DEdgeNature___call__( BPy_UnaryFunction1DEdgeNature *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!", &Interface1D_Type, &obj) ) + return NULL; + + if( typeid(*(self->uf1D_edgenature)) == typeid(UnaryFunction1D<Nature::EdgeNature>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf1D_edgenature->operator()(*( ((BPy_Interface1D *) obj)->if1D )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf1D_edgenature->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return BPy_Nature_from_Nature( self->uf1D_edgenature->result ); + +} + +PyObject * UnaryFunction1DEdgeNature_setIntegrationType(BPy_UnaryFunction1DEdgeNature* self, PyObject *args) +{ + PyObject *obj; + + if( !PyArg_ParseTuple(args, "O!", &IntegrationType_Type, &obj) ) + return NULL; + + self->uf1D_edgenature->setIntegrationType( IntegrationType_from_BPy_IntegrationType(obj) ); + Py_RETURN_NONE; +} + +PyObject * UnaryFunction1DEdgeNature_getIntegrationType(BPy_UnaryFunction1DEdgeNature* self) { + return BPy_IntegrationType_from_IntegrationType( self->uf1D_edgenature->getIntegrationType() ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h new file mode 100644 index 00000000000..05e3e522c4b --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h @@ -0,0 +1,36 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION1DEDGENATURE_H +#define FREESTYLE_PYTHON_UNARYFUNCTION1DEDGENATURE_H + +#include "../BPy_UnaryFunction1D.h" + +#include "../../winged_edge/Nature.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction1DEdgeNature_Type; + +#define BPy_UnaryFunction1DEdgeNature_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction1DEdgeNature_Type) ) + +/*---------------------------Python BPy_UnaryFunction1DEdgeNature structure definition----------*/ +typedef struct { + BPy_UnaryFunction1D py_uf1D; + UnaryFunction1D<Nature::EdgeNature> *uf1D_edgenature; +} BPy_UnaryFunction1DEdgeNature; + +/*---------------------------Python BPy_UnaryFunction1DEdgeNature visible prototypes-----------*/ +int UnaryFunction1DEdgeNature_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION1DEDGENATURE_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp new file mode 100644 index 00000000000..272ee1e4f15 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.cpp @@ -0,0 +1,171 @@ +#include "BPy_UnaryFunction1DFloat.h" + +#include "../BPy_Convert.h" +#include "../BPy_Interface1D.h" +#include "../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction1DFloat instance -----------*/ +static int UnaryFunction1DFloat___init__(BPy_UnaryFunction1DFloat* self, PyObject *args); +static void UnaryFunction1DFloat___dealloc__(BPy_UnaryFunction1DFloat* self); +static PyObject * UnaryFunction1DFloat___repr__(BPy_UnaryFunction1DFloat* self); + +static PyObject * UnaryFunction1DFloat_getName( BPy_UnaryFunction1DFloat *self); +static PyObject * UnaryFunction1DFloat___call__( BPy_UnaryFunction1DFloat *self, PyObject *args, PyObject *kwds); +static PyObject * UnaryFunction1DFloat_setIntegrationType(BPy_UnaryFunction1DFloat* self, PyObject *args); +static PyObject * UnaryFunction1DFloat_getIntegrationType(BPy_UnaryFunction1DFloat* self); + +/*----------------------UnaryFunction1DFloat instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction1DFloat_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction1DFloat_getName, METH_NOARGS, "() Returns the string of the name of the unary 1D function."}, + {"setIntegrationType", ( PyCFunction ) UnaryFunction1DFloat_setIntegrationType, METH_VARARGS, "(IntegrationType i) Sets the integration method" }, + {"getIntegrationType", ( PyCFunction ) UnaryFunction1DFloat_getIntegrationType, METH_NOARGS, "() Returns the integration method." }, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction1DFloat type definition ------------------------------*/ + +PyTypeObject UnaryFunction1DFloat_Type = { + PyObject_HEAD_INIT(NULL) + "UnaryFunction1DFloat", /* tp_name */ + sizeof(BPy_UnaryFunction1DFloat), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction1DFloat___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction1DFloat___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction1DFloat___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction1DFloat objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction1DFloat_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction1DFloat___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction1DFloat_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction1DFloat_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction1DFloat_Type ); + PyModule_AddObject(module, "UnaryFunction1DFloat", (PyObject *)&UnaryFunction1DFloat_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction1DFloat___init__(BPy_UnaryFunction1DFloat* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + if( !obj ) + self->uf1D_float = new UnaryFunction1D<float>(); + else { + self->uf1D_float = new UnaryFunction1D<float>( IntegrationType_from_BPy_IntegrationType(obj) ); + } + + self->uf1D_float->py_uf1D = (PyObject *)self; + + return 0; +} +void UnaryFunction1DFloat___dealloc__(BPy_UnaryFunction1DFloat* self) +{ + if (self->uf1D_float) + delete self->uf1D_float; + UnaryFunction1D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction1DFloat___repr__(BPy_UnaryFunction1DFloat* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf1D_float->getName().c_str(), self->uf1D_float ); +} + +PyObject * UnaryFunction1DFloat_getName( BPy_UnaryFunction1DFloat *self ) +{ + return PyUnicode_FromFormat( self->uf1D_float->getName().c_str() ); +} + +PyObject * UnaryFunction1DFloat___call__( BPy_UnaryFunction1DFloat *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!", &Interface1D_Type, &obj) ) + return NULL; + + if( typeid(*(self->uf1D_float)) == typeid(UnaryFunction1D<float>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf1D_float->operator()(*( ((BPy_Interface1D *) obj)->if1D )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf1D_float->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return PyFloat_FromDouble( self->uf1D_float->result ); + +} + +PyObject * UnaryFunction1DFloat_setIntegrationType(BPy_UnaryFunction1DFloat* self, PyObject *args) +{ + PyObject *obj; + + if( !PyArg_ParseTuple(args, "O!", &IntegrationType_Type, &obj) ) + return NULL; + + self->uf1D_float->setIntegrationType( IntegrationType_from_BPy_IntegrationType(obj) ); + Py_RETURN_NONE; +} + +PyObject * UnaryFunction1DFloat_getIntegrationType(BPy_UnaryFunction1DFloat* self) { + return BPy_IntegrationType_from_IntegrationType( self->uf1D_float->getIntegrationType() ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h new file mode 100644 index 00000000000..529b382372e --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DFloat.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION1DFLOAT_H +#define FREESTYLE_PYTHON_UNARYFUNCTION1DFLOAT_H + +#include "../BPy_UnaryFunction1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction1DFloat_Type; + +#define BPy_UnaryFunction1DFloat_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction1DFloat_Type) ) + +/*---------------------------Python BPy_UnaryFunction1DFloat structure definition----------*/ +typedef struct { + BPy_UnaryFunction1D py_uf1D; + UnaryFunction1D<float> *uf1D_float; +} BPy_UnaryFunction1DFloat; + +/*---------------------------Python BPy_UnaryFunction1DFloat visible prototypes-----------*/ +int UnaryFunction1DFloat_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION1DFLOAT_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp new file mode 100644 index 00000000000..d5f3d38ff4b --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.cpp @@ -0,0 +1,178 @@ +#include "BPy_UnaryFunction1DUnsigned.h" + +#include "../BPy_Convert.h" +#include "../BPy_Interface1D.h" +#include "../BPy_IntegrationType.h" + +#include "UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction1DUnsigned instance -----------*/ +static int UnaryFunction1DUnsigned___init__(BPy_UnaryFunction1DUnsigned* self, PyObject *args); +static void UnaryFunction1DUnsigned___dealloc__(BPy_UnaryFunction1DUnsigned* self); +static PyObject * UnaryFunction1DUnsigned___repr__(BPy_UnaryFunction1DUnsigned* self); + +static PyObject * UnaryFunction1DUnsigned_getName( BPy_UnaryFunction1DUnsigned *self); +static PyObject * UnaryFunction1DUnsigned___call__( BPy_UnaryFunction1DUnsigned *self, PyObject *args, PyObject *kwds); +static PyObject * UnaryFunction1DUnsigned_setIntegrationType(BPy_UnaryFunction1DUnsigned* self, PyObject *args); +static PyObject * UnaryFunction1DUnsigned_getIntegrationType(BPy_UnaryFunction1DUnsigned* self); + +/*----------------------UnaryFunction1DUnsigned instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction1DUnsigned_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction1DUnsigned_getName, METH_NOARGS, "() Returns the string of the name of the unary 1D function."}, + {"setIntegrationType", ( PyCFunction ) UnaryFunction1DUnsigned_setIntegrationType, METH_VARARGS, "(IntegrationType i) Sets the integration method" }, + {"getIntegrationType", ( PyCFunction ) UnaryFunction1DUnsigned_getIntegrationType, METH_NOARGS, "() Returns the integration method." }, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction1DUnsigned type definition ------------------------------*/ + +PyTypeObject UnaryFunction1DUnsigned_Type = { + PyObject_HEAD_INIT(NULL) + "UnaryFunction1DUnsigned", /* tp_name */ + sizeof(BPy_UnaryFunction1DUnsigned), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction1DUnsigned___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction1DUnsigned___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction1DUnsigned___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction1DUnsigned objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction1DUnsigned_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction1DUnsigned___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction1DUnsigned_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction1DUnsigned_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction1DUnsigned_Type ); + PyModule_AddObject(module, "UnaryFunction1DUnsigned", (PyObject *)&UnaryFunction1DUnsigned_Type); + + if( PyType_Ready( &QuantitativeInvisibilityF1D_Type ) < 0 ) + return -1; + Py_INCREF( &QuantitativeInvisibilityF1D_Type ); + PyModule_AddObject(module, "QuantitativeInvisibilityF1D", (PyObject *)&QuantitativeInvisibilityF1D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction1DUnsigned___init__(BPy_UnaryFunction1DUnsigned* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + if( !obj ) + self->uf1D_unsigned = new UnaryFunction1D<unsigned int>(); + else { + self->uf1D_unsigned = new UnaryFunction1D<unsigned int>( IntegrationType_from_BPy_IntegrationType(obj) ); + } + + self->uf1D_unsigned->py_uf1D = (PyObject *)self; + + return 0; +} +void UnaryFunction1DUnsigned___dealloc__(BPy_UnaryFunction1DUnsigned* self) +{ + if (self->uf1D_unsigned) + delete self->uf1D_unsigned; + UnaryFunction1D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction1DUnsigned___repr__(BPy_UnaryFunction1DUnsigned* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf1D_unsigned->getName().c_str(), self->uf1D_unsigned ); +} + +PyObject * UnaryFunction1DUnsigned_getName( BPy_UnaryFunction1DUnsigned *self ) +{ + return PyUnicode_FromFormat( self->uf1D_unsigned->getName().c_str() ); +} + +PyObject * UnaryFunction1DUnsigned___call__( BPy_UnaryFunction1DUnsigned *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!", &Interface1D_Type, &obj) ) + return NULL; + + if( typeid(*(self->uf1D_unsigned)) == typeid(UnaryFunction1D<unsigned int>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf1D_unsigned->operator()(*( ((BPy_Interface1D *) obj)->if1D )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf1D_unsigned->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return PyLong_FromLong( self->uf1D_unsigned->result ); + +} + +PyObject * UnaryFunction1DUnsigned_setIntegrationType(BPy_UnaryFunction1DUnsigned* self, PyObject *args) +{ + PyObject *obj; + + if( !PyArg_ParseTuple(args, "O!", &IntegrationType_Type, &obj) ) + return NULL; + + self->uf1D_unsigned->setIntegrationType( IntegrationType_from_BPy_IntegrationType(obj) ); + Py_RETURN_NONE; +} + +PyObject * UnaryFunction1DUnsigned_getIntegrationType(BPy_UnaryFunction1DUnsigned* self) { + return BPy_IntegrationType_from_IntegrationType( self->uf1D_unsigned->getIntegrationType() ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h new file mode 100644 index 00000000000..c70cc6257a7 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION1DUNSIGNED_H +#define FREESTYLE_PYTHON_UNARYFUNCTION1DUNSIGNED_H + +#include "../BPy_UnaryFunction1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction1DUnsigned_Type; + +#define BPy_UnaryFunction1DUnsigned_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction1DUnsigned_Type) ) + +/*---------------------------Python BPy_UnaryFunction1DUnsigned structure definition----------*/ +typedef struct { + BPy_UnaryFunction1D py_uf1D; + UnaryFunction1D<unsigned int> *uf1D_unsigned; +} BPy_UnaryFunction1DUnsigned; + +/*---------------------------Python BPy_UnaryFunction1DUnsigned visible prototypes-----------*/ +int UnaryFunction1DUnsigned_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION1DUNSIGNED_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp new file mode 100644 index 00000000000..b544530926f --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.cpp @@ -0,0 +1,184 @@ +#include "BPy_UnaryFunction1DVec2f.h" + +#include "../BPy_Convert.h" +#include "../BPy_Interface1D.h" +#include "../BPy_IntegrationType.h" + +#include "UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h" +#include "UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction1DVec2f instance -----------*/ +static int UnaryFunction1DVec2f___init__(BPy_UnaryFunction1DVec2f* self, PyObject *args); +static void UnaryFunction1DVec2f___dealloc__(BPy_UnaryFunction1DVec2f* self); +static PyObject * UnaryFunction1DVec2f___repr__(BPy_UnaryFunction1DVec2f* self); + +static PyObject * UnaryFunction1DVec2f_getName( BPy_UnaryFunction1DVec2f *self); +static PyObject * UnaryFunction1DVec2f___call__( BPy_UnaryFunction1DVec2f *self, PyObject *args, PyObject *kwds); +static PyObject * UnaryFunction1DVec2f_setIntegrationType(BPy_UnaryFunction1DVec2f* self, PyObject *args); +static PyObject * UnaryFunction1DVec2f_getIntegrationType(BPy_UnaryFunction1DVec2f* self); + +/*----------------------UnaryFunction1DVec2f instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction1DVec2f_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction1DVec2f_getName, METH_NOARGS, "() Returns the string of the name of the unary 1D function."}, + {"setIntegrationType", ( PyCFunction ) UnaryFunction1DVec2f_setIntegrationType, METH_VARARGS, "(IntegrationType i) Sets the integration method" }, + {"getIntegrationType", ( PyCFunction ) UnaryFunction1DVec2f_getIntegrationType, METH_NOARGS, "() Returns the integration method." }, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction1DVec2f type definition ------------------------------*/ + +PyTypeObject UnaryFunction1DVec2f_Type = { + PyObject_HEAD_INIT(NULL) + "UnaryFunction1DVec2f", /* tp_name */ + sizeof(BPy_UnaryFunction1DVec2f), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction1DVec2f___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction1DVec2f___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction1DVec2f___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction1DVec2f objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction1DVec2f_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction1DVec2f___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction1DVec2f_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction1DVec2f_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction1DVec2f_Type ); + PyModule_AddObject(module, "UnaryFunction1DVec2f", (PyObject *)&UnaryFunction1DVec2f_Type); + + if( PyType_Ready( &Normal2DF1D_Type ) < 0 ) + return -1; + Py_INCREF( &Normal2DF1D_Type ); + PyModule_AddObject(module, "Normal2DF1D", (PyObject *)&Normal2DF1D_Type); + + if( PyType_Ready( &Orientation2DF1D_Type ) < 0 ) + return -1; + Py_INCREF( &Orientation2DF1D_Type ); + PyModule_AddObject(module, "Orientation2DF1D", (PyObject *)&Orientation2DF1D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction1DVec2f___init__(BPy_UnaryFunction1DVec2f* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + if( !obj ) + self->uf1D_vec2f = new UnaryFunction1D<Vec2f>(); + else { + self->uf1D_vec2f = new UnaryFunction1D<Vec2f>( IntegrationType_from_BPy_IntegrationType(obj) ); + } + + self->uf1D_vec2f->py_uf1D = (PyObject *)self; + + return 0; +} +void UnaryFunction1DVec2f___dealloc__(BPy_UnaryFunction1DVec2f* self) +{ + if (self->uf1D_vec2f) + delete self->uf1D_vec2f; + UnaryFunction1D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction1DVec2f___repr__(BPy_UnaryFunction1DVec2f* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf1D_vec2f->getName().c_str(), self->uf1D_vec2f ); +} + +PyObject * UnaryFunction1DVec2f_getName( BPy_UnaryFunction1DVec2f *self ) +{ + return PyUnicode_FromFormat( self->uf1D_vec2f->getName().c_str() ); +} + +PyObject * UnaryFunction1DVec2f___call__( BPy_UnaryFunction1DVec2f *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!", &Interface1D_Type, &obj) ) + return NULL; + + if( typeid(*(self->uf1D_vec2f)) == typeid(UnaryFunction1D<Vec2f>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf1D_vec2f->operator()(*( ((BPy_Interface1D *) obj)->if1D )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf1D_vec2f->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return Vector_from_Vec2f( self->uf1D_vec2f->result ); + +} + +PyObject * UnaryFunction1DVec2f_setIntegrationType(BPy_UnaryFunction1DVec2f* self, PyObject *args) +{ + PyObject *obj; + + if( !PyArg_ParseTuple(args, "O!", &IntegrationType_Type, &obj) ) + return NULL; + + self->uf1D_vec2f->setIntegrationType( IntegrationType_from_BPy_IntegrationType(obj) ); + Py_RETURN_NONE; +} + +PyObject * UnaryFunction1DVec2f_getIntegrationType(BPy_UnaryFunction1DVec2f* self) { + return BPy_IntegrationType_from_IntegrationType( self->uf1D_vec2f->getIntegrationType() ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h new file mode 100644 index 00000000000..64a616e211a --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec2f.h @@ -0,0 +1,37 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION1DVEC2F_H +#define FREESTYLE_PYTHON_UNARYFUNCTION1DVEC2F_H + +#include "../BPy_UnaryFunction1D.h" + +#include "../../geometry/Geom.h" +using namespace Geometry; + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction1DVec2f_Type; + +#define BPy_UnaryFunction1DVec2f_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction1DVec2f_Type) ) + +/*---------------------------Python BPy_UnaryFunction1DVec2f structure definition----------*/ +typedef struct { + BPy_UnaryFunction1D py_uf1D; + UnaryFunction1D<Vec2f> *uf1D_vec2f; +} BPy_UnaryFunction1DVec2f; + +/*---------------------------Python BPy_UnaryFunction1DVec2f visible prototypes-----------*/ +int UnaryFunction1DVec2f_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION1DVEC2F_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp new file mode 100644 index 00000000000..5b7e854e921 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.cpp @@ -0,0 +1,178 @@ +#include "BPy_UnaryFunction1DVec3f.h" + +#include "../BPy_Convert.h" +#include "../BPy_Interface1D.h" +#include "../BPy_IntegrationType.h" + +#include "UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction1DVec3f instance -----------*/ +static int UnaryFunction1DVec3f___init__(BPy_UnaryFunction1DVec3f* self, PyObject *args); +static void UnaryFunction1DVec3f___dealloc__(BPy_UnaryFunction1DVec3f* self); +static PyObject * UnaryFunction1DVec3f___repr__(BPy_UnaryFunction1DVec3f* self); + +static PyObject * UnaryFunction1DVec3f_getName( BPy_UnaryFunction1DVec3f *self); +static PyObject * UnaryFunction1DVec3f___call__( BPy_UnaryFunction1DVec3f *self, PyObject *args, PyObject *kwds); +static PyObject * UnaryFunction1DVec3f_setIntegrationType(BPy_UnaryFunction1DVec3f* self, PyObject *args); +static PyObject * UnaryFunction1DVec3f_getIntegrationType(BPy_UnaryFunction1DVec3f* self); + +/*----------------------UnaryFunction1DVec3f instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction1DVec3f_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction1DVec3f_getName, METH_NOARGS, "() Returns the string of the name of the unary 1D function."}, + {"setIntegrationType", ( PyCFunction ) UnaryFunction1DVec3f_setIntegrationType, METH_VARARGS, "(IntegrationType i) Sets the integration method" }, + {"getIntegrationType", ( PyCFunction ) UnaryFunction1DVec3f_getIntegrationType, METH_NOARGS, "() Returns the integration method." }, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction1DVec3f type definition ------------------------------*/ + +PyTypeObject UnaryFunction1DVec3f_Type = { + PyObject_HEAD_INIT(NULL) + "UnaryFunction1DVec3f", /* tp_name */ + sizeof(BPy_UnaryFunction1DVec3f), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction1DVec3f___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction1DVec3f___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction1DVec3f___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction1DVec3f objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction1DVec3f_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction1DVec3f___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction1DVec3f_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction1DVec3f_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction1DVec3f_Type ); + PyModule_AddObject(module, "UnaryFunction1DVec3f", (PyObject *)&UnaryFunction1DVec3f_Type); + + if( PyType_Ready( &Orientation3DF1D_Type ) < 0 ) + return -1; + Py_INCREF( &Orientation3DF1D_Type ); + PyModule_AddObject(module, "Orientation3DF1D", (PyObject *)&Orientation3DF1D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction1DVec3f___init__(BPy_UnaryFunction1DVec3f* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + if( !obj ) + self->uf1D_vec3f = new UnaryFunction1D<Vec3f>(); + else { + self->uf1D_vec3f = new UnaryFunction1D<Vec3f>( IntegrationType_from_BPy_IntegrationType(obj) ); + } + + self->uf1D_vec3f->py_uf1D = (PyObject *)self; + + return 0; +} +void UnaryFunction1DVec3f___dealloc__(BPy_UnaryFunction1DVec3f* self) +{ + if (self->uf1D_vec3f) + delete self->uf1D_vec3f; + UnaryFunction1D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction1DVec3f___repr__(BPy_UnaryFunction1DVec3f* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf1D_vec3f->getName().c_str(), self->uf1D_vec3f ); +} + +PyObject * UnaryFunction1DVec3f_getName( BPy_UnaryFunction1DVec3f *self ) +{ + return PyUnicode_FromFormat( self->uf1D_vec3f->getName().c_str() ); +} + +PyObject * UnaryFunction1DVec3f___call__( BPy_UnaryFunction1DVec3f *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!", &Interface1D_Type, &obj) ) + return NULL; + + if( typeid(*(self->uf1D_vec3f)) == typeid(UnaryFunction1D<Vec3f>) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf1D_vec3f->operator()(*( ((BPy_Interface1D *) obj)->if1D )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf1D_vec3f->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + return Vector_from_Vec3f( self->uf1D_vec3f->result ); + +} + +PyObject * UnaryFunction1DVec3f_setIntegrationType(BPy_UnaryFunction1DVec3f* self, PyObject *args) +{ + PyObject *obj; + + if( !PyArg_ParseTuple(args, "O!", &IntegrationType_Type, &obj) ) + return NULL; + + self->uf1D_vec3f->setIntegrationType( IntegrationType_from_BPy_IntegrationType(obj) ); + Py_RETURN_NONE; +} + +PyObject * UnaryFunction1DVec3f_getIntegrationType(BPy_UnaryFunction1DVec3f* self) { + return BPy_IntegrationType_from_IntegrationType( self->uf1D_vec3f->getIntegrationType() ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h new file mode 100644 index 00000000000..7730271fc09 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVec3f.h @@ -0,0 +1,37 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION1DVEC3F_H +#define FREESTYLE_PYTHON_UNARYFUNCTION1DVEC3F_H + +#include "../BPy_UnaryFunction1D.h" + +#include "../../geometry/Geom.h" +using namespace Geometry; + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction1DVec3f_Type; + +#define BPy_UnaryFunction1DVec3f_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction1DVec3f_Type) ) + +/*---------------------------Python BPy_UnaryFunction1DVec3f structure definition----------*/ +typedef struct { + BPy_UnaryFunction1D py_uf1D; + UnaryFunction1D<Vec3f> *uf1D_vec3f; +} BPy_UnaryFunction1DVec3f; + +/*---------------------------Python BPy_UnaryFunction1DVec3f visible prototypes-----------*/ +int UnaryFunction1DVec3f_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION1DVEC3F_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp new file mode 100644 index 00000000000..4f5a5a731f9 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp @@ -0,0 +1,196 @@ +#include "BPy_UnaryFunction1DVectorViewShape.h" + +#include "../BPy_Convert.h" +#include "../BPy_Interface1D.h" +#include "../BPy_IntegrationType.h" + +#include "UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h" +#include "UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h" +#include "UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction1DVectorViewShape instance -----------*/ +static int UnaryFunction1DVectorViewShape___init__(BPy_UnaryFunction1DVectorViewShape* self, PyObject *args); +static void UnaryFunction1DVectorViewShape___dealloc__(BPy_UnaryFunction1DVectorViewShape* self); +static PyObject * UnaryFunction1DVectorViewShape___repr__(BPy_UnaryFunction1DVectorViewShape* self); + +static PyObject * UnaryFunction1DVectorViewShape_getName( BPy_UnaryFunction1DVectorViewShape *self); +static PyObject * UnaryFunction1DVectorViewShape___call__( BPy_UnaryFunction1DVectorViewShape *self, PyObject *args, PyObject *kwds); +static PyObject * UnaryFunction1DVectorViewShape_setIntegrationType(BPy_UnaryFunction1DVectorViewShape* self, PyObject *args); +static PyObject * UnaryFunction1DVectorViewShape_getIntegrationType(BPy_UnaryFunction1DVectorViewShape* self); + +/*----------------------UnaryFunction1DVectorViewShape instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction1DVectorViewShape_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction1DVectorViewShape_getName, METH_NOARGS, "() Returns the string of the name of the unary 1D function."}, + {"setIntegrationType", ( PyCFunction ) UnaryFunction1DVectorViewShape_setIntegrationType, METH_VARARGS, "(IntegrationType i) Sets the integration method" }, + {"getIntegrationType", ( PyCFunction ) UnaryFunction1DVectorViewShape_getIntegrationType, METH_NOARGS, "() Returns the integration method." }, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction1DVectorViewShape type definition ------------------------------*/ + +PyTypeObject UnaryFunction1DVectorViewShape_Type = { + PyObject_HEAD_INIT(NULL) + "UnaryFunction1DVectorViewShape", /* tp_name */ + sizeof(BPy_UnaryFunction1DVectorViewShape), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction1DVectorViewShape___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction1DVectorViewShape___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction1DVectorViewShape___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction1DVectorViewShape objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction1DVectorViewShape_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction1DVectorViewShape___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction1DVectorViewShape_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction1DVectorViewShape_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction1DVectorViewShape_Type ); + PyModule_AddObject(module, "UnaryFunction1DVectorViewShape", (PyObject *)&UnaryFunction1DVectorViewShape_Type); + + if( PyType_Ready( &GetOccludeeF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetOccludeeF1D_Type ); + PyModule_AddObject(module, "GetOccludeeF1D", (PyObject *)&GetOccludeeF1D_Type); + + if( PyType_Ready( &GetOccludersF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetOccludersF1D_Type ); + PyModule_AddObject(module, "GetOccludersF1D", (PyObject *)&GetOccludersF1D_Type); + + if( PyType_Ready( &GetShapeF1D_Type ) < 0 ) + return -1; + Py_INCREF( &GetShapeF1D_Type ); + PyModule_AddObject(module, "GetShapeF1D", (PyObject *)&GetShapeF1D_Type); + + return 0; +} + + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction1DVectorViewShape___init__(BPy_UnaryFunction1DVectorViewShape* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + if( !obj ) + self->uf1D_vectorviewshape = new UnaryFunction1D< std::vector<ViewShape*> >(); + else { + self->uf1D_vectorviewshape = new UnaryFunction1D< std::vector<ViewShape*> >( IntegrationType_from_BPy_IntegrationType(obj) ); + } + + self->uf1D_vectorviewshape->py_uf1D = (PyObject *)self; + + return 0; +} + +void UnaryFunction1DVectorViewShape___dealloc__(BPy_UnaryFunction1DVectorViewShape* self) +{ + if (self->uf1D_vectorviewshape) + delete self->uf1D_vectorviewshape; + UnaryFunction1D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction1DVectorViewShape___repr__(BPy_UnaryFunction1DVectorViewShape* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf1D_vectorviewshape->getName().c_str(), self->uf1D_vectorviewshape ); +} + +PyObject * UnaryFunction1DVectorViewShape_getName( BPy_UnaryFunction1DVectorViewShape *self ) +{ + return PyUnicode_FromFormat( self->uf1D_vectorviewshape->getName().c_str() ); +} + +PyObject * UnaryFunction1DVectorViewShape___call__( BPy_UnaryFunction1DVectorViewShape *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!", &Interface1D_Type, &obj) ) + return NULL; + + if( typeid(*(self->uf1D_vectorviewshape)) == typeid(UnaryFunction1D< std::vector<ViewShape*> >) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf1D_vectorviewshape->operator()(*( ((BPy_Interface1D *) obj)->if1D )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf1D_vectorviewshape->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + PyObject *list = PyList_New(0); + + for( unsigned int i = 0; i < self->uf1D_vectorviewshape->result.size(); i++) + PyList_Append(list, BPy_ViewShape_from_ViewShape(*( self->uf1D_vectorviewshape->result[i] )) ); + + return list; +} + +PyObject * UnaryFunction1DVectorViewShape_setIntegrationType(BPy_UnaryFunction1DVectorViewShape* self, PyObject *args) +{ + PyObject *obj; + + if( !PyArg_ParseTuple(args, "O!", &IntegrationType_Type, &obj) ) + return NULL; + + self->uf1D_vectorviewshape->setIntegrationType( IntegrationType_from_BPy_IntegrationType(obj) ); + Py_RETURN_NONE; +} + +PyObject * UnaryFunction1DVectorViewShape_getIntegrationType(BPy_UnaryFunction1DVectorViewShape* self) { + return BPy_IntegrationType_from_IntegrationType( self->uf1D_vectorviewshape->getIntegrationType() ); +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h new file mode 100644 index 00000000000..e2321a6107f --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h @@ -0,0 +1,37 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION1DVECTORVIEWSHAPE_H +#define FREESTYLE_PYTHON_UNARYFUNCTION1DVECTORVIEWSHAPE_H + +#include "../BPy_UnaryFunction1D.h" + +#include <vector> +#include "../../view_map/ViewMap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction1DVectorViewShape_Type; + +#define BPy_UnaryFunction1DVectorViewShape_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction1DVectorViewShape_Type) ) + +/*---------------------------Python BPy_UnaryFunction1DVectorViewShape structure definition----------*/ +typedef struct { + BPy_UnaryFunction1D py_uf1D; + UnaryFunction1D< std::vector<ViewShape*> > *uf1D_vectorviewshape; +} BPy_UnaryFunction1DVectorViewShape; + +/*---------------------------Python BPy_UnaryFunction1DVectorViewShape visible prototypes-----------*/ +int UnaryFunction1DVectorViewShape_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION1DVECTORVIEWSHAPE_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp new file mode 100644 index 00000000000..6c3f9df99af --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.cpp @@ -0,0 +1,193 @@ +#include "BPy_UnaryFunction1DVoid.h" + +#include "../BPy_Convert.h" +#include "../BPy_Interface1D.h" +#include "../BPy_IntegrationType.h" + +#include "UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h" +#include "UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h" +#include "UnaryFunction1D_void/BPy_TimeStampF1D.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for UnaryFunction1DVoid instance -----------*/ +static int UnaryFunction1DVoid___init__(BPy_UnaryFunction1DVoid* self, PyObject *args); +static void UnaryFunction1DVoid___dealloc__(BPy_UnaryFunction1DVoid* self); +static PyObject * UnaryFunction1DVoid___repr__(BPy_UnaryFunction1DVoid* self); + +static PyObject * UnaryFunction1DVoid_getName( BPy_UnaryFunction1DVoid *self); +static PyObject * UnaryFunction1DVoid___call__( BPy_UnaryFunction1DVoid *self, PyObject *args, PyObject *kwds); + +static PyObject * UnaryFunction1DVoid_setIntegrationType(BPy_UnaryFunction1DVoid* self, PyObject *args); +static PyObject * UnaryFunction1DVoid_getIntegrationType(BPy_UnaryFunction1DVoid* self); + +/*----------------------UnaryFunction1DVoid instance definitions ----------------------------*/ +static PyMethodDef BPy_UnaryFunction1DVoid_methods[] = { + {"getName", ( PyCFunction ) UnaryFunction1DVoid_getName, METH_NOARGS, "() Returns the string of the name of the unary 1D function."}, + {"setIntegrationType", ( PyCFunction ) UnaryFunction1DVoid_setIntegrationType, METH_VARARGS, "(IntegrationType i) Sets the integration method" }, + {"getIntegrationType", ( PyCFunction ) UnaryFunction1DVoid_getIntegrationType, METH_NOARGS, "() Returns the integration method." }, + {NULL, NULL, 0, NULL} +}; + +/*-----------------------BPy_UnaryFunction1DVoid type definition ------------------------------*/ + +PyTypeObject UnaryFunction1DVoid_Type = { + PyObject_HEAD_INIT(NULL) + "UnaryFunction1DVoid", /* tp_name */ + sizeof(BPy_UnaryFunction1DVoid), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)UnaryFunction1DVoid___dealloc__, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)UnaryFunction1DVoid___repr__, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (ternaryfunc)UnaryFunction1DVoid___call__, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "UnaryFunction1DVoid objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BPy_UnaryFunction1DVoid_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)UnaryFunction1DVoid___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//-------------------MODULE INITIALIZATION-------------------------------- + +int UnaryFunction1DVoid_Init( PyObject *module ) { + + if( module == NULL ) + return -1; + + if( PyType_Ready( &UnaryFunction1DVoid_Type ) < 0 ) + return -1; + Py_INCREF( &UnaryFunction1DVoid_Type ); + PyModule_AddObject(module, "UnaryFunction1DVoid", (PyObject *)&UnaryFunction1DVoid_Type); + + if( PyType_Ready( &ChainingTimeStampF1D_Type ) < 0 ) + return -1; + Py_INCREF( &ChainingTimeStampF1D_Type ); + PyModule_AddObject(module, "ChainingTimeStampF1D", (PyObject *)&ChainingTimeStampF1D_Type); + + if( PyType_Ready( &IncrementChainingTimeStampF1D_Type ) < 0 ) + return -1; + Py_INCREF( &IncrementChainingTimeStampF1D_Type ); + PyModule_AddObject(module, "IncrementChainingTimeStampF1D", (PyObject *)&IncrementChainingTimeStampF1D_Type); + + if( PyType_Ready( &TimeStampF1D_Type ) < 0 ) + return -1; + Py_INCREF( &TimeStampF1D_Type ); + PyModule_AddObject(module, "TimeStampF1D", (PyObject *)&TimeStampF1D_Type); + + return 0; +} + +//------------------------INSTANCE METHODS ---------------------------------- + +int UnaryFunction1DVoid___init__(BPy_UnaryFunction1DVoid* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + if( !obj ) + self->uf1D_void = new UnaryFunction1D_void(); + else { + self->uf1D_void = new UnaryFunction1D_void( IntegrationType_from_BPy_IntegrationType(obj) ); + } + + self->uf1D_void->py_uf1D = (PyObject *)self; + + return 0; +} + +void UnaryFunction1DVoid___dealloc__(BPy_UnaryFunction1DVoid* self) +{ + if (self->uf1D_void) + delete self->uf1D_void; + UnaryFunction1D_Type.tp_dealloc((PyObject*)self); +} + + +PyObject * UnaryFunction1DVoid___repr__(BPy_UnaryFunction1DVoid* self) +{ + return PyUnicode_FromFormat("type: %s - address: %p", self->uf1D_void->getName().c_str(), self->uf1D_void ); +} + +PyObject * UnaryFunction1DVoid_getName( BPy_UnaryFunction1DVoid *self ) +{ + return PyUnicode_FromFormat( self->uf1D_void->getName().c_str() ); +} + +PyObject * UnaryFunction1DVoid___call__( BPy_UnaryFunction1DVoid *self, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + + if( kwds != NULL ) { + PyErr_SetString(PyExc_TypeError, "keyword argument(s) not supported"); + return NULL; + } + if( !PyArg_ParseTuple(args, "O!", &Interface1D_Type, &obj) ) + return NULL; + + if( typeid(*(self->uf1D_void)) == typeid(UnaryFunction1D_void) ) { + PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden"); + return NULL; + } + if (self->uf1D_void->operator()(*( ((BPy_Interface1D *) obj)->if1D )) < 0) { + if (!PyErr_Occurred()) { + string msg(self->uf1D_void->getName() + " __call__ method failed"); + PyErr_SetString(PyExc_RuntimeError, msg.c_str()); + } + return NULL; + } + Py_RETURN_NONE; +} + +PyObject * UnaryFunction1DVoid_setIntegrationType(BPy_UnaryFunction1DVoid* self, PyObject *args) +{ + PyObject *obj; + + if( !PyArg_ParseTuple(args, "O!", &IntegrationType_Type, &obj) ) + return NULL; + + self->uf1D_void->setIntegrationType( IntegrationType_from_BPy_IntegrationType(obj) ); + Py_RETURN_NONE; +} + +PyObject * UnaryFunction1DVoid_getIntegrationType(BPy_UnaryFunction1DVoid* self) { + return BPy_IntegrationType_from_IntegrationType( self->uf1D_void->getIntegrationType() ); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h new file mode 100644 index 00000000000..af907aeec84 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVoid.h @@ -0,0 +1,34 @@ +#ifndef FREESTYLE_PYTHON_UNARYFUNCTION1DVOID_H +#define FREESTYLE_PYTHON_UNARYFUNCTION1DVOID_H + +#include "../BPy_UnaryFunction1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject UnaryFunction1DVoid_Type; + +#define BPy_UnaryFunction1DVoid_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &UnaryFunction1DVoid_Type) ) + +/*---------------------------Python BPy_UnaryFunction1DVoid structure definition----------*/ +typedef struct { + BPy_UnaryFunction1D py_uf1D; + UnaryFunction1D_void *uf1D_void; +} BPy_UnaryFunction1DVoid; + +/*---------------------------Python BPy_UnaryFunction1DVoid visible prototypes-----------*/ +int UnaryFunction1DVoid_Init( PyObject *module ); + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_UNARYFUNCTION1DVOID_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp new file mode 100644 index 00000000000..79dc076eed5 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp @@ -0,0 +1,77 @@ +#include "BPy_CurveNatureF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for CurveNatureF1D instance -----------*/ +static int CurveNatureF1D___init__( BPy_CurveNatureF1D* self, PyObject *args); + +/*-----------------------BPy_CurveNatureF1D type definition ------------------------------*/ + +PyTypeObject CurveNatureF1D_Type = { + PyObject_HEAD_INIT(NULL) + "CurveNatureF1D", /* tp_name */ + sizeof(BPy_CurveNatureF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "CurveNatureF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DEdgeNature_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)CurveNatureF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int CurveNatureF1D___init__( BPy_CurveNatureF1D* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_edgenature.uf1D_edgenature = new Functions1D::CurveNatureF1D(t); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h new file mode 100644 index 00000000000..852f8937954 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_CURVENATUREF1D_H +#define FREESTYLE_PYTHON_CURVENATUREF1D_H + +#include "../BPy_UnaryFunction1DEdgeNature.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject CurveNatureF1D_Type; + +#define BPy_CurveNatureF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &CurveNatureF1D_Type) ) + +/*---------------------------Python BPy_CurveNatureF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DEdgeNature py_uf1D_edgenature; +} BPy_CurveNatureF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CURVENATUREF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp new file mode 100644 index 00000000000..670d837cbd8 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp @@ -0,0 +1,77 @@ +#include "BPy_Normal2DF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Normal2DF1D instance -----------*/ +static int Normal2DF1D___init__( BPy_Normal2DF1D* self, PyObject *args); + +/*-----------------------BPy_Normal2DF1D type definition ------------------------------*/ + +PyTypeObject Normal2DF1D_Type = { + PyObject_HEAD_INIT(NULL) + "Normal2DF1D", /* tp_name */ + sizeof(BPy_Normal2DF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Normal2DF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DVec2f_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Normal2DF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int Normal2DF1D___init__( BPy_Normal2DF1D* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_vec2f.uf1D_vec2f = new Functions1D::Normal2DF1D(t); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h new file mode 100644 index 00000000000..32078558d0c --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_NORMAL2DF1D_H +#define FREESTYLE_PYTHON_NORMAL2DF1D_H + +#include "../BPy_UnaryFunction1DVec2f.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Normal2DF1D_Type; + +#define BPy_Normal2DF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Normal2DF1D_Type) ) + +/*---------------------------Python BPy_Normal2DF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DVec2f py_uf1D_vec2f; +} BPy_Normal2DF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_NORMAL2DF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp new file mode 100644 index 00000000000..6f205acaf0d --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp @@ -0,0 +1,79 @@ +#include "BPy_Orientation2DF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Orientation2DF1D instance -----------*/ + static int Orientation2DF1D___init__( BPy_Orientation2DF1D* self, PyObject *args); + +/*-----------------------BPy_Orientation2DF1D type definition ------------------------------*/ + +PyTypeObject Orientation2DF1D_Type = { + PyObject_HEAD_INIT(NULL) + "Orientation2DF1D", /* tp_name */ + sizeof(BPy_Orientation2DF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Orientation2DF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DVec2f_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Orientation2DF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int Orientation2DF1D___init__( BPy_Orientation2DF1D* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_vec2f.uf1D_vec2f = new Functions1D::Orientation2DF1D(t); + return 0; + +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h new file mode 100644 index 00000000000..189ab04db4f --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_ORIENTATION2DF1D_H +#define FREESTYLE_PYTHON_ORIENTATION2DF1D_H + +#include "../BPy_UnaryFunction1DVec2f.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Orientation2DF1D_Type; + +#define BPy_Orientation2DF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Orientation2DF1D_Type) ) + +/*---------------------------Python BPy_Orientation2DF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DVec2f py_uf1D_vec2f; +} BPy_Orientation2DF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_ORIENTATION2DF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp new file mode 100644 index 00000000000..5480d18931e --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp @@ -0,0 +1,77 @@ +#include "BPy_Orientation3DF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Orientation3DF1D instance -----------*/ +static int Orientation3DF1D___init__( BPy_Orientation3DF1D* self, PyObject *args); + +/*-----------------------BPy_Orientation3DF1D type definition ------------------------------*/ + +PyTypeObject Orientation3DF1D_Type = { + PyObject_HEAD_INIT(NULL) + "Orientation3DF1D", /* tp_name */ + sizeof(BPy_Orientation3DF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Orientation3DF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DVec3f_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Orientation3DF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int Orientation3DF1D___init__( BPy_Orientation3DF1D* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_vec3f.uf1D_vec3f = new Functions1D::Orientation3DF1D(t); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h new file mode 100644 index 00000000000..b69baf106f4 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_ORIENTATION3DF1D_H +#define FREESTYLE_PYTHON_ORIENTATION3DF1D_H + +#include "../BPy_UnaryFunction1DVec3f.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Orientation3DF1D_Type; + +#define BPy_Orientation3DF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Orientation3DF1D_Type) ) + +/*---------------------------Python BPy_Orientation3DF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DVec3f py_uf1D_vec3f; +} BPy_Orientation3DF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_ORIENTATION3DF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp new file mode 100644 index 00000000000..1a51e11631e --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp @@ -0,0 +1,77 @@ +#include "BPy_Curvature2DAngleF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for Curvature2DAngleF1D instance -----------*/ +static int Curvature2DAngleF1D___init__(BPy_Curvature2DAngleF1D* self, PyObject *args); + +/*-----------------------BPy_Curvature2DAngleF1D type definition ------------------------------*/ + +PyTypeObject Curvature2DAngleF1D_Type = { + PyObject_HEAD_INIT(NULL) + "Curvature2DAngleF1D", /* tp_name */ + sizeof(BPy_Curvature2DAngleF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "Curvature2DAngleF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Curvature2DAngleF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int Curvature2DAngleF1D___init__( BPy_Curvature2DAngleF1D* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::Curvature2DAngleF1D(t); + return 0; + +} +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h new file mode 100644 index 00000000000..1603a7dc4ea --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_CURVATURE2DANGLEF1D_H +#define FREESTYLE_PYTHON_CURVATURE2DANGLEF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject Curvature2DAngleF1D_Type; + +#define BPy_Curvature2DAngleF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &Curvature2DAngleF1D_Type) ) + +/*---------------------------Python BPy_Curvature2DAngleF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_Curvature2DAngleF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CURVATURE2DANGLEF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp new file mode 100644 index 00000000000..91276681224 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp @@ -0,0 +1,80 @@ +#include "BPy_DensityF1D.h" + +#include "../../../stroke/AdvancedFunctions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for DensityF1D instance -----------*/ +static int DensityF1D___init__(BPy_DensityF1D* self, PyObject *args); + +/*-----------------------BPy_DensityF1D type definition ------------------------------*/ + +PyTypeObject DensityF1D_Type = { + PyObject_HEAD_INIT(NULL) + "DensityF1D", /* tp_name */ + sizeof(BPy_DensityF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "DensityF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)DensityF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int DensityF1D___init__( BPy_DensityF1D* self, PyObject *args) +{ + PyObject *obj = 0; + double d = 2.0; + float f = 2.0; + + if( !PyArg_ParseTuple(args, "|dO!f", &d, &IntegrationType_Type, &obj, &f) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::DensityF1D(d,t,f); + return 0; + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h new file mode 100644 index 00000000000..36426536b36 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_DENSITYF1D_H +#define FREESTYLE_PYTHON_DENSITYF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject DensityF1D_Type; + +#define BPy_DensityF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &DensityF1D_Type) ) + +/*---------------------------Python BPy_DensityF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_DensityF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_DENSITYF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp new file mode 100644 index 00000000000..de175d19d61 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp @@ -0,0 +1,80 @@ +#include "BPy_GetCompleteViewMapDensityF1D.h" + +#include "../../../stroke/AdvancedFunctions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetCompleteViewMapDensityF1D instance -----------*/ +static int GetCompleteViewMapDensityF1D___init__(BPy_GetCompleteViewMapDensityF1D* self, PyObject *args); + +/*-----------------------BPy_GetCompleteViewMapDensityF1D type definition ------------------------------*/ + +PyTypeObject GetCompleteViewMapDensityF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetCompleteViewMapDensityF1D", /* tp_name */ + sizeof(BPy_GetCompleteViewMapDensityF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetCompleteViewMapDensityF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetCompleteViewMapDensityF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetCompleteViewMapDensityF1D___init__( BPy_GetCompleteViewMapDensityF1D* self, PyObject *args) +{ + PyObject *obj = 0; + unsigned i; + float f = 2.0; + + if( !PyArg_ParseTuple(args, "i|O!f", &i, &IntegrationType_Type, &obj, &f) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::GetCompleteViewMapDensityF1D(i,t,f); + return 0; + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h new file mode 100644 index 00000000000..5963b820348 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETCOMPLETEVIEWMAPDENSITYF1D_H +#define FREESTYLE_PYTHON_GETCOMPLETEVIEWMAPDENSITYF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetCompleteViewMapDensityF1D_Type; + +#define BPy_GetCompleteViewMapDensityF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetCompleteViewMapDensityF1D_Type) ) + +/*---------------------------Python BPy_GetCompleteViewMapDensityF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_GetCompleteViewMapDensityF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETCOMPLETEVIEWMAPDENSITYF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp new file mode 100644 index 00000000000..e28c582c0e1 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp @@ -0,0 +1,80 @@ +#include "BPy_GetDirectionalViewMapDensityF1D.h" + +#include "../../../stroke/AdvancedFunctions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetDirectionalViewMapDensityF1D instance -----------*/ +static int GetDirectionalViewMapDensityF1D___init__(BPy_GetDirectionalViewMapDensityF1D* self, PyObject *args); + +/*-----------------------BPy_GetDirectionalViewMapDensityF1D type definition ------------------------------*/ + +PyTypeObject GetDirectionalViewMapDensityF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetDirectionalViewMapDensityF1D", /* tp_name */ + sizeof(BPy_GetDirectionalViewMapDensityF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetDirectionalViewMapDensityF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetDirectionalViewMapDensityF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetDirectionalViewMapDensityF1D___init__( BPy_GetDirectionalViewMapDensityF1D* self, PyObject *args) +{ + PyObject *obj = 0; + unsigned int u1, u2; + float f = 2.0; + + if( !PyArg_ParseTuple(args, "II|O!f", &u1, &u2, &IntegrationType_Type, &obj, &f) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::GetDirectionalViewMapDensityF1D(u1, u2, t, f); + return 0; + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h new file mode 100644 index 00000000000..0e2d7ec2718 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETDIRECTIONALVIEWMAPDENSITYF1D_H +#define FREESTYLE_PYTHON_GETDIRECTIONALVIEWMAPDENSITYF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetDirectionalViewMapDensityF1D_Type; + +#define BPy_GetDirectionalViewMapDensityF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetDirectionalViewMapDensityF1D_Type) ) + +/*---------------------------Python BPy_GetDirectionalViewMapDensityF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_GetDirectionalViewMapDensityF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETDIRECTIONALVIEWMAPDENSITYF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp new file mode 100644 index 00000000000..d22185a92fe --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp @@ -0,0 +1,78 @@ +#include "BPy_GetProjectedXF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetProjectedXF1D instance -----------*/ +static int GetProjectedXF1D___init__(BPy_GetProjectedXF1D* self, PyObject *args ); + +/*-----------------------BPy_GetProjectedXF1D type definition ------------------------------*/ + +PyTypeObject GetProjectedXF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetProjectedXF1D", /* tp_name */ + sizeof(BPy_GetProjectedXF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetProjectedXF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetProjectedXF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetProjectedXF1D___init__( BPy_GetProjectedXF1D* self, PyObject *args ) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::GetProjectedXF1D(t); + return 0; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h new file mode 100644 index 00000000000..d799fb7b334 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETPROJECTEDXF1D_H +#define FREESTYLE_PYTHON_GETPROJECTEDXF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetProjectedXF1D_Type; + +#define BPy_GetProjectedXF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetProjectedXF1D_Type) ) + +/*---------------------------Python BPy_GetProjectedXF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_GetProjectedXF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETPROJECTEDXF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp new file mode 100644 index 00000000000..00e9e2eb108 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp @@ -0,0 +1,77 @@ +#include "BPy_GetProjectedYF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetProjectedYF1D instance -----------*/ + static int GetProjectedYF1D___init__(BPy_GetProjectedYF1D* self, PyObject *args ); + +/*-----------------------BPy_GetProjectedYF1D type definition ------------------------------*/ + +PyTypeObject GetProjectedYF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetProjectedYF1D", /* tp_name */ + sizeof(BPy_GetProjectedYF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetProjectedYF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetProjectedYF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetProjectedYF1D___init__( BPy_GetProjectedYF1D* self, PyObject *args ) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::GetProjectedYF1D(t); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h new file mode 100644 index 00000000000..1b7fe6c6b5f --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETPROJECTEDYF1D_H +#define FREESTYLE_PYTHON_GETPROJECTEDYF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetProjectedYF1D_Type; + +#define BPy_GetProjectedYF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetProjectedYF1D_Type) ) + +/*---------------------------Python BPy_GetProjectedYF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_GetProjectedYF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETPROJECTEDYF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp new file mode 100644 index 00000000000..3c761407cae --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp @@ -0,0 +1,77 @@ +#include "BPy_GetProjectedZF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetProjectedZF1D instance -----------*/ +static int GetProjectedZF1D___init__(BPy_GetProjectedZF1D* self, PyObject *args ); + +/*-----------------------BPy_GetProjectedZF1D type definition ------------------------------*/ + +PyTypeObject GetProjectedZF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetProjectedZF1D", /* tp_name */ + sizeof(BPy_GetProjectedZF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetProjectedZF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetProjectedZF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetProjectedZF1D___init__( BPy_GetProjectedZF1D* self, PyObject *args ) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::GetProjectedZF1D(t); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h new file mode 100644 index 00000000000..a87ac6f8c5e --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETPROJECTEDZF1D_H +#define FREESTYLE_PYTHON_GETPROJECTEDZF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetProjectedZF1D_Type; + +#define BPy_GetProjectedZF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetProjectedZF1D_Type) ) + +/*---------------------------Python BPy_GetProjectedZF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_GetProjectedZF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETPROJECTEDZF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp new file mode 100644 index 00000000000..61998767bfb --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp @@ -0,0 +1,80 @@ +#include "BPy_GetSteerableViewMapDensityF1D.h" + +#include "../../../stroke/AdvancedFunctions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetSteerableViewMapDensityF1D instance -----------*/ +static int GetSteerableViewMapDensityF1D___init__(BPy_GetSteerableViewMapDensityF1D* self, PyObject *args); + +/*-----------------------BPy_GetSteerableViewMapDensityF1D type definition ------------------------------*/ + +PyTypeObject GetSteerableViewMapDensityF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetSteerableViewMapDensityF1D", /* tp_name */ + sizeof(BPy_GetSteerableViewMapDensityF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetSteerableViewMapDensityF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetSteerableViewMapDensityF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetSteerableViewMapDensityF1D___init__( BPy_GetSteerableViewMapDensityF1D* self, PyObject *args) +{ + PyObject *obj = 0; + int i; + float f = 2.0; + + if( !PyArg_ParseTuple(args, "i|O!f", &i, &IntegrationType_Type, &obj, &f) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::GetSteerableViewMapDensityF1D(i,t,f); + return 0; + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h new file mode 100644 index 00000000000..29880c7e9a7 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_GETSTEERABLEVIEWMAPDENSITYF1D_H +#define FREESTYLE_PYTHON_GETSTEERABLEVIEWMAPDENSITYF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetSteerableViewMapDensityF1D_Type; + +#define BPy_GetSteerableViewMapDensityF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetSteerableViewMapDensityF1D_Type) ) +/*---------------------------Python BPy_GetSteerableViewMapDensityF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_GetSteerableViewMapDensityF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETSTEERABLEVIEWMAPDENSITYF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp new file mode 100644 index 00000000000..6f079b855ee --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp @@ -0,0 +1,80 @@ +#include "BPy_GetViewMapGradientNormF1D.h" + +#include "../../../stroke/AdvancedFunctions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetViewMapGradientNormF1D instance -----------*/ +static int GetViewMapGradientNormF1D___init__(BPy_GetViewMapGradientNormF1D* self, PyObject *args); + +/*-----------------------BPy_GetViewMapGradientNormF1D type definition ------------------------------*/ + +PyTypeObject GetViewMapGradientNormF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetViewMapGradientNormF1D", /* tp_name */ + sizeof(BPy_GetViewMapGradientNormF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetViewMapGradientNormF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetViewMapGradientNormF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetViewMapGradientNormF1D___init__( BPy_GetViewMapGradientNormF1D* self, PyObject *args) +{ + PyObject *obj = 0; + int i; + float f = 2.0; + + if( !PyArg_ParseTuple(args, "i|O!f", &i, &IntegrationType_Type, &obj, &f) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::GetViewMapGradientNormF1D(i,t,f); + return 0; + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h new file mode 100644 index 00000000000..4f07629870f --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF1D_H +#define FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetViewMapGradientNormF1D_Type; + +#define BPy_GetViewMapGradientNormF1D_Check(v) ( ((PyObject *) v)->ob_type == PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetViewMapGradientNormF1D_Type) ) + +/*---------------------------Python BPy_GetViewMapGradientNormF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_GetViewMapGradientNormF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETVIEWMAPGRADIENTNORMF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp new file mode 100644 index 00000000000..a08871e0559 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp @@ -0,0 +1,78 @@ +#include "BPy_GetXF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetXF1D instance -----------*/ +static int GetXF1D___init__(BPy_GetXF1D* self, PyObject *args ); + +/*-----------------------BPy_GetXF1D type definition ------------------------------*/ + +PyTypeObject GetXF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetXF1D", /* tp_name */ + sizeof(BPy_GetXF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetXF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetXF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetXF1D___init__( BPy_GetXF1D* self, PyObject *args ) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::GetXF1D(t); + return 0; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h new file mode 100644 index 00000000000..5eae107daae --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETXF1D_H +#define FREESTYLE_PYTHON_GETXF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetXF1D_Type; + +#define BPy_GetXF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetXF1D_Type) ) + +/*---------------------------Python BPy_GetXF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_GetXF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETXF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp new file mode 100644 index 00000000000..ebf7dc79add --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp @@ -0,0 +1,76 @@ +#include "BPy_GetYF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetYF1D instance -----------*/ +static int GetYF1D___init__(BPy_GetYF1D* self, PyObject *args ); + +/*-----------------------BPy_GetYF1D type definition ------------------------------*/ + +PyTypeObject GetYF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetYF1D", /* tp_name */ + sizeof(BPy_GetYF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetYF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetYF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetYF1D___init__( BPy_GetYF1D* self, PyObject *args ) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::GetYF1D(t); + return 0; +} +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h new file mode 100644 index 00000000000..5864c245776 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETYF1D_H +#define FREESTYLE_PYTHON_GETYF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetYF1D_Type; + +#define BPy_GetYF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetYF1D_Type) ) + +/*---------------------------Python BPy_GetYF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_GetYF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETYF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp new file mode 100644 index 00000000000..5b61d4931e0 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp @@ -0,0 +1,77 @@ +#include "BPy_GetZF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetZF1D instance -----------*/ +static int GetZF1D___init__(BPy_GetZF1D* self, PyObject *args ); + +/*-----------------------BPy_GetZF1D type definition ------------------------------*/ + +PyTypeObject GetZF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetZF1D", /* tp_name */ + sizeof(BPy_GetZF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetZF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetZF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetZF1D___init__( BPy_GetZF1D* self, PyObject *args ) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::GetZF1D(t); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h new file mode 100644 index 00000000000..4b91a567eef --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETZF1D_H +#define FREESTYLE_PYTHON_GETZF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetZF1D_Type; + +#define BPy_GetZF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetZF1D_Type) ) + +/*---------------------------Python BPy_GetZF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_GetZF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETZF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp new file mode 100644 index 00000000000..0743181d71c --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp @@ -0,0 +1,77 @@ +#include "BPy_LocalAverageDepthF1D.h" + +#include "../../../stroke/AdvancedFunctions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for LocalAverageDepthF1D instance -----------*/ +static int LocalAverageDepthF1D___init__(BPy_LocalAverageDepthF1D* self, PyObject *args); + +/*-----------------------BPy_LocalAverageDepthF1D type definition ------------------------------*/ + +PyTypeObject LocalAverageDepthF1D_Type = { + PyObject_HEAD_INIT(NULL) + "LocalAverageDepthF1D", /* tp_name */ + sizeof(BPy_LocalAverageDepthF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "LocalAverageDepthF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)LocalAverageDepthF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int LocalAverageDepthF1D___init__( BPy_LocalAverageDepthF1D* self, PyObject *args) +{ + PyObject *obj = 0; + double d; + + if( !PyArg_ParseTuple(args, "d|O!", &d, &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::LocalAverageDepthF1D(d,t); + return 0; +} +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h new file mode 100644 index 00000000000..627d10b6414 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF1D_H +#define FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject LocalAverageDepthF1D_Type; + +#define BPy_LocalAverageDepthF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &LocalAverageDepthF1D_Type) ) + +/*---------------------------Python BPy_LocalAverageDepthF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_LocalAverageDepthF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_LOCALAVERAGEDEPTHF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp new file mode 100644 index 00000000000..066589bd992 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp @@ -0,0 +1,78 @@ +#include "BPy_ZDiscontinuityF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ZDiscontinuityF1D instance -----------*/ +static int ZDiscontinuityF1D___init__(BPy_ZDiscontinuityF1D* self, PyObject *args ); + +/*-----------------------BPy_ZDiscontinuityF1D type definition ------------------------------*/ + +PyTypeObject ZDiscontinuityF1D_Type = { + PyObject_HEAD_INIT(NULL) + "ZDiscontinuityF1D", /* tp_name */ + sizeof(BPy_ZDiscontinuityF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ZDiscontinuityF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DDouble_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ZDiscontinuityF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ZDiscontinuityF1D___init__( BPy_ZDiscontinuityF1D* self, PyObject *args ) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_double.uf1D_double = new Functions1D::ZDiscontinuityF1D(t); + return 0; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h new file mode 100644 index 00000000000..e6b4be556d7 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_ZDISCONTINUITYF1D_H +#define FREESTYLE_PYTHON_ZDISCONTINUITYF1D_H + +#include "../BPy_UnaryFunction1DDouble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ZDiscontinuityF1D_Type; + +#define BPy_ZDiscontinuityF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ZDiscontinuityF1D_Type) ) + +/*---------------------------Python BPy_ZDiscontinuityF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DDouble py_uf1D_double; +} BPy_ZDiscontinuityF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_ZDISCONTINUITYF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp new file mode 100644 index 00000000000..fdfb875fd65 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp @@ -0,0 +1,78 @@ +#include "BPy_QuantitativeInvisibilityF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for QuantitativeInvisibilityF1D instance -----------*/ +static int QuantitativeInvisibilityF1D___init__(BPy_QuantitativeInvisibilityF1D* self, PyObject *args); + +/*-----------------------BPy_QuantitativeInvisibilityF1D type definition ------------------------------*/ + +PyTypeObject QuantitativeInvisibilityF1D_Type = { + PyObject_HEAD_INIT(NULL) + "QuantitativeInvisibilityF1D", /* tp_name */ + sizeof(BPy_QuantitativeInvisibilityF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "QuantitativeInvisibilityF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DUnsigned_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)QuantitativeInvisibilityF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int QuantitativeInvisibilityF1D___init__( BPy_QuantitativeInvisibilityF1D* self, PyObject *args) +{ + PyObject *obj = 0; + + if( !PyArg_ParseTuple(args, "|O!", &IntegrationType_Type, &obj) ) + return -1; + + IntegrationType t = ( obj ) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN; + self->py_uf1D_unsigned.uf1D_unsigned = new Functions1D::QuantitativeInvisibilityF1D(t); + return 0; + +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h new file mode 100644 index 00000000000..5bcf5fcc0a2 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF1D_H +#define FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF1D_H + +#include "../BPy_UnaryFunction1DUnsigned.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject QuantitativeInvisibilityF1D_Type; + +#define BPy_QuantitativeInvisibilityF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &QuantitativeInvisibilityF1D_Type) ) + +/*---------------------------Python BPy_QuantitativeInvisibilityF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DUnsigned py_uf1D_unsigned; +} BPy_QuantitativeInvisibilityF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp new file mode 100644 index 00000000000..7617593a600 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp @@ -0,0 +1,73 @@ +#include "BPy_GetOccludeeF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetOccludeeF1D instance -----------*/ +static int GetOccludeeF1D___init__(BPy_GetOccludeeF1D* self, PyObject *args); + +/*-----------------------BPy_GetOccludeeF1D type definition ------------------------------*/ + +PyTypeObject GetOccludeeF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetOccludeeF1D", /* tp_name */ + sizeof(BPy_GetOccludeeF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetOccludeeF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DVectorViewShape_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetOccludeeF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetOccludeeF1D___init__( BPy_GetOccludeeF1D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf1D_vectorviewshape.uf1D_vectorviewshape = new Functions1D::GetOccludeeF1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h new file mode 100644 index 00000000000..c8d5e99a6a7 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETOCCLUDEEF1D_H +#define FREESTYLE_PYTHON_GETOCCLUDEEF1D_H + +#include "../BPy_UnaryFunction1DVectorViewShape.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetOccludeeF1D_Type; + +#define BPy_GetOccludeeF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetOccludeeF1D_Type) ) + +/*---------------------------Python BPy_GetOccludeeF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DVectorViewShape py_uf1D_vectorviewshape; +} BPy_GetOccludeeF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETOCCLUDEEF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp new file mode 100644 index 00000000000..3442ec4988e --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp @@ -0,0 +1,73 @@ +#include "BPy_GetOccludersF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetOccludersF1D instance -----------*/ +static int GetOccludersF1D___init__(BPy_GetOccludersF1D* self, PyObject *args); + +/*-----------------------BPy_GetOccludersF1D type definition ------------------------------*/ + +PyTypeObject GetOccludersF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetOccludersF1D", /* tp_name */ + sizeof(BPy_GetOccludersF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetOccludersF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DVectorViewShape_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetOccludersF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetOccludersF1D___init__( BPy_GetOccludersF1D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf1D_vectorviewshape.uf1D_vectorviewshape = new Functions1D::GetOccludersF1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h new file mode 100644 index 00000000000..ad39ad25c3d --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETOCCLUDERSF1D_H +#define FREESTYLE_PYTHON_GETOCCLUDERSF1D_H + +#include "../BPy_UnaryFunction1DVectorViewShape.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetOccludersF1D_Type; + +#define BPy_GetOccludersF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetOccludersF1D_Type) ) + +/*---------------------------Python BPy_GetOccludersF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DVectorViewShape py_uf1D_vectorviewshape; +} BPy_GetOccludersF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETOCCLUDERSF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp new file mode 100644 index 00000000000..cb3d8694d86 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp @@ -0,0 +1,73 @@ +#include "BPy_GetShapeF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for GetShapeF1D instance -----------*/ +static int GetShapeF1D___init__(BPy_GetShapeF1D* self, PyObject *args); + +/*-----------------------BPy_GetShapeF1D type definition ------------------------------*/ + +PyTypeObject GetShapeF1D_Type = { + PyObject_HEAD_INIT(NULL) + "GetShapeF1D", /* tp_name */ + sizeof(BPy_GetShapeF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "GetShapeF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DVectorViewShape_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)GetShapeF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int GetShapeF1D___init__( BPy_GetShapeF1D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf1D_vectorviewshape.uf1D_vectorviewshape = new Functions1D::GetShapeF1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h new file mode 100644 index 00000000000..39d1268c03f --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_GETSHAPEF1D_H +#define FREESTYLE_PYTHON_GETSHAPEF1D_H + +#include "../BPy_UnaryFunction1DVectorViewShape.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject GetShapeF1D_Type; + +#define BPy_GetShapeF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &GetShapeF1D_Type) ) + +/*---------------------------Python BPy_GetShapeF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DVectorViewShape py_uf1D_vectorviewshape; +} BPy_GetShapeF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_GETSHAPEF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp new file mode 100644 index 00000000000..5767b5be3d6 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp @@ -0,0 +1,73 @@ +#include "BPy_ChainingTimeStampF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ChainingTimeStampF1D instance -----------*/ +static int ChainingTimeStampF1D___init__(BPy_ChainingTimeStampF1D* self, PyObject *args); + +/*-----------------------BPy_ChainingTimeStampF1D type definition ------------------------------*/ + +PyTypeObject ChainingTimeStampF1D_Type = { + PyObject_HEAD_INIT(NULL) + "ChainingTimeStampF1D", /* tp_name */ + sizeof(BPy_ChainingTimeStampF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ChainingTimeStampF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DVoid_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ChainingTimeStampF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ChainingTimeStampF1D___init__( BPy_ChainingTimeStampF1D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf1D_void.uf1D_void = new Functions1D::ChainingTimeStampF1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h new file mode 100644 index 00000000000..6855ddaf14b --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_CHAININGTIMESTAMPF1D_H +#define FREESTYLE_PYTHON_CHAININGTIMESTAMPF1D_H + +#include "../BPy_UnaryFunction1DVoid.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ChainingTimeStampF1D_Type; + +#define BPy_ChainingTimeStampF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ChainingTimeStampF1D_Type) ) + +/*---------------------------Python BPy_ChainingTimeStampF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DVoid py_uf1D_void; +} BPy_ChainingTimeStampF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CHAININGTIMESTAMPF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp new file mode 100644 index 00000000000..692f358b17e --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp @@ -0,0 +1,73 @@ +#include "BPy_IncrementChainingTimeStampF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for IncrementChainingTimeStampF1D instance -----------*/ +static int IncrementChainingTimeStampF1D___init__(BPy_IncrementChainingTimeStampF1D* self, PyObject *args); + +/*-----------------------BPy_IncrementChainingTimeStampF1D type definition ------------------------------*/ + +PyTypeObject IncrementChainingTimeStampF1D_Type = { + PyObject_HEAD_INIT(NULL) + "IncrementChainingTimeStampF1D", /* tp_name */ + sizeof(BPy_IncrementChainingTimeStampF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "IncrementChainingTimeStampF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DVoid_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)IncrementChainingTimeStampF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int IncrementChainingTimeStampF1D___init__( BPy_IncrementChainingTimeStampF1D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf1D_void.uf1D_void = new Functions1D::IncrementChainingTimeStampF1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h new file mode 100644 index 00000000000..a1d5714ab63 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_INCREMENTCHAININGTIMESTAMPF1D_H +#define FREESTYLE_PYTHON_INCREMENTCHAININGTIMESTAMPF1D_H + +#include "../BPy_UnaryFunction1DVoid.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject IncrementChainingTimeStampF1D_Type; + +#define BPy_IncrementChainingTimeStampF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &IncrementChainingTimeStampF1D_Type) ) + +/*---------------------------Python BPy_IncrementChainingTimeStampF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DVoid py_uf1D_void; +} BPy_IncrementChainingTimeStampF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_INCREMENTCHAININGTIMESTAMPF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp new file mode 100644 index 00000000000..8f5cf5c987d --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp @@ -0,0 +1,73 @@ +#include "BPy_TimeStampF1D.h" + +#include "../../../view_map/Functions1D.h" +#include "../../BPy_Convert.h" +#include "../../BPy_IntegrationType.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for TimeStampF1D instance -----------*/ +static int TimeStampF1D___init__(BPy_TimeStampF1D* self, PyObject *args); + +/*-----------------------BPy_TimeStampF1D type definition ------------------------------*/ + +PyTypeObject TimeStampF1D_Type = { + PyObject_HEAD_INIT(NULL) + "TimeStampF1D", /* tp_name */ + sizeof(BPy_TimeStampF1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "TimeStampF1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryFunction1DVoid_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)TimeStampF1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int TimeStampF1D___init__( BPy_TimeStampF1D* self, PyObject *args ) +{ + if( !PyArg_ParseTuple(args, "") ) + return -1; + self->py_uf1D_void.uf1D_void = new Functions1D::TimeStampF1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h new file mode 100644 index 00000000000..d9bee247c09 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.h @@ -0,0 +1,30 @@ +#ifndef FREESTYLE_PYTHON_TIMESTAMPF1D_H +#define FREESTYLE_PYTHON_TIMESTAMPF1D_H + +#include "../BPy_UnaryFunction1DVoid.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject TimeStampF1D_Type; + +#define BPy_TimeStampF1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &TimeStampF1D_Type) ) + +/*---------------------------Python BPy_TimeStampF1D structure definition----------*/ +typedef struct { + BPy_UnaryFunction1DVoid py_uf1D_void; +} BPy_TimeStampF1D; + + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CHAININGTIMESTAMPF1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp new file mode 100644 index 00000000000..789999c00f6 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp @@ -0,0 +1,70 @@ +#include "BPy_FalseUP0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for FalseUP0D instance -----------*/ + +static int FalseUP0D___init__(BPy_FalseUP0D* self, PyObject *args); + +/*-----------------------BPy_FalseUP0D type definition ------------------------------*/ + +PyTypeObject FalseUP0D_Type = { + PyObject_HEAD_INIT(NULL) + "FalseUP0D", /* tp_name */ + sizeof(BPy_FalseUP0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "FalseUP0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FalseUP0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int FalseUP0D___init__( BPy_FalseUP0D* self, PyObject *args) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_up0D.up0D = new Predicates0D::FalseUP0D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h new file mode 100644 index 00000000000..399941d442d --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_FALSEUP0D_H +#define FREESTYLE_PYTHON_FALSEUP0D_H + +#include "../BPy_UnaryPredicate0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject FalseUP0D_Type; + +#define BPy_FalseUP0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &FalseUP0D_Type) ) + +/*---------------------------Python BPy_FalseUP0D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate0D py_up0D; +} BPy_FalseUP0D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_FALSEUP0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp new file mode 100644 index 00000000000..47b9ce02d8a --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp @@ -0,0 +1,69 @@ +#include "BPy_TrueUP0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for TrueUP0D instance -----------*/ +static int TrueUP0D___init__(BPy_TrueUP0D* self, PyObject *args); + +/*-----------------------BPy_TrueUP0D type definition ------------------------------*/ + +PyTypeObject TrueUP0D_Type = { + PyObject_HEAD_INIT(NULL) + "TrueUP0D", /* tp_name */ + sizeof(BPy_TrueUP0D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "TrueUP0D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate0D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)TrueUP0D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int TrueUP0D___init__( BPy_TrueUP0D* self, PyObject *args ) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_up0D.up0D = new Predicates0D::TrueUP0D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h new file mode 100644 index 00000000000..24976aaa5c9 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_TRUEUP0D_H +#define FREESTYLE_PYTHON_TRUEUP0D_H + +#include "../BPy_UnaryPredicate0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject TrueUP0D_Type; + +#define BPy_TrueUP0D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &TrueUP0D_Type) ) + +/*---------------------------Python BPy_TrueUP0D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate0D py_up0D; +} BPy_TrueUP0D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_TRUEUP0D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp new file mode 100644 index 00000000000..7cd39d86f28 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp @@ -0,0 +1,69 @@ +#include "BPy_ContourUP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ContourUP1D instance -----------*/ +static int ContourUP1D___init__(BPy_ContourUP1D* self, PyObject *args); + +/*-----------------------BPy_ContourUP1D type definition ------------------------------*/ + +PyTypeObject ContourUP1D_Type = { + PyObject_HEAD_INIT(NULL) + "ContourUP1D", /* tp_name */ + sizeof(BPy_ContourUP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ContourUP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ContourUP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ContourUP1D___init__( BPy_ContourUP1D* self, PyObject *args ) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_up1D.up1D = new Predicates1D::ContourUP1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h new file mode 100644 index 00000000000..a24261a60de --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_CONTOURUP1D_H +#define FREESTYLE_PYTHON_CONTOURUP1D_H + +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ContourUP1D_Type; + +#define BPy_ContourUP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ContourUP1D_Type) ) + +/*---------------------------Python BPy_ContourUP1D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate1D py_up1D; +} BPy_ContourUP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_CONTOURUP1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp new file mode 100644 index 00000000000..9230cdb93f0 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp @@ -0,0 +1,74 @@ +#include "BPy_DensityLowerThanUP1D.h" + +#include "../../stroke/AdvancedPredicates1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for DensityLowerThanUP1D instance -----------*/ +static int DensityLowerThanUP1D___init__(BPy_DensityLowerThanUP1D* self, PyObject *args); + +/*-----------------------BPy_DensityLowerThanUP1D type definition ------------------------------*/ + +PyTypeObject DensityLowerThanUP1D_Type = { + PyObject_HEAD_INIT(NULL) + "DensityLowerThanUP1D", /* tp_name */ + sizeof(BPy_DensityLowerThanUP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "DensityLowerThanUP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)DensityLowerThanUP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int DensityLowerThanUP1D___init__( BPy_DensityLowerThanUP1D* self, PyObject *args ) +{ + double d1, d2 = 2.0; + + if( !PyArg_ParseTuple(args, "d|d", &d1, &d2) ) + return -1; + + self->py_up1D.up1D = new Predicates1D::DensityLowerThanUP1D(d1,d2); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h new file mode 100644 index 00000000000..2862b060a0a --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_DENSITYLOWERTHANUP1D_H +#define FREESTYLE_PYTHON_DENSITYLOWERTHANUP1D_H + +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject DensityLowerThanUP1D_Type; + +#define BPy_DensityLowerThanUP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &DensityLowerThanUP1D_Type) ) + +/*---------------------------Python BPy_DensityLowerThanUP1D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate1D py_up1D; +} BPy_DensityLowerThanUP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_DENSITYLOWERTHANUP1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp new file mode 100644 index 00000000000..6d340c8ab8e --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp @@ -0,0 +1,72 @@ +#include "BPy_EqualToChainingTimeStampUP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for EqualToChainingTimeStampUP1D instance -----------*/ +static int EqualToChainingTimeStampUP1D___init__(BPy_EqualToChainingTimeStampUP1D* self, PyObject *args ); + +/*-----------------------BPy_EqualToChainingTimeStampUP1D type definition ------------------------------*/ + +PyTypeObject EqualToChainingTimeStampUP1D_Type = { + PyObject_HEAD_INIT(NULL) + "EqualToChainingTimeStampUP1D", /* tp_name */ + sizeof(BPy_EqualToChainingTimeStampUP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "EqualToChainingTimeStampUP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)EqualToChainingTimeStampUP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int EqualToChainingTimeStampUP1D___init__( BPy_EqualToChainingTimeStampUP1D* self, PyObject *args ) +{ + unsigned u; + + if( !PyArg_ParseTuple(args, "I", &u) ) + return -1; + + self->py_up1D.up1D = new Predicates1D::EqualToChainingTimeStampUP1D(u); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h new file mode 100644 index 00000000000..39423423b8e --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_EQUALTOCHAININGTIMESTAMPUP1D_H +#define FREESTYLE_PYTHON_EQUALTOCHAININGTIMESTAMPUP1D_H + +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject EqualToChainingTimeStampUP1D_Type; + +#define BPy_EqualToChainingTimeStampUP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &EqualToChainingTimeStampUP1D_Type) ) + +/*---------------------------Python BPy_EqualToChainingTimeStampUP1D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate1D py_up1D; +} BPy_EqualToChainingTimeStampUP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_EQUALTOCHAININGTIMESTAMPUP1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp new file mode 100644 index 00000000000..ea38fe6fdc0 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp @@ -0,0 +1,72 @@ +#include "BPy_EqualToTimeStampUP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for EqualToTimeStampUP1D instance -----------*/ +static int EqualToTimeStampUP1D___init__(BPy_EqualToTimeStampUP1D* self, PyObject *args ); + +/*-----------------------BPy_EqualToTimeStampUP1D type definition ------------------------------*/ + +PyTypeObject EqualToTimeStampUP1D_Type = { + PyObject_HEAD_INIT(NULL) + "EqualToTimeStampUP1D", /* tp_name */ + sizeof(BPy_EqualToTimeStampUP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "EqualToTimeStampUP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)EqualToTimeStampUP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int EqualToTimeStampUP1D___init__( BPy_EqualToTimeStampUP1D* self, PyObject *args ) +{ + unsigned u; + + if( !PyArg_ParseTuple(args, "I", &u) ) + return -1; + + self->py_up1D.up1D = new Predicates1D::EqualToTimeStampUP1D(u); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h new file mode 100644 index 00000000000..538dc400dc2 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_EQUALTOTIMESTAMPUP1D_H +#define FREESTYLE_PYTHON_EQUALTOTIMESTAMPUP1D_H + +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject EqualToTimeStampUP1D_Type; + +#define BPy_EqualToTimeStampUP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &EqualToTimeStampUP1D_Type) ) + +/*---------------------------Python BPy_EqualToTimeStampUP1D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate1D py_up1D; +} BPy_EqualToTimeStampUP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_EQUALTOTIMESTAMPUP1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp new file mode 100644 index 00000000000..e4e94c68291 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp @@ -0,0 +1,69 @@ +#include "BPy_ExternalContourUP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ExternalContourUP1D instance -----------*/ +static int ExternalContourUP1D___init__(BPy_ExternalContourUP1D* self, PyObject *args); + +/*-----------------------BPy_ExternalContourUP1D type definition ------------------------------*/ + +PyTypeObject ExternalContourUP1D_Type = { + PyObject_HEAD_INIT(NULL) + "ExternalContourUP1D", /* tp_name */ + sizeof(BPy_ExternalContourUP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ExternalContourUP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ExternalContourUP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ExternalContourUP1D___init__( BPy_ExternalContourUP1D* self, PyObject *args ) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_up1D.up1D = new Predicates1D::ExternalContourUP1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h new file mode 100644 index 00000000000..31300f04dfe --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_EXTERNALCONTOURUP1D_H +#define FREESTYLE_PYTHON_EXTERNALCONTOURUP1D_H + +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ExternalContourUP1D_Type; + +#define BPy_ExternalContourUP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ExternalContourUP1D_Type) ) + +/*---------------------------Python BPy_ExternalContourUP1D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate1D py_up1D; +} BPy_ExternalContourUP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_EXTERNALCONTOURUP1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp new file mode 100644 index 00000000000..79b3a0a96a2 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp @@ -0,0 +1,69 @@ +#include "BPy_FalseUP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for FalseUP1D instance -----------*/ +static int FalseUP1D___init__(BPy_FalseUP1D* self, PyObject *args); + +/*-----------------------BPy_FalseUP1D type definition ------------------------------*/ + +PyTypeObject FalseUP1D_Type = { + PyObject_HEAD_INIT(NULL) + "FalseUP1D", /* tp_name */ + sizeof(BPy_FalseUP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "FalseUP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FalseUP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int FalseUP1D___init__( BPy_FalseUP1D* self, PyObject *args ) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_up1D.up1D = new Predicates1D::FalseUP1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h new file mode 100644 index 00000000000..273e4962db9 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_FALSEUP1D_H +#define FREESTYLE_PYTHON_FALSEUP1D_H + +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject FalseUP1D_Type; + +#define BPy_FalseUP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &FalseUP1D_Type) ) + +/*---------------------------Python BPy_FalseUP1D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate1D py_up1D; +} BPy_FalseUP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_FALSEUP1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp new file mode 100644 index 00000000000..926010f4a21 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp @@ -0,0 +1,72 @@ +#include "BPy_QuantitativeInvisibilityUP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for QuantitativeInvisibilityUP1D instance -----------*/ +static int QuantitativeInvisibilityUP1D___init__(BPy_QuantitativeInvisibilityUP1D* self, PyObject *args ); + +/*-----------------------BPy_QuantitativeInvisibilityUP1D type definition ------------------------------*/ + +PyTypeObject QuantitativeInvisibilityUP1D_Type = { + PyObject_HEAD_INIT(NULL) + "QuantitativeInvisibilityUP1D", /* tp_name */ + sizeof(BPy_QuantitativeInvisibilityUP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "QuantitativeInvisibilityUP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)QuantitativeInvisibilityUP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int QuantitativeInvisibilityUP1D___init__( BPy_QuantitativeInvisibilityUP1D* self, PyObject *args ) +{ + int i = 0; + + if( !PyArg_ParseTuple(args, "|i", &i) ) + return -1; + + self->py_up1D.up1D = new Predicates1D::QuantitativeInvisibilityUP1D(i); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h new file mode 100644 index 00000000000..f120ecb9778 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYUP1D_H +#define FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYUP1D_H + +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject QuantitativeInvisibilityUP1D_Type; + +#define BPy_QuantitativeInvisibilityUP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &QuantitativeInvisibilityUP1D_Type) ) + +/*---------------------------Python BPy_QuantitativeInvisibilityUP1D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate1D py_up1D; +} BPy_QuantitativeInvisibilityUP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_QUANTITATIVEINVISIBILITYUP1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp new file mode 100644 index 00000000000..105e1b75a0a --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp @@ -0,0 +1,72 @@ +#include "BPy_ShapeUP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for ShapeUP1D instance -----------*/ +static int ShapeUP1D___init__(BPy_ShapeUP1D* self, PyObject *args ); + +/*-----------------------BPy_ShapeUP1D type definition ------------------------------*/ + +PyTypeObject ShapeUP1D_Type = { + PyObject_HEAD_INIT(NULL) + "ShapeUP1D", /* tp_name */ + sizeof(BPy_ShapeUP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "ShapeUP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ShapeUP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int ShapeUP1D___init__( BPy_ShapeUP1D* self, PyObject *args ) +{ + unsigned u1, u2 = 0; + + if( !PyArg_ParseTuple(args, "I|I", &u1, &u2) ) + return -1; + + self->py_up1D.up1D = new Predicates1D::ShapeUP1D(u1,u2); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h new file mode 100644 index 00000000000..ce6d0276edd --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_SHAPEUP1D_H +#define FREESTYLE_PYTHON_SHAPEUP1D_H + +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject ShapeUP1D_Type; + +#define BPy_ShapeUP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &ShapeUP1D_Type) ) + +/*---------------------------Python BPy_ShapeUP1D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate1D py_up1D; +} BPy_ShapeUP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_SHAPEUP1D_H */ diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp new file mode 100644 index 00000000000..6f41e4927e5 --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp @@ -0,0 +1,69 @@ +#include "BPy_TrueUP1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +/*--------------- Python API function prototypes for TrueUP1D instance -----------*/ +static int TrueUP1D___init__(BPy_TrueUP1D* self, PyObject *args); + +/*-----------------------BPy_TrueUP1D type definition ------------------------------*/ + +PyTypeObject TrueUP1D_Type = { + PyObject_HEAD_INIT(NULL) + "TrueUP1D", /* tp_name */ + sizeof(BPy_TrueUP1D), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "TrueUP1D objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &UnaryPredicate1D_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)TrueUP1D___init__, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +//------------------------INSTANCE METHODS ---------------------------------- + +int TrueUP1D___init__( BPy_TrueUP1D* self, PyObject *args ) +{ + if(!( PyArg_ParseTuple(args, "") )) + return -1; + self->py_up1D.up1D = new Predicates1D::TrueUP1D(); + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h new file mode 100644 index 00000000000..5a01ad42d2a --- /dev/null +++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.h @@ -0,0 +1,29 @@ +#ifndef FREESTYLE_PYTHON_TRUEUP1D_H +#define FREESTYLE_PYTHON_TRUEUP1D_H + +#include "../BPy_UnaryPredicate1D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + +#include <Python.h> + +extern PyTypeObject TrueUP1D_Type; + +#define BPy_TrueUP1D_Check(v) ( PyObject_IsInstance( (PyObject *) v, (PyObject *) &TrueUP1D_Type) ) + +/*---------------------------Python BPy_TrueUP1D structure definition----------*/ +typedef struct { + BPy_UnaryPredicate1D py_up1D; +} BPy_TrueUP1D; + +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif /* FREESTYLE_PYTHON_TRUEUP1D_H */ diff --git a/source/blender/freestyle/intern/rendering/GLBBoxRenderer.cpp b/source/blender/freestyle/intern/rendering/GLBBoxRenderer.cpp new file mode 100755 index 00000000000..464779d6a43 --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLBBoxRenderer.cpp @@ -0,0 +1,108 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "GLBBoxRenderer.h" +#include "../scene_graph/IndexedFaceSet.h" +#include "../scene_graph/NodeDrawingStyle.h" +#include "../scene_graph/NodeShape.h" +#include "../scene_graph/NodeLight.h" +#include "../scene_graph/NodeTransform.h" + +#include "../scene_graph/Rep.h" +#include "../scene_graph/Node.h" + +void GLBBoxRenderer::visitIndexedFaceSet(IndexedFaceSet& iFaceSet) +{ + RenderRep(iFaceSet); +} + +void GLBBoxRenderer::visitNodeGroup(NodeGroup& iGroupNode) +{ + RenderNode(iGroupNode); +} + +void GLBBoxRenderer::visitNodeTransform(NodeTransform& iTransformNode) +{ + RenderNode(iTransformNode); +} + +void GLBBoxRenderer::visitDrawingStyle(DrawingStyle& iDrawingStyle) +{ + if(DrawingStyle::INVISIBLE == iDrawingStyle.style()) + return ; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_LINE_SMOOTH); + glPolygonMode(GL_FRONT, GL_LINE); + glLineWidth(1.f); + + glDisable(GL_LIGHTING); +} + +void GLBBoxRenderer::RenderRep(const Rep& iRep) const +{ + RenderBBox(iRep.bbox()); +} + +void GLBBoxRenderer::RenderNode(const Node& iNode) const +{ + RenderBBox(iNode.bbox()); +} + +void GLBBoxRenderer::RenderBBox(const BBox<Vec3r>& iBox) const +{ + if(iBox.empty()) + return; + + Vec3r m = iBox.getMin(); + Vec3r M = iBox.getMax(); + + glColor3f(0.f, 0.f, 0.f); + glBegin(GL_LINE_LOOP); + ((GLBBoxRenderer*)(this))->glVertex3r(m[0], m[1], m[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(M[0], m[1], m[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(M[0], M[1], m[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(m[0], M[1], m[2]); + glEnd(); + + glBegin(GL_LINE_LOOP); + ((GLBBoxRenderer*)(this))->glVertex3r(m[0], m[1], M[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(M[0], m[1], M[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(M[0], M[1], M[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(m[0], M[1], M[2]); + glEnd(); + + glBegin(GL_LINE_LOOP); + ((GLBBoxRenderer*)(this))->glVertex3r(m[0], m[1], m[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(m[0], m[1], M[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(m[0], M[1], M[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(m[0], M[1], m[2]); + glEnd(); + + glBegin(GL_LINE_LOOP); + ((GLBBoxRenderer*)(this))->glVertex3r(M[0], m[1], m[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(M[0], m[1], M[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(M[0], M[1], M[2]); + ((GLBBoxRenderer*)(this))->glVertex3r(M[0], M[1], m[2]); + glEnd(); + +} diff --git a/source/blender/freestyle/intern/rendering/GLBBoxRenderer.h b/source/blender/freestyle/intern/rendering/GLBBoxRenderer.h new file mode 100755 index 00000000000..4bb72ba80b0 --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLBBoxRenderer.h @@ -0,0 +1,59 @@ +// +// Filename : GLBBoxRenderer.h +// Author(s) : Stephane Grabli +// Purpose : Class to render BBoxes of a 3D scene thanks to OpenGL +// Date of creation : 07/02/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GLBBOXRENDERER_H +# define GLBBOXRENDERER_H + +# include "../system/FreestyleConfig.h" +# include "GLRenderer.h" +# include "../geometry/BBox.h" + +class Rep; +class Node; + +class LIB_RENDERING_EXPORT GLBBoxRenderer : public GLRenderer +{ +public: + + inline GLBBoxRenderer() : GLRenderer() {} + virtual ~GLBBoxRenderer() {} + + VISIT_DECL(NodeGroup) + VISIT_DECL(NodeTransform) + VISIT_DECL(IndexedFaceSet) + VISIT_DECL(DrawingStyle) + + protected: + + void RenderRep(const Rep& iRep) const ; + void RenderNode(const Node& iNode) const ; + void RenderBBox(const BBox<Vec3r>& iBox) const ; +}; + +#endif // GLBBOXRENDERER_H diff --git a/source/blender/freestyle/intern/rendering/GLBlendEquation.cpp b/source/blender/freestyle/intern/rendering/GLBlendEquation.cpp new file mode 100644 index 00000000000..2cbd003c58e --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLBlendEquation.cpp @@ -0,0 +1,9 @@ +#include "GLBlendEquation.h" + +void FRS_glBlendEquation(GLenum mode) { + if( glBlendEquation ) { + glBlendEquation(mode); + } else if ( glBlendEquationEXT ) { + glBlendEquationEXT(mode); + } +} diff --git a/source/blender/freestyle/intern/rendering/GLBlendEquation.h b/source/blender/freestyle/intern/rendering/GLBlendEquation.h new file mode 100644 index 00000000000..89a90837bea --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLBlendEquation.h @@ -0,0 +1,16 @@ +#ifndef GLBLENDEQUATION_H +#define GLBLENDEQUATION_H + +#include <GL/glew.h> +#ifdef WIN32 +# include <windows.h> +#endif +#ifdef __MACH__ +# include <OpenGL/gl.h> +#else +# include <GL/gl.h> +#endif + +void FRS_glBlendEquation(GLenum mode); + +#endif // GLBLENDEQUATION_H diff --git a/source/blender/freestyle/intern/rendering/GLDebugRenderer.cpp b/source/blender/freestyle/intern/rendering/GLDebugRenderer.cpp new file mode 100755 index 00000000000..b3b77bb3ed8 --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLDebugRenderer.cpp @@ -0,0 +1,201 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "../scene_graph/VertexRep.h" +#include "../scene_graph/NodeShape.h" +#include "../scene_graph/IndexedFaceSet.h" +#include "../scene_graph/LineRep.h" +#include "../geometry/Grid.h" + +#include "GLDebugRenderer.h" + +#ifdef __MACH__ +#include <GLUT/glut.h> +#else +# ifdef WIN32 +# include <GL/glu.h> +# else +# include <GL/glut.h> +# endif +#endif + +void GLDebugRenderer::visitIndexedFaceSet(IndexedFaceSet& iFaceSet) +{ + unsigned int fIndex = 0; + + const real * vertices = iFaceSet.vertices(); + const real * normals = iFaceSet.normals(); + const FrsMaterial *const* frs_materials = (const FrsMaterial**)iFaceSet.frs_materials(); + const unsigned *vindices = iFaceSet.vindices(); + const unsigned *nindices = iFaceSet.nindices(); + const unsigned *mindices = iFaceSet.mindices(); + const unsigned numfaces = iFaceSet.numFaces(); + const unsigned *numVertexPerFace = iFaceSet.numVertexPerFaces(); + const IndexedFaceSet::TRIANGLES_STYLE * faceStyle = iFaceSet.trianglesStyle(); + + const unsigned *pvi = vindices; + const unsigned *pni = nindices; + const unsigned* pmi = mindices; + + for(fIndex=0; fIndex<numfaces; fIndex++) + { + switch(faceStyle[fIndex]) + { + case IndexedFaceSet::TRIANGLE_STRIP: + RenderTriangleStrip(vertices, normals, frs_materials, pvi, pni, pmi, numVertexPerFace[fIndex]); + break; + case IndexedFaceSet::TRIANGLE_FAN: + RenderTriangleFan(vertices, normals, frs_materials, pvi, pni, pmi, numVertexPerFace[fIndex]); + break; + case IndexedFaceSet::TRIANGLES: + RenderTriangles(vertices, normals, frs_materials, pvi, pni, pmi, numVertexPerFace[fIndex]); + break; + } + pvi += numVertexPerFace[fIndex]; + pni += numVertexPerFace[fIndex]; + pmi += numVertexPerFace[fIndex]; + } +} + +void GLDebugRenderer::visitNodeShape(NodeShape& iShapeNode) +{ + // Gets the bbox size: + real minY = iShapeNode.bbox().getMin()[1]; + real maxY = iShapeNode.bbox().getMax()[1]; + + // sets the text size: + _bboxSize = fabs((maxY-minY)); ///1000.f; +} + +void GLDebugRenderer::visitLineRep(LineRep& iLine) +{ + + glColor3f(0,0,0); + + GLRenderer::visitLineRep(iLine); +} + +void GLDebugRenderer::visitOrientedLineRep(OrientedLineRep& iLine) +{ + GLRenderer::visitOrientedLineRep(iLine); +} + +void GLDebugRenderer::visitVertexRep(VertexRep& iVertex) +{ + glPointSize(3.0); + + GLRenderer::visitVertexRep(iVertex); +} + + +void GLDebugRenderer::renderBitmapString(real x, + real y, + real z, + void *font, + char *string, + float size) +{ + char *c; + + glPushMatrix(); + glTranslater(x, y,z); + real textSize = min(_bboxSize/10.0, _minEdgeSize/2.0); + // adjust the text size so as it + // is acceptable giving the bbox size: + while(_bboxSize/textSize>1000) + textSize *= 10.0; + + glScalef(size, size, size); + glScalef(textSize/200.0, textSize/200.0, textSize/200.0); + for (c=string; *c != '\0'; c++) + { + //soc glutStrokeCharacter(font, *c); + } + glPopMatrix(); +} + +void GLDebugRenderer::RenderTriangleStrip(const real *iVertices, + const real *iNormals, + const FrsMaterial *const* iMaterials, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned iNVertices) +{ + // glBegin(GL_TRIANGLE_STRIP); + // for(unsigned int i=0; i<iNVertices; i++) + // { + // glNormal3r(iNormals[iNIndices[i]], + // iNormals[iNIndices[i]+1], + // iNormals[iNIndices[i]+2]); + // + // glVertex3r( iVertices[iVIndices[i]], + // iVertices[iVIndices[i]+1], + // iVertices[iVIndices[i]+2]); + // } + // glEnd(); +} + +void GLDebugRenderer::RenderTriangleFan(const real *iVertices, + const real *iNormals, + const FrsMaterial *const* iMaterials, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned iNVertices) +{ + // glBegin(GL_TRIANGLE_FAN); + // for(unsigned int i=0; i<iNVertices; i++) + // { + // glNormal3r(iNormals[iNIndices[i]], + // iNormals[iNIndices[i]+1], + // iNormals[iNIndices[i]+2]); + // + // glVertex3r( iVertices[iVIndices[i]], + // iVertices[iVIndices[i]+1], + // iVertices[iVIndices[i]+2]); + // } + // glEnd(); +} + +void GLDebugRenderer::RenderTriangles(const real *iVertices, + const real *iNormals, + const FrsMaterial *const* iMaterials, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned iNVertices) +{ + // // Renders the normals: + // glBegin(GL_LINES); + // for(unsigned int i=0; i<iNVertices; i++) + // { + // glVertex3r( iVertices[iVIndices[i]], + // iVertices[iVIndices[i]+1], + // iVertices[iVIndices[i]+2]); + // + // glVertex3r(iVertices[iVIndices[i]] + iNormals[iNIndices[i]]/10.f, + // iVertices[iVIndices[i]+1] + iNormals[iNIndices[i]+1]/10.f, + // iVertices[iVIndices[i]+2] + iNormals[iNIndices[i]+2]/10.f); + // } + // glEnd(); +} diff --git a/source/blender/freestyle/intern/rendering/GLDebugRenderer.h b/source/blender/freestyle/intern/rendering/GLDebugRenderer.h new file mode 100755 index 00000000000..9111d5067bc --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLDebugRenderer.h @@ -0,0 +1,182 @@ +// +// Filename : GLDebugRenderer.h +// Author(s) : Stephane Grabli +// Purpose : Class to render the debug informations related to +// a scene +// Date of creation : 03/04/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GLDEBUGRENDERER_H +# define GLDEBUGRENDERER_H + +# include <float.h> +# include "../system/FreestyleConfig.h" +# include "GLRenderer.h" +# include "../view_map/Silhouette.h" +# include "../winged_edge/Curvature.h" + +class WSMeshShape; +class WSExactShape; + +class LIB_RENDERING_EXPORT GLDebugRenderer : public GLRenderer +{ +public: + + inline GLDebugRenderer() : GLRenderer() { + _bboxSize = 2.0; + setMaxValue(&_minEdgeSize); + _SelectedFEdge = 0; + } + + inline ~GLDebugRenderer() {} + + VISIT_DECL(NodeShape) + + VISIT_DECL(IndexedFaceSet) + VISIT_DECL(LineRep) + VISIT_DECL(OrientedLineRep) + VISIT_DECL(VertexRep) + + /*! Renders a bitmap string in world coordinates + * x, y, z + * The world coordinates of the sentence's starting point + * font + * The font used to display the text. + * Must be one of : + * - GLUT_STROKE_ROMAN + * - GLUT_STROKE_MONO_ROMAN + * string + * The text to display + * size + * The relative size of the text to display + */ + void renderBitmapString(real x, + real y, + real z, + void *font, + char *string, + float size = 1.f) ; + + /*! Reinitialize the Renderer so as the previous + * text size does not affect the current one. + * iBBoxSize + * The size of the scene bounding box. + */ + inline void ReInit(real iBBoxSize) {_bboxSize = iBBoxSize; setMaxValue(&_minEdgeSize);} + + inline void setSelectedFEdge(FEdge *iFEdge) {_SelectedFEdge = iFEdge;} + inline FEdge * selectedFEdge() {return _SelectedFEdge;} + +protected: + + /*! Renders a face made of a triangles strip + * iVertices + * Array of float containing the face vertices. 3 floats per + * x, y, z vertex coordinates + * iNormals + * Array of float containing the face normals. 3 floats per + * x, y, z vertex normal coordinates + * iVIndices + * Array of the indices (to use with the iVertices array) + * describing the vertices parsing order + * iNIndices + * Array of normals indices (to use with iNormals array) + * describing the normals parsing order + * iNVertices + * The number of vertices in the face + */ + virtual void RenderTriangleStrip(const real *iVertices, + const real *iNormals, + const FrsMaterial *const* iMaterials, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned iNVertices); + + /*! Renders a face made of a triangles fan + * iVertices + * Array of float containing the face vertices. 3 floats per + * x, y, z vertex coordinates + * iNormals + * Array of float containing the face normals. 3 floats per + * x, y, z vertex normal coordinates + * iVIndices + * Array of the indices (to use with the iVertices array) + * describing the vertices parsing order + * iNIndices + * Array of normals indices (to use with iNormals array) + * describing the normals parsing order + * iNVertices + * The number of vertices in the face + */ + virtual void RenderTriangleFan(const real *iVertices, + const real *iNormals, + const FrsMaterial *const*iMaterials, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned iNVertices); + + /*! Renders a face made of single triangles + * iVertices + * Array of float containing the face vertices. 3 floats per + * x, y, z vertex coordinates + * iNormals + * Array of float containing the face normals. 3 floats per + * x, y, z vertex normal coordinates + * iVIndices + * Array of the indices (to use with the iVertices array) + * describing the vertices parsing order + * iNIndices + * Array of normals indices (to use with iNormals array) + * describing the normals parsing order + * iNVertices + * The number of vertices in the face + */ + virtual void RenderTriangles(const real *iVertices, + const real *iNormals, + const FrsMaterial *const* iMaterials, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned iNVertices); + + /*! glTranslatef or glTranslated */ + inline void glTranslater(float x, float y, float z) {glTranslatef(x,y,z);} + inline void glTranslater(real x, real y, real z) {glTranslated(x,y,z);} + + +private: + + inline void setMaxValue(float *oValue) {*oValue = FLT_MAX;} + inline void setMaxValue(real *oValue) {*oValue = DBL_MAX;} + + mutable real _bboxSize; + mutable real _minEdgeSize; + + FEdge *_SelectedFEdge; +}; + +#endif // GLDEBUGRENDERER_H diff --git a/source/blender/freestyle/intern/rendering/GLFreeMemoryVisitor.cpp b/source/blender/freestyle/intern/rendering/GLFreeMemoryVisitor.cpp new file mode 100644 index 00000000000..b5a835f5104 --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLFreeMemoryVisitor.cpp @@ -0,0 +1,27 @@ +#include "GLFreeMemoryVisitor.h" +#include "../scene_graph/IndexedFaceSet.h" + +# ifdef WIN32 +# include <windows.h> +# endif +# ifdef __MACH__ +# include <OpenGL/gl.h> +# else +# include <GL/gl.h> +# endif + +GLFreeMemoryVisitor::GLFreeMemoryVisitor() +:SceneVisitor(){ +} + +GLFreeMemoryVisitor::~GLFreeMemoryVisitor(){ +} + +void GLFreeMemoryVisitor::visitIndexedFaceSet(IndexedFaceSet& ifs){ + GLuint dl = ifs.displayList(); + if(dl != 0){ + if(glIsList(dl)){ + glDeleteLists(dl, 1); + } + } +} diff --git a/source/blender/freestyle/intern/rendering/GLFreeMemoryVisitor.h b/source/blender/freestyle/intern/rendering/GLFreeMemoryVisitor.h new file mode 100644 index 00000000000..2b9314f3701 --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLFreeMemoryVisitor.h @@ -0,0 +1,23 @@ +#ifndef GL_FREE_MEMORY_VISITOR_H_ +#define GL_FREE_MEMORY_VISITOR_H_ + +# include "../system/FreestyleConfig.h" +# include "../scene_graph/SceneVisitor.h" + +/*! Mainly used to delete display lists */ +class LIB_RENDERING_EXPORT GLFreeMemoryVisitor : public SceneVisitor +{ +public: + + GLFreeMemoryVisitor() ; + virtual ~GLFreeMemoryVisitor() ; + + // + // visitClass methods + // + ////////////////////////////////////////////// + + VISIT_DECL(IndexedFaceSet) +}; + +#endif // GL_FREE_MEMORY_H_ diff --git a/source/blender/freestyle/intern/rendering/GLMonoColorRenderer.cpp b/source/blender/freestyle/intern/rendering/GLMonoColorRenderer.cpp new file mode 100755 index 00000000000..ff893484fb5 --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLMonoColorRenderer.cpp @@ -0,0 +1,43 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "GLMonoColorRenderer.h" + +void GLMonoColorRenderer::visitFrsMaterial(FrsMaterial&) { + glColor3f(_r, _g, _b); +} + +void GLMonoColorRenderer::visitDrawingStyle(DrawingStyle&) { + glDisable(GL_LIGHTING); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_LINE_SMOOTH); + glLineWidth(3.0); + glPolygonMode(GL_BACK, GL_LINE); + //glPolygonMode(GL_BACK, GL_FILL); +} + +void GLMonoColorRenderer::setColor(float r, float g, float b, float alpha) { + _r = r; + _g = g; + _b = b; + _alpha = alpha; +} diff --git a/source/blender/freestyle/intern/rendering/GLMonoColorRenderer.h b/source/blender/freestyle/intern/rendering/GLMonoColorRenderer.h new file mode 100755 index 00000000000..9eb6c8134bb --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLMonoColorRenderer.h @@ -0,0 +1,60 @@ +// +// Filename : GLMonoColorRenderer.h +// Author(s) : Stephane Grabli +// Purpose : Class to render 3D scene in 2 colors thanks to OpenGL +// Date of creation : 07/02/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GLMONOCOLORRENDERER_H +# define GLMONOCOLORRENDERER_H + +# include "../system/FreestyleConfig.h" +# include "GLRenderer.h" + +class LIB_RENDERING_EXPORT GLMonoColorRenderer : public GLRenderer +{ + public: + + GLMonoColorRenderer() : GLRenderer() { + _r = _g = _b = 0.f; + _alpha = 1.f; + } + + virtual ~GLMonoColorRenderer() {} + + VISIT_DECL(DrawingStyle) + VISIT_DECL(FrsMaterial) + + void setColor(float r, float g, float b, float alpha = 1.f); + +private: + + float _r; + float _g; + float _b; + float _alpha; +}; + +#endif // GLMONOCOLORRENDERER_H diff --git a/source/blender/freestyle/intern/rendering/GLRenderer.cpp b/source/blender/freestyle/intern/rendering/GLRenderer.cpp new file mode 100755 index 00000000000..678256f72bf --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLRenderer.cpp @@ -0,0 +1,467 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "../scene_graph/IndexedFaceSet.h" +#include "../scene_graph/NodeDrawingStyle.h" +#include "../scene_graph/NodeLight.h" +#include "../scene_graph/NodeCamera.h" +#include "../scene_graph/NodeTransform.h" +#include "../scene_graph/NodeShape.h" +#include "../scene_graph/OrientedLineRep.h" +#include "../scene_graph/VertexRep.h" +#include "../stroke/Stroke.h" + +#include "../scene_graph/TriangleRep.h" + +#include "GLRenderer.h" + +static GLenum lights[8] = {GL_LIGHT0, + GL_LIGHT1, + GL_LIGHT2, + GL_LIGHT3, + GL_LIGHT4, + GL_LIGHT5, + GL_LIGHT6, + GL_LIGHT7}; + +void GLRenderer::visitIndexedFaceSet(IndexedFaceSet& ifs) +{ + /*GLuint dl = ifs.displayList(); + if(dl != 0){ + glCallList(dl); + return; + }*/ + unsigned int fIndex = 0; + + const real * vertices = ifs.vertices(); + const real * normals = ifs.normals(); + const real * texCoords = ifs.texCoords(); + const FrsMaterial *const* frs_materials = ifs.frs_materials(); + const unsigned *vindices = ifs.vindices(); + const unsigned *nindices = ifs.nindices(); + const unsigned *mindices = ifs.mindices(); + const unsigned *tindices = ifs.tindices(); + const unsigned numfaces = ifs.numFaces(); + const IndexedFaceSet::TRIANGLES_STYLE * faceStyle = ifs.trianglesStyle(); + const unsigned *numVertexPerFace = ifs.numVertexPerFaces(); + + + const unsigned* pvi = vindices; + const unsigned* pni = nindices; + const unsigned* pmi = mindices; + const unsigned* pti = tindices; + + //dl = glGenLists(1); + //glNewList(dl, GL_COMPILE_AND_EXECUTE); + for(fIndex=0; fIndex<numfaces; fIndex++) + { + switch(faceStyle[fIndex]) + { + case IndexedFaceSet::TRIANGLE_STRIP: + RenderTriangleStrip(vertices, normals, frs_materials, texCoords, pvi, pni, pmi, pti, numVertexPerFace[fIndex]); + break; + case IndexedFaceSet::TRIANGLE_FAN: + RenderTriangleFan(vertices, normals, frs_materials, texCoords, pvi, pni, pmi, pti, numVertexPerFace[fIndex]); + break; + case IndexedFaceSet::TRIANGLES: + RenderTriangles(vertices, normals, frs_materials, texCoords, pvi, pni, pmi, pti, numVertexPerFace[fIndex]); + break; + } + pvi += numVertexPerFace[fIndex]; + pni += numVertexPerFace[fIndex]; + if(pmi) + pmi += numVertexPerFace[fIndex]; + if(pti) + pti += numVertexPerFace[fIndex]; + } + //glEndList(); + //ifs.setDisplayList(dl); +} + +void GLRenderer::visitNodeTransform(NodeTransform& tn) { + if(tn.scaled()) + glEnable(GL_NORMALIZE); +} + +void GLRenderer::visitNodeTransformBefore(NodeTransform& tn) { + glPushMatrix(); + + // Now apply transform + applyTransform(tn.matrix()); +} + +void GLRenderer::visitNodeTransformAfter(NodeTransform& tn) { + glPopMatrix(); +} + +void GLRenderer::visitNodeLight(NodeLight& ln) +{ + if(true != ln.isOn()) + return; + + int number = ln.number(); + + glLightfv(lights[number], GL_AMBIENT, ln.ambient()); + glLightfv(lights[number], GL_DIFFUSE, ln.diffuse()); + glLightfv(lights[number], GL_SPECULAR, ln.specular()); + glLightfv(lights[number], GL_POSITION, ln.position()); + + glEnable(lights[number]); +} + +void GLRenderer::visitNodeCamera(NodeCamera& cn) +{ + const double * mvm = cn.modelViewMatrix(); + const double * pm = cn.projectionMatrix(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMultMatrixd(pm); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMultMatrixd(mvm); + + +} + +void GLRenderer::visitNodeDrawingStyleBefore(NodeDrawingStyle& ds) { + glPushAttrib(GL_ALL_ATTRIB_BITS); +} + +void GLRenderer::visitNodeDrawingStyleAfter(NodeDrawingStyle&) { + glPopAttrib(); +} + +void GLRenderer::RenderTriangleStrip( const real *iVertices, + const real *iNormals, + const FrsMaterial *const* iMaterials, + const real *iTexCoords, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned* iTIndices, + const unsigned iNVertices) +{ + unsigned index = -1; + glBegin(GL_TRIANGLE_STRIP); + for(unsigned int i=0; i<iNVertices; i++) + { + if(iMIndices){ + if(iMIndices[i] != index){ + visitFrsMaterial(*(iMaterials[iMIndices[i]])); + index = iMIndices[i]; + } + } + + if(iTIndices){ + glTexCoord2f( iTexCoords[iTIndices[i]], + iTexCoords[iTIndices[i]+1]); + } + + glNormal3r(iNormals[iNIndices[i]], + iNormals[iNIndices[i]+1], + iNormals[iNIndices[i]+2]); + + glVertex3r( iVertices[iVIndices[i]], + iVertices[iVIndices[i]+1], + iVertices[iVIndices[i]+2]); + } + glEnd(); +} + +void GLRenderer::RenderTriangleFan( const real *iVertices, + const real *iNormals, + const FrsMaterial *const* iMaterials, + const real *iTexCoords, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned* iTIndices, + const unsigned iNVertices) +{ + unsigned index = -1; + glBegin(GL_TRIANGLE_FAN); + for(unsigned int i=0; i<iNVertices; i++) + { + if(iMIndices){ + if(iMIndices[i] != index){ + visitFrsMaterial(*(iMaterials[iMIndices[i]])); + index = iMIndices[i]; + } + } + if(iTIndices){ + glTexCoord2f( iTexCoords[iTIndices[i]], + iTexCoords[iTIndices[i]+1]); + } + + glNormal3r(iNormals[iNIndices[i]], + iNormals[iNIndices[i]+1], + iNormals[iNIndices[i]+2]); + + glVertex3r( iVertices[iVIndices[i]], + iVertices[iVIndices[i]+1], + iVertices[iVIndices[i]+2]); + } + glEnd(); +} + +void GLRenderer::RenderTriangles( const real *iVertices, + const real *iNormals, + const FrsMaterial *const* iMaterials, + const real *iTexCoords, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned* iTIndices, + const unsigned iNVertices) +{ + unsigned index = -1; + glBegin(GL_TRIANGLES); + for(unsigned int i=0; i<iNVertices; i++) + { + if(iMIndices){ + if(iMIndices[i] != index){ + visitFrsMaterial(*(iMaterials[iMIndices[i]])); + index = iMIndices[i]; + } + } + if(iTIndices){ + glTexCoord2f( iTexCoords[iTIndices[i]], + iTexCoords[iTIndices[i]+1]); + } + + glNormal3r(iNormals[iNIndices[i]], + iNormals[iNIndices[i]+1], + iNormals[iNIndices[i]+2]); + + glVertex3r( iVertices[iVIndices[i]], + iVertices[iVIndices[i]+1], + iVertices[iVIndices[i]+2]); + } + glEnd(); +} + +void GLRenderer::visitLineRep( LineRep& iLine) +{ + if(iLine.width() != 0) + glLineWidth(iLine.width()); + + switch(iLine.style()) + { + case LineRep::LINES: + glBegin(GL_LINES); + break; + case LineRep::LINE_STRIP: + glBegin(GL_LINE_STRIP); + break; + case LineRep::LINE_LOOP: + glBegin(GL_LINE_LOOP); + break; + default: + return; + } + + const vector<Vec3r>& vertices = iLine.vertices(); + //soc unused float step=1.f/vertices.size(); + vector<Vec3r>::const_iterator v; + + for(v=vertices.begin(); v!=vertices.end(); v++) + glVertex3r((*v)[0], (*v)[1], (*v)[2]); + + glEnd(); +} + + +void GLRenderer::visitTriangleRep( TriangleRep& iTriangle) +{ + glPushAttrib(GL_ALL_ATTRIB_BITS); + switch(iTriangle.style()) + { + case TriangleRep::FILL: + glPolygonMode(GL_FRONT, GL_FILL); + break; + case TriangleRep::LINES: + glPolygonMode(GL_FRONT, GL_LINES); + break; + default: + return; + } + + glBegin(GL_TRIANGLES); + for(int i=0; i<3; ++i) + { + glColor3f(iTriangle.color(i)[0], iTriangle.color(i)[1], iTriangle.color(i)[2]); + glVertex3r(iTriangle.vertex(i)[0], iTriangle.vertex(i)[1], iTriangle.vertex(i)[2]); + } + + glEnd(); + + + + glPopAttrib(); + +} + +void GLRenderer::visitOrientedLineRep(OrientedLineRep& iLine) +{ + switch(iLine.style()) + { + case LineRep::LINES: + glBegin(GL_LINES); + break; + case LineRep::LINE_STRIP: + glBegin(GL_LINE_STRIP); + break; + case LineRep::LINE_LOOP: + glBegin(GL_LINE_LOOP); + break; + default: + return; + } + + int i=0; + int ncolor = iLine.getId().getFirst()%3; + + const vector<Vec3r>& vertices = iLine.vertices(); + float step=1.f/vertices.size(); + vector<Vec3r>::const_iterator v; + for(v=vertices.begin(); v!=vertices.end(); v++) + { + switch(ncolor) + { + case 0: + glColor3f(i*step,0.f,0.f); + break; + case 1: + glColor3f(0.f, i*step, 0.f); + break; + case 2: + glColor3f(0.f, 0.f, i*step); + break; + default: + glColor3f(i*step, i*step,i*step); + break; + } + i++; + glVertex3r((*v)[0], (*v)[1], (*v)[2]); + } + + glEnd(); +} + +void GLRenderer::visitVertexRep( VertexRep& iVertex) +{ + if(iVertex.pointSize() != 0.f) + glPointSize(iVertex.pointSize()); + + glBegin(GL_POINTS); + glVertex3r(iVertex.x(), iVertex.y(), iVertex.z()); + glEnd(); +} + +void GLRenderer::visitDrawingStyle(DrawingStyle& iDrawingStyle) +{ + + // Drawing Style management + switch(iDrawingStyle.style()) + { + case DrawingStyle::FILLED: + glPolygonMode(GL_FRONT, GL_FILL); + glShadeModel(GL_SMOOTH); + break; + + case DrawingStyle::LINES: + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_LINE_SMOOTH); + glPolygonMode(GL_FRONT, GL_LINE); + glLineWidth(iDrawingStyle.lineWidth()); + break; + + case DrawingStyle::POINTS: + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_POINT_SMOOTH); + glPolygonMode(GL_FRONT, GL_POINT); + glPointSize(iDrawingStyle.pointSize()); + break; + + case DrawingStyle::INVISIBLE: + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDepthMask(0); + break; + + default: + break; + } + + glLineWidth(iDrawingStyle.lineWidth()); + glPointSize(iDrawingStyle.pointSize()); + + // FIXME + if(true == iDrawingStyle.lightingEnabled()) + glEnable(GL_LIGHTING); + else + glDisable(GL_LIGHTING); +} + +void GLRenderer::visitFrsMaterial(FrsMaterial& m) { + const float* diff = m.diffuse(); + const float* amb = m.ambient(); + const float* spec = m.specular(); + const float* em = m.emission(); + + RenderColor(diff); + glMaterialfv(GL_FRONT, GL_AMBIENT, amb); + glMaterialfv(GL_FRONT, GL_DIFFUSE, diff); + glMaterialfv(GL_FRONT, GL_SPECULAR, spec); + glMaterialfv(GL_FRONT, GL_EMISSION, em); + glMaterialf(GL_FRONT, GL_SHININESS, m.shininess()); +} + +void GLRenderer::visitFrsMaterial(const FrsMaterial& m) { + const float* diff = m.diffuse(); + const float* amb = m.ambient(); + const float* spec = m.specular(); + const float* em = m.emission(); + + RenderColor(diff); + glMaterialfv(GL_FRONT, GL_AMBIENT, amb); + glMaterialfv(GL_FRONT, GL_DIFFUSE, diff); + glMaterialfv(GL_FRONT, GL_SPECULAR, spec); + glMaterialfv(GL_FRONT, GL_EMISSION, em); + glMaterialf(GL_FRONT, GL_SHININESS, m.shininess()); +} +void GLRenderer::applyTransform( const Matrix44r &iMatrix) +{ + real m[16]; + for(int lign=0; lign<4; lign++) + for(int column=0; column<4; column++) + m[column*4+lign] = iMatrix(lign, column); + + glMultMatrixr(m); +} + +void GLRenderer::RenderColor( const float *rgba) +{ + glColor4fv(rgba); +} diff --git a/source/blender/freestyle/intern/rendering/GLRenderer.h b/source/blender/freestyle/intern/rendering/GLRenderer.h new file mode 100755 index 00000000000..3769aefb92b --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLRenderer.h @@ -0,0 +1,204 @@ +// +// Filename : GLRenderer.h +// Author(s) : Stephane Grabli, Emmanuel Turquin +// Purpose : Class to render a 3D scene thanks to OpenGL +// Date of creation : 07/02/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GLRENDERER_H +# define GLRENDERER_H + +# ifdef WIN32 +# include <windows.h> +# endif +# ifdef __MACH__ +# include <OpenGL/gl.h> +# else +# include <GL/gl.h> +# endif + +# include "../system/FreestyleConfig.h" +# include "../system/Precision.h" +# include "../scene_graph/SceneVisitor.h" +# include "../geometry/Geom.h" +using namespace Geometry; + +class LIB_RENDERING_EXPORT GLRenderer : public SceneVisitor +{ + public: + + inline GLRenderer() : SceneVisitor() {} + virtual ~GLRenderer() {} + + // + // visitClass methods + // + ////////////////////////////////////////////// + + VISIT_DECL(NodeLight) + VISIT_DECL(NodeCamera) + VISIT_DECL(NodeTransform) + + VISIT_DECL(LineRep) + VISIT_DECL(OrientedLineRep) + VISIT_DECL(TriangleRep) + VISIT_DECL(VertexRep) + VISIT_DECL(IndexedFaceSet) + VISIT_DECL(DrawingStyle) + VISIT_DECL(FrsMaterial) + + virtual void visitFrsMaterial(const FrsMaterial&); + virtual void visitNodeTransformBefore(NodeTransform&); + virtual void visitNodeTransformAfter(NodeTransform&); + virtual void visitNodeDrawingStyleBefore(NodeDrawingStyle&); + virtual void visitNodeDrawingStyleAfter(NodeDrawingStyle&); + + protected: + + /*! Renders a face made of a triangles strip + * iVertices + * Array of float containing the face vertices. 3 floats per + * x, y, z vertex coordinates + * iNormals + * Array of float containing the face normals. 3 floats per + * x, y, z vertex normal coordinates + * iTexCoords + * Array of float containing the face uv coords. 2 floats per + * u,v vertex texture coordinates + * iVIndices + * Array of the indices (to use with the iVertices array) + * describing the vertices parsing order + * iNIndices + * Array of normals indices (to use with iNormals array) + * describing the normals parsing order + * iTIndices + * Array of texture coordinates indices (to use with iTexCoords array) + * describing the texture coordinates parsing order + * iNVertices + * The number of vertices in the face + */ + virtual void RenderTriangleStrip(const real *iVertices, + const real *iNormals, + const FrsMaterial *const*iMaterials, + const real *iTexCoords, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned* iTIndices, + const unsigned iNVertices) ; + + /*! Renders a face made of a triangles fan + * iVertices + * Array of float containing the face vertices. 3 floats per + * x, y, z vertex coordinates + * iNormals + * Array of float containing the face normals. 3 floats per + * x, y, z vertex normal coordinates + * iTexCoords + * Array of float containing the face uv coords. 2 floats per + * u,v vertex texture coordinates + * iVIndices + * Array of the indices (to use with the iVertices array) + * describing the vertices parsing order + * iNIndices + * Array of normals indices (to use with iNormals array) + * describing the normals parsing order + * iTIndices + * Array of texture coordinates indices (to use with iTexCoords array) + * describing the texture coordinates parsing order + * iNVertices + * The number of vertices in the face + */ + virtual void RenderTriangleFan(const real *iVertices, + const real *iNormals, + const FrsMaterial *const* iMaterials, + const real *iTexCoords, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned* iTIndices, + const unsigned iNVertices) ; + + /*! Renders a face made of single triangles + * iVertices + * Array of float containing the face vertices. 3 floats per + * x, y, z vertex coordinates + * iNormals + * Array of float containing the face normals. 3 floats per + * x, y, z vertex normal coordinates + * iTexCoords + * Array of float containing the face uv coords. 2 floats per + * u,v vertex texture coordinates + * iVIndices + * Array of the indices (to use with the iVertices array) + * describing the vertices parsing order + * iNIndices + * Array of normals indices (to use with iNormals array) + * describing the normals parsing order + * iTIndices + * Array of texture coordinates indices (to use with iTexCoords array) + * describing the texture coordinates parsing order + * iNVertices + * The number of vertices in the face + */ + virtual void RenderTriangles(const real *iVertices, + const real *iNormals, + const FrsMaterial *const* iMaterials, + const real *iTexCoords, + const unsigned* iVIndices, + const unsigned* iNIndices, + const unsigned* iMIndices, + const unsigned* iTIndices, + const unsigned iNVertices) ; + + /*! Apply a transform matrix by multiplying + * the current OpenGL ModelView Matrix by + * iMatrix + */ + virtual void applyTransform( const Matrix44r &iMatrix) ; + + /*! Sets the current drawing color. + * Active only when light is disabled + * (simple call to glColor4fv) + * rgba + * array of 4 floats (r, g, b and alpha) + */ + virtual void RenderColor( const float *rgba); + + /*! glVertex3f or glVertex3d */ + inline void glVertex3r(float x, float y, float z) {glVertex3f(x,y,z);} + inline void glVertex3r(real x, real y, real z) {glVertex3d(x,y,z);} + + /*! glVertex3f or glNormal3d */ + inline void glNormal3r(float x, float y, float z) {glNormal3f(x,y,z);} + inline void glNormal3r(real x, real y, real z) {glNormal3d(x,y,z);} + + /*! glMultMatrixf or glMultMatrixd */ + inline void glMultMatrixr(float *m) {glMultMatrixf(m);} + inline void glMultMatrixr(real *m) {glMultMatrixd(m);} + +}; + +#endif // GLRENDERER_H diff --git a/source/blender/freestyle/intern/rendering/GLSelectRenderer.cpp b/source/blender/freestyle/intern/rendering/GLSelectRenderer.cpp new file mode 100755 index 00000000000..ca9199740f8 --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLSelectRenderer.cpp @@ -0,0 +1,159 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "../scene_graph/IndexedFaceSet.h" +#include "../scene_graph/NodeShape.h" +#include "GLSelectRenderer.h" + +static const float INACTIVE_COLOR_MIN = 0.2; +static const float INACTIVE_COLOR_MAX = 0.8; +static const float INACTIVE_COLOR_OFFSET = 0.2; + +static const float ACTIVE_COLOR[4] = {0.8, + 0.2, + 0.2, + 1}; + +static float selection_color[4] = {INACTIVE_COLOR_MIN, + INACTIVE_COLOR_MIN, + INACTIVE_COLOR_MIN, + 1}; + + +void GLSelectRenderer::resetColor() { + for (unsigned i = 0; i < 3; ++i) + selection_color[i] = INACTIVE_COLOR_MIN; +} + +void GLSelectRenderer::visitNodeShape(NodeShape& sn) { + if (_gl_select_rendering) + return; + for (unsigned i = 0; i < 3; ++i) { + selection_color[i] += INACTIVE_COLOR_OFFSET; + if (selection_color[i] > INACTIVE_COLOR_MAX) + selection_color[i] = INACTIVE_COLOR_MIN; + } + if (sn.shapes()[0]->getId() == _selected_shape) { + _current_shape_active = true; + return; + } + _current_shape_active = false; +} + +void GLSelectRenderer::visitFrsMaterial(FrsMaterial& m) { + if (_gl_select_rendering) + return; + + const float* amb = m.ambient(); + const float* spec = m.specular(); + const float* em = m.emission(); + + if (_current_shape_active) { + RenderColor(ACTIVE_COLOR); + glMaterialfv(GL_FRONT, GL_DIFFUSE, ACTIVE_COLOR); + } else { + RenderColor(selection_color); + glMaterialfv(GL_FRONT, GL_DIFFUSE, selection_color); + } + glMaterialfv(GL_FRONT, GL_AMBIENT, amb); + glMaterialfv(GL_FRONT, GL_SPECULAR, spec); + glMaterialfv(GL_FRONT, GL_EMISSION, em); + glMaterialf(GL_FRONT, GL_SHININESS, m.shininess()); +} + +void GLSelectRenderer::visitFrsMaterial(const FrsMaterial& m) { + if (_gl_select_rendering) + return; + + const float* amb = m.ambient(); + const float* spec = m.specular(); + const float* em = m.emission(); + + if (_current_shape_active) { + RenderColor(ACTIVE_COLOR); + glMaterialfv(GL_FRONT, GL_DIFFUSE, ACTIVE_COLOR); + } else { + RenderColor(selection_color); + glMaterialfv(GL_FRONT, GL_DIFFUSE, selection_color); + } + glMaterialfv(GL_FRONT, GL_AMBIENT, amb); + glMaterialfv(GL_FRONT, GL_SPECULAR, spec); + glMaterialfv(GL_FRONT, GL_EMISSION, em); + glMaterialf(GL_FRONT, GL_SHININESS, m.shininess()); +} + +void GLSelectRenderer::visitIndexedFaceSet(IndexedFaceSet& ifs) +{ + unsigned int fIndex = 0; + + const real * vertices = ifs.vertices(); + const real * normals = ifs.normals(); + const FrsMaterial *const* frs_materials = ifs.frs_materials(); + const real * texCoords= ifs.texCoords(); + const unsigned *vindices = ifs.vindices(); + const unsigned *nindices = ifs.nindices(); + const unsigned *mindices = ifs.mindices(); + const unsigned *tindices = ifs.tindices(); + const unsigned numfaces = ifs.numFaces(); + const IndexedFaceSet::TRIANGLES_STYLE * faceStyle = ifs.trianglesStyle(); + const unsigned *numVertexPerFace = ifs.numVertexPerFaces(); + + + const unsigned* pvi = vindices; + const unsigned* pni = nindices; + const unsigned* pmi = mindices; + const unsigned* pti = tindices; + + for(fIndex=0; fIndex<numfaces; fIndex++) + { + switch(faceStyle[fIndex]) + { + case IndexedFaceSet::TRIANGLE_STRIP: + RenderTriangleStrip(vertices, normals, frs_materials, texCoords, pvi, pni, pmi, pti, numVertexPerFace[fIndex]); + break; + case IndexedFaceSet::TRIANGLE_FAN: + RenderTriangleFan(vertices, normals, frs_materials, texCoords, pvi, pni, pmi, pti, numVertexPerFace[fIndex]); + break; + case IndexedFaceSet::TRIANGLES: + RenderTriangles(vertices, normals, frs_materials, texCoords, pvi, pni, pmi, pti, numVertexPerFace[fIndex]); + break; + } + pvi += numVertexPerFace[fIndex]; + pni += numVertexPerFace[fIndex]; + pmi += numVertexPerFace[fIndex]; + if(pti) + pti += numVertexPerFace[fIndex]; + } +} + +void GLSelectRenderer::visitNodeShapeBefore(NodeShape& sn) { + if (!_gl_select_rendering) + return; + + glPushName(sn.shapes()[0]->getId().getFirst()); +} + +void GLSelectRenderer::visitNodeShapeAfter(NodeShape& sn) { + if (!_gl_select_rendering) + return; + + glPopName(); +} diff --git a/source/blender/freestyle/intern/rendering/GLSelectRenderer.h b/source/blender/freestyle/intern/rendering/GLSelectRenderer.h new file mode 100755 index 00000000000..2ce8c3f62db --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLSelectRenderer.h @@ -0,0 +1,85 @@ +// +// Filename : GLSelectRenderer.h +// Author(s) : Emmanuel Turquin +// Purpose : Class to highlight selected shapes +// Date of creation : 09/01/2004 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GL_SELECT_RENDERER_H +# define GL_SELECT_RENDERER_H + +# include "GLRenderer.h" + +class LIB_RENDERING_EXPORT GLSelectRenderer : public GLRenderer +{ + public: + + inline GLSelectRenderer() : GLRenderer() { + _selected_shape = -1; // -1 means no selection + _current_shape_active = false; + _gl_select_rendering = false; + } + virtual ~GLSelectRenderer() {} + + // + // visitClass methods + // + ////////////////////////////////////////////// + + VISIT_DECL(NodeShape) + + VISIT_DECL(IndexedFaceSet) + VISIT_DECL(FrsMaterial) + + virtual void visitFrsMaterial(const FrsMaterial&); + virtual void visitNodeShapeBefore(NodeShape&); + virtual void visitNodeShapeAfter(NodeShape&); + + void resetColor(); + + void setSelectedId(const int id) { + _selected_shape = id; + } + + void setSelectRendering(bool b) { + _gl_select_rendering = b; + } + + int getSelectedId() const { + return _selected_shape; + } + + bool getSelectRendering() const { + return _gl_select_rendering; + } + + private: + + int _selected_shape; + bool _current_shape_active; + bool _gl_select_rendering; +}; + +#endif // GL_SELECT_RENDERER_H diff --git a/source/blender/freestyle/intern/rendering/GLStrokeRenderer.cpp b/source/blender/freestyle/intern/rendering/GLStrokeRenderer.cpp new file mode 100755 index 00000000000..e29dd5cad8f --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLStrokeRenderer.cpp @@ -0,0 +1,474 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "GLStrokeRenderer.h" + +//soc +// #include <qimage.h> +// #include <qfileinfo.h> +// #include <qgl.h> +// #include <qfile.h> + +extern "C" { +#include "BLI_blenlib.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +#include "MEM_guardedalloc.h" +} + +#include "../system/StringUtils.h" + +GLStrokeRenderer::GLStrokeRenderer() +:StrokeRenderer() +{ + _textureManager = new GLTextureManager; +} + +GLStrokeRenderer::~GLStrokeRenderer() +{ + if(0 != _textureManager) + { + delete _textureManager; + _textureManager = 0; + } +} + +float initialColor(float x, float avTex=0.5) +{ + float y=(1-x)/avTex; + return (y>1 ? 1 : y); +} +//float complementColor(float x, float avTex=0.5) +//{ +// float y=(1-x)/avTex-1; +// return (y<0 ? 0 : y); +//} + +float complementColor(float x, float avTex=0.5) +{ + float y=(1-x);///avTex-1; + return (y<0 ? 0 : y); +} + +void GLStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const +{ + glPushAttrib(GL_COLOR_BUFFER_BIT); + Stroke::MediumType strokeType = iStrokeRep->getMediumType(); + // int averageTextureAlpha=0.5; //default value + // if (strokeType==OIL_STROKE) + // averageTextureAlpha=0.75; + // if (strokeType>=NO_BLEND_STROKE) + // averageTextureAlpha=1.0; + // if (strokeType<0) + // { + // renderNoTexture(iStrokeRep); + // return; + // } + //soc unused - int i; + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_DEPTH_TEST); + + glEnable(GL_BLEND); + + if(strokeType==Stroke::DRY_MEDIUM) + { + FRS_glBlendEquation(GL_MAX); + } + else if(strokeType==Stroke::OPAQUE_MEDIUM) + { + FRS_glBlendEquation(GL_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else + { + FRS_glBlendEquation(GL_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + glEnable(GL_TEXTURE_2D); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + //first texture, basically the only one for lighter strokes + glBindTexture(GL_TEXTURE_2D, iStrokeRep->getTextureId()); + + vector<Strip*>& strips = iStrokeRep->getStrips(); + for(vector<Strip*>::iterator s=strips.begin(), send=strips.end(); + s!=send; + ++s){ + Strip::vertex_container& vertices = (*s)->vertices(); + glBegin(GL_TRIANGLE_STRIP); + for(Strip::vertex_container::iterator v=vertices.begin(), vend=vertices.end(); + v!=vend; + ++v){ + + StrokeVertexRep * svRep = (*v); + Vec3r color = svRep->color(); + real alpha = svRep->alpha(); + glColor4f(complementColor(color[0]), + complementColor(color[1]), + complementColor(color[2]), alpha); + glTexCoord2f(svRep->texCoord()[0],svRep->texCoord()[1] ); + glVertex2f(svRep->point2d()[0], svRep->point2d()[1]); + } + glEnd(); + } +// if (strokeType>=NO_BLEND_STROKE) return; + // //return; + // + // //second texture, the complement, for stronger strokes + // glBindTexture(GL_TEXTURE_2D, _textureManager.getTextureIndex(2*strokeType+1)); + // glBegin(GL_TRIANGLE_STRIP); + // for(i=0; i<_sizeStrip; i++) + // { + // glColor4f(complementColor(_color[i][0]), + // complementColor(_color[i][1]), + // complementColor(_color[i][2]), _alpha[i]); + // glTexCoord2f(_texCoord[i][0],_texCoord[i][1] ); + // glVertex2f(_vertex[i][0], _vertex[i][1]); + // } + // glEnd(); + + glPopAttrib(); +} + +void GLStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const +{ + glPushAttrib(GL_COLOR_BUFFER_BIT); + //soc unused - Stroke::MediumType strokeType = iStrokeRep->getMediumType(); + //soc unused - int i; + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glShadeModel(GL_SMOOTH); + glDisable(GL_DEPTH_TEST); + + glEnable(GL_BLEND); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_TEXTURE_2D); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + //first texture, basically the only one for lighter strokes + glBindTexture(GL_TEXTURE_2D, iStrokeRep->getTextureId()); + + vector<Strip*>& strips = iStrokeRep->getStrips(); + for(vector<Strip*>::iterator s=strips.begin(), send=strips.end(); + s!=send; + ++s){ + Strip::vertex_container& vertices = (*s)->vertices(); + glBegin(GL_TRIANGLE_STRIP); + for(Strip::vertex_container::iterator v=vertices.begin(), vend=vertices.end(); + v!=vend; + ++v){ + StrokeVertexRep * svRep = (*v); + Vec3r color = svRep->color(); + real alpha = svRep->alpha(); + glColor4f(color[0], + color[1], + color[2], alpha); + glTexCoord2f(svRep->texCoord()[0],svRep->texCoord()[1] ); + glVertex2f(svRep->point2d()[0], svRep->point2d()[1]); + } + glEnd(); + } + glPopAttrib(); +} + +//No Texture +//void GLStrokeRenderer::renderNoTexture(StrokeRep *iStrokeRep) const +//{ +// Stroke::MediumType strokeType = iStrokeRep->getMediumType(); +// int sizeStrip = iStrokeRep->sizeStrip(); +// const Vec3r *color = iStrokeRep->colors(); +// const Vec2r *vertex = iStrokeRep->vertices(); +// const float *alpha = iStrokeRep->alpha(); +// +// glDisable(GL_LIGHTING); +// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +// glShadeModel(GL_SMOOTH); +// glDisable(GL_DEPTH_TEST); +// +// //if (strokeType==NO_TEXTURE_STROKE) +// if(strokeType < 0) +// { +// glDisable(GL_BLEND); +// glDisable(GL_TEXTURE_2D); +// glBegin(GL_TRIANGLE_STRIP); +// for(int i=0; i<sizeStrip; i++) +// { +// glColor4f(complementColor(color[i][0]), +// complementColor(color[i][1]), +// complementColor(color[i][2]), alpha[i]); +// glVertex2f(vertex[i][0], vertex[i][1]); +// } +// glEnd(); +// } +// else +// { +// //#ifdef WIN32 +// //glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); +// glBlendEquation(GL_ADD); +// //#endif +// glEnable(GL_BLEND); +// glBlendFunc(GL_SRC_ALPHA, GL_ONE); +// glDisable(GL_TEXTURE_2D); +// glBegin(GL_TRIANGLE_STRIP); +// for(int i=0; i<sizeStrip; i++) +// { +// glColor4f(complementColor(color[i][0]), +// complementColor(color[i][1]), +// complementColor(color[i][2]), alpha[i]); +// glVertex2f(vertex[i][0], vertex[i][1]); +// } +// glEnd(); +// } +// // cerr<<"color="<<_color[1][0]<<", "<<_color[1][1]<<", "<<_color[1][2]<<") "<<endl; +// +// +//} + + +/**********************************/ +/* */ +/* */ +/* GLTextureManager */ +/* */ +/* */ +/**********************************/ + +//#define TEXTURES_DIR ROOT_DIR "/data/textures" + +GLTextureManager::GLTextureManager () +: TextureManager() +{ + //_brushes_path = Config::getInstance()... +} + +GLTextureManager::~GLTextureManager () +{ +} + +void GLTextureManager::loadStandardBrushes() +{ + // getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/oil.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/oilnoblend.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::DRY_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::DRY_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueDryBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM); + _defaultTextureId = getBrushTextureIndex("smoothAlpha.bmp", Stroke::OPAQUE_MEDIUM); +} + + +unsigned +GLTextureManager::loadBrush(string sname, Stroke::MediumType mediumType) +{ + GLuint texId; + glGenTextures(1, &texId); + bool found = false; + vector<string> pathnames; + string path; //soc + StringUtils::getPathName(TextureManager::Options::getBrushesPath(), + sname, + pathnames); + for (vector<string>::const_iterator j = pathnames.begin(); j != pathnames.end(); j++) { + path = j->c_str(); + //soc if(QFile::exists(path)){ + if( BLI_exists( const_cast<char *>(path.c_str()) ) ) { + found = true; + break; + } + } + if(!found) + return 0; + // Brush texture + cout << "Loading brush texture..." << endl; + switch(mediumType){ + case Stroke::DRY_MEDIUM: + //soc prepareTextureLuminance((const char*)path.toAscii(), texId); + prepareTextureLuminance(StringUtils::toAscii(path), texId); + break; + case Stroke::HUMID_MEDIUM: + case Stroke::OPAQUE_MEDIUM: + default: + //soc prepareTextureAlpha((const char*)path.toAscii(), texId); + prepareTextureAlpha(StringUtils::toAscii(path), texId); + break; + } + cout << "Done." << endl << endl; + + return texId; +} + +bool +GLTextureManager::prepareTextureAlpha (string sname, GLuint itexname) +{ + //soc const char * name = sname.c_str(); + char * name = (char *) sname.c_str(); + + //soc + ImBuf *qim = IMB_loadiffname(name, 0); + char filename[FILE_MAXFILE]; + char *p = BLI_strdup(name); + BLI_splitdirstring(p, filename); + MEM_freeN(p); + +//soc if (qim.isNull()) + if (!qim) //soc + { + cerr << " Error: unable to read \"" << filename << "\"" << endl; + IMB_freeImBuf(qim); + return false; + } + + if( qim->depth > 8) //soc + { + cerr<<" Error: \""<< filename <<"\" has "<< qim->depth <<" bits/pixel"<<endl; //soc + return false; + } + // qim=QGLWidget::convertToGLFormat( qimOri ); + + glBindTexture(GL_TEXTURE_2D, itexname); + //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + // GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, qim->x, qim->y, 0, + GL_ALPHA, GL_UNSIGNED_BYTE, qim->rect); //soc + + //soc cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl; + cout << " \"" << filename << "\" loaded with 32 bits per pixel" << endl; + + return true; + +} + +bool +GLTextureManager::prepareTextureLuminance (string sname, GLuint itexname) +{ + //soc const char * name = sname.c_str(); + char * name = (char *) sname.c_str(); + + //soc + ImBuf *qim = IMB_loadiffname(name, 0); + char filename[FILE_MAXFILE]; + char *p = BLI_strdup(name); + BLI_splitdirstring(p, filename); + MEM_freeN(p); + + if (!qim) //soc + { + cerr << " Error: unable to read \"" << filename << "\"" << endl; + IMB_freeImBuf(qim); + return false; + } + if (qim->depth > 8) //soc + { + cerr<<" Error: \""<<filename<<"\" has "<<qim->depth <<" bits/pixel"<<endl;//soc + return false; + } + + glBindTexture(GL_TEXTURE_2D, itexname); + //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + // GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, qim->x, qim->y, 0, + GL_LUMINANCE, GL_UNSIGNED_BYTE, qim->rect); //soc + + //soc cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl; + cout << " \"" << filename << "\" loaded with "<< qim->depth << " bits per pixel" << endl; + + return true; + +} + +bool +GLTextureManager::prepareTextureLuminanceAndAlpha (string sname, GLuint itexname) +{ + //soc const char * name = sname.c_str(); + char * name = (char *) sname.c_str(); + + //soc + ImBuf *qim = IMB_loadiffname(name, 0); + char filename[FILE_MAXFILE]; + char *p = BLI_strdup(name); + BLI_splitdirstring(p, filename); + MEM_freeN(p); + + if (!qim) //soc + { + cerr << " Error: unable to read \"" << filename << "\"" << endl; + IMB_freeImBuf(qim); + return false; + } + + if (qim->depth > 8) //soc + { + cerr<<" Error: \""<<filename<<"\" has "<< qim->depth <<" bits/pixel"<<endl; //soc + return false; + } + + glBindTexture(GL_TEXTURE_2D, itexname); + //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + // GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, qim->x, qim->y, 0, + GL_LUMINANCE, GL_UNSIGNED_BYTE, qim->rect); //soc + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, qim->x, qim->y, 0, + GL_ALPHA, GL_UNSIGNED_BYTE, qim->rect); //soc + + //soc cout << " \"" << filename.toAscii().data() << "\" loaded with "<< qim.depth() << " bits per pixel" << endl; + cout << " \"" << filename << "\" loaded with "<< qim->depth << " bits per pixel" << endl; + + return true; + +} + + diff --git a/source/blender/freestyle/intern/rendering/GLStrokeRenderer.h b/source/blender/freestyle/intern/rendering/GLStrokeRenderer.h new file mode 100755 index 00000000000..345a4273350 --- /dev/null +++ b/source/blender/freestyle/intern/rendering/GLStrokeRenderer.h @@ -0,0 +1,88 @@ +// +// Filename : GLStrokeRenderer.h +// Author(s) : Stephane Grabli +// Purpose : Class to define the GL stroke renderer. +// Date of creation : 05/03/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef GLSTROKERENDERER_H +# define GLSTROKERENDERER_H + +# include "../system/FreestyleConfig.h" +# include "../stroke/StrokeRenderer.h" +# include "../stroke/StrokeRep.h" + +#include "GLBlendEquation.h" + +/**********************************/ +/* */ +/* */ +/* GLTextureManager */ +/* */ +/* */ +/**********************************/ + +/*! Class to load textures + */ +class LIB_RENDERING_EXPORT GLTextureManager : public TextureManager +{ + public: + GLTextureManager (); + virtual ~GLTextureManager (); +protected: + virtual unsigned loadBrush(string fileName, Stroke::MediumType = Stroke::OPAQUE_MEDIUM); + + protected: + virtual void loadStandardBrushes(); + bool prepareTextureAlpha (string name, GLuint itexname); + bool prepareTextureLuminance (string name, GLuint itexname); + bool prepareTextureLuminanceAndAlpha (string name, GLuint itexname); +}; + + + +/**********************************/ +/* */ +/* */ +/* GLStrokeRenderer */ +/* */ +/* */ +/**********************************/ + +class LIB_RENDERING_EXPORT GLStrokeRenderer : public StrokeRenderer +{ +public: + GLStrokeRenderer(); + virtual ~GLStrokeRenderer(); + + /*! Renders a stroke rep */ + virtual void RenderStrokeRep(StrokeRep *iStrokeRep) const; + virtual void RenderStrokeRepBasic(StrokeRep *iStrokeRep) const; + +protected: + //void renderNoTexture(StrokeRep *iStrokeRep) const; +}; + +#endif // GLSTROKERENDERER_H diff --git a/source/blender/freestyle/intern/scene_graph/DrawingStyle.h b/source/blender/freestyle/intern/scene_graph/DrawingStyle.h new file mode 100755 index 00000000000..58dcf4fede9 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/DrawingStyle.h @@ -0,0 +1,82 @@ +// +// Filename : DrawingStyle.h +// Author(s) : Stephane Grabli +// Purpose : Class to define the drawing style of a node +// Date of creation : 10/10/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef DRAWINGSTYLE_H +# define DRAWINGSTYLE_H + +class DrawingStyle +{ +public: + enum STYLE + {FILLED, LINES, POINTS, INVISIBLE}; + + inline DrawingStyle() {Style = FILLED; LineWidth = 2.f; PointSize = 2.f; LightingEnabled = true;} + inline explicit DrawingStyle(const DrawingStyle& iBrother); + + virtual ~DrawingStyle() {} + + /*! operators */ + inline DrawingStyle& operator=(const DrawingStyle& ds); + + inline void setStyle(const STYLE iStyle) {Style = iStyle;} + inline void setLineWidth(const float iLineWidth) {LineWidth = iLineWidth;} + inline void setPointSize(const float iPointSize) {PointSize = iPointSize;} + inline void setLightingEnabled(const bool on) {LightingEnabled = on;} + + inline STYLE style() const {return Style;} + inline float lineWidth() const {return LineWidth;} + inline float pointSize() const {return PointSize;} + inline bool lightingEnabled() const {return LightingEnabled;} + +private: + STYLE Style; + float LineWidth; + float PointSize; + bool LightingEnabled; +}; + +DrawingStyle::DrawingStyle(const DrawingStyle& iBrother) +{ + Style = iBrother.Style; + LineWidth = iBrother.LineWidth; + PointSize = iBrother.PointSize; + LightingEnabled = iBrother.LightingEnabled; +} + +DrawingStyle& DrawingStyle::operator=(const DrawingStyle& ds) +{ + Style = ds.Style; + LineWidth = ds.LineWidth; + PointSize = ds.PointSize; + LightingEnabled = ds.LightingEnabled; + + return *this; +} + +#endif // DRAWINGSTYLE_H diff --git a/source/blender/freestyle/intern/scene_graph/FrsMaterial.h b/source/blender/freestyle/intern/scene_graph/FrsMaterial.h new file mode 100755 index 00000000000..1cbadab2bd3 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/FrsMaterial.h @@ -0,0 +1,304 @@ +// +// Filename : FrsMaterial.h +// Author(s) : Stephane Grabli +// Purpose : Class used to handle materials. +// Date of creation : 10/10/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef FRS_MATERIAL_H +# define FRS_MATERIAL_H + +# include "../system/FreestyleConfig.h" + +/*! Class defining a material */ +class FrsMaterial +{ +public: + /*! Default constructor */ + inline FrsMaterial(); + /*! Builds a Material from its diffuse, ambiant, specular, emissive + * colors and a shininess coefficient. + * \param iDiffuse + * A 4 element float-array containing the diffuse color. + * \param iAmbiant + * A 4 element float-array containing the ambiant color. + * \param iSpecular + * A 4 element float-array containing the specular color. + * \param iEmission + * A 4 element float-array containing the emissive color. + * \param iShininess + * The shininess coefficient. + */ + inline FrsMaterial(const float *iDiffuse, + const float *iAmbiant, + const float *iSpecular, + const float *iEmission, + const float iShininess); + + /*! Copy constructor */ + inline FrsMaterial(const FrsMaterial& m); + /*! Destructor */ + virtual ~FrsMaterial() {} + + + /*! Returns the diffuse color as a 4 float array */ + inline const float * diffuse() const { return Diffuse; } + /*! Returns the red component of the diffuse color */ + inline const float diffuseR() const { return Diffuse[0]; } + /*! Returns the green component of the diffuse color */ + inline const float diffuseG() const { return Diffuse[1]; } + /*! Returns the blue component of the diffuse color */ + inline const float diffuseB() const { return Diffuse[2]; } + /*! Returns the alpha component of the diffuse color */ + inline const float diffuseA() const { return Diffuse[3]; } + + /*! Returns the specular color as a 4 float array */ + inline const float * specular() const { return Specular; } + /*! Returns the red component of the specular color */ + inline const float specularR() const { return Specular[0]; } + /*! Returns the green component of the specular color */ + inline const float specularG() const { return Specular[1]; } + /*! Returns the blue component of the specular color */ + inline const float specularB() const { return Specular[2]; } + /*! Returns the alpha component of the specular color */ + inline const float specularA() const { return Specular[3]; } + + /*! Returns the ambiant color as a 4 float array */ + inline const float * ambient() const { return Ambient; } + /*! Returns the red component of the ambiant color */ + inline const float ambientR() const { return Ambient[0]; } + /*! Returns the green component of the ambiant color */ + inline const float ambientG() const { return Ambient[1]; } + /*! Returns the blue component of the ambiant color */ + inline const float ambientB() const { return Ambient[2]; } + /*! Returns the alpha component of the ambiant color */ + inline const float ambientA() const { return Ambient[3]; } + + /*! Returns the emissive color as a 4 float array */ + inline const float * emission() const { return Emission; } + /*! Returns the red component of the emissive color */ + inline const float emissionR() const { return Emission[0]; } + /*! Returns the green component of the emissive color */ + inline const float emissionG() const { return Emission[1]; } + /*! Returns the blue component of the emissive color */ + inline const float emissionB() const { return Emission[2]; } + /*! Returns the alpha component of the emissive color */ + inline const float emissionA() const { return Emission[3]; } + + /*! Returns the shininess coefficient */ + inline const float shininess() const { return Shininess; } + + /*! Sets the diffuse color. + * \param r + * Red component + * \param g + * Green component + * \param b + * Blue component + * \param a + * Alpha component + */ + inline void setDiffuse(const float r, const float g, const float b, const float a); + /*! Sets the specular color. + * \param r + * Red component + * \param g + * Green component + * \param b + * Blue component + * \param a + * Alpha component + */ + inline void setSpecular(const float r, const float g, const float b, const float a); + /*! Sets the ambiant color. + * \param r + * Red component + * \param g + * Green component + * \param b + * Blue component + * \param a + * Alpha component + */ + inline void setAmbient(const float r, const float g, const float b, const float a); + + /*! Sets the emissive color. + * \param r + * Red component + * \param g + * Green component + * \param b + * Blue component + * \param a + * Alpha component + */ + inline void setEmission(const float r, const float g, const float b, const float a); + + /*! Sets the shininess. + * \param s + * Shininess + */ + inline void setShininess(const float s); + + /* operators */ + inline FrsMaterial& operator=(const FrsMaterial& m); + inline bool operator!=(const FrsMaterial& m) const; + inline bool operator==(const FrsMaterial& m) const; + +private: + + /*! Material properties */ + float Diffuse[4]; + float Specular[4]; + float Ambient[4]; + float Emission[4]; + float Shininess; + +}; + +FrsMaterial::FrsMaterial() +{ + Ambient[0] = Ambient[1] = Ambient[2] = 0.2f; + Ambient[3] = 1.f; + + Diffuse[0] = Diffuse[1] = Diffuse[2] = 0.8f; + Diffuse[3] = 1.f; + + Emission[0] = Emission[1] = Emission[2] = 0.f; + Emission[3] = 1.f; + + Specular[0] = Specular[1] = Specular[2] = 0.f; + Specular[3] = 1.f; + + Shininess = 0.f; +} + +FrsMaterial::FrsMaterial(const float *iDiffuse, + const float *iAmbiant, + const float *iSpecular, + const float *iEmission, + const float iShininess) +{ + for(int i=0; i<4; i++) + { + Diffuse[i] = iDiffuse[i]; + Specular[i] = iSpecular[i]; + Ambient[i] = iAmbiant[i]; + Emission[i] = iEmission[i]; + } + + Shininess = iShininess; +} + +FrsMaterial::FrsMaterial(const FrsMaterial& m) +{ + for(int i=0; i<4; i++) + { + Diffuse[i] = m.diffuse()[i]; + Specular[i] = m.specular()[i]; + Ambient[i] = m.ambient()[i]; + Emission[i] = m.emission()[i]; + } + + Shininess = m.shininess(); +} + +void FrsMaterial::setDiffuse(const float r, const float g, const float b, const float a) +{ + Diffuse[0] = r; + Diffuse[1] = g; + Diffuse[2] = b; + Diffuse[3] = a; +} + +void FrsMaterial::setSpecular(const float r, const float g, const float b, const float a) +{ + Specular[0] = r; + Specular[1] = g; + Specular[2] = b; + Specular[3] = a; +} + +void FrsMaterial::setAmbient(const float r, const float g, const float b, const float a) +{ + Ambient[0] = r; + Ambient[1] = g; + Ambient[2] = b; + Ambient[3] = a; +} + +void FrsMaterial::setEmission(const float r, const float g, const float b, const float a) +{ + Emission[0] = r; + Emission[1] = g; + Emission[2] = b; + Emission[3] = a; +} + +void FrsMaterial::setShininess(const float s) +{ + Shininess = s; +} + +FrsMaterial& FrsMaterial::operator=(const FrsMaterial& m) +{ + for(int i=0; i<4; i++) + { + Diffuse[i] = m.diffuse()[i]; + Specular[i] = m.specular()[i]; + Ambient[i] = m.ambient()[i]; + Emission[i] = m.emission()[i]; + } + + Shininess = m.shininess(); + + return *this; +} + +bool FrsMaterial::operator!=(const FrsMaterial& m) const +{ + if(Shininess != m.shininess()) + return true; + for(int i=0; i<4; i++) + { + if(Diffuse[i] != m.diffuse()[i]) + return true; + if(Specular[i] != m.specular()[i]) + return true; + if(Ambient[i] != m.ambient()[i]) + return true; + if(Emission[i] != m.emission()[i]) + return true; + } + + return false; +} + +bool FrsMaterial::operator==(const FrsMaterial& m) const +{ + return (!((*this)!=m)); +} + +#endif // FRS_MATERIAL_H diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp new file mode 100755 index 00000000000..98872c6c8ea --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp @@ -0,0 +1,321 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "IndexedFaceSet.h" + +IndexedFaceSet::IndexedFaceSet() +: Rep() +{ + _Vertices = NULL; + _Normals = NULL; + _FrsMaterials = 0; + _TexCoords = 0; + _VSize = 0; + _NSize = 0; + _MSize = 0; + _TSize = 0; + _NumFaces = 0; + _NumVertexPerFace = NULL; + _FaceStyle = NULL; + _VIndices = NULL; + _VISize = 0; + _NIndices = NULL; + _NISize = 0; + _MIndices = NULL; + _MISize = 0; + _TIndices = NULL; + _TISize = 0; + _displayList = 0; +} + +IndexedFaceSet::IndexedFaceSet( real *iVertices, unsigned iVSize, + real *iNormals, unsigned iNSize, + FrsMaterial **iMaterials, unsigned iMSize, + real *iTexCoords, unsigned iTSize, + unsigned iNumFaces, unsigned *iNumVertexPerFace, TRIANGLES_STYLE *iFaceStyle, + unsigned *iVIndices, unsigned iVISize, + unsigned *iNIndices, unsigned iNISize, + unsigned *iMIndices, unsigned iMISize, + unsigned *iTIndices, unsigned iTISize, + unsigned iCopy) + : Rep() +{ + if(1 == iCopy) + { + _VSize = iVSize; + _Vertices = new real[_VSize]; + memcpy(_Vertices, iVertices, iVSize*sizeof(real)); + + _NSize = iNSize; + _Normals = new real[_NSize]; + memcpy(_Normals, iNormals, iNSize*sizeof(real)); + + _MSize = iMSize; + _FrsMaterials = 0; + if(iMaterials){ + _FrsMaterials = new FrsMaterial*[_MSize]; + for(unsigned i=0; i<_MSize; ++i) + _FrsMaterials[i] = new FrsMaterial(*(iMaterials[i])); + } + _TSize = iTSize; + _TexCoords = 0; + if(_TSize){ + _TexCoords = new real[_TSize]; + memcpy(_TexCoords, iTexCoords, iTSize*sizeof(real)); + } + + _NumFaces = iNumFaces; + _NumVertexPerFace = new unsigned[_NumFaces]; + memcpy(_NumVertexPerFace, iNumVertexPerFace, _NumFaces*sizeof(unsigned)); + + _FaceStyle = new TRIANGLES_STYLE[_NumFaces]; + memcpy(_FaceStyle, iFaceStyle, _NumFaces*sizeof(TRIANGLES_STYLE)); + + _VISize = iVISize; + _VIndices = new unsigned[_VISize]; + memcpy(_VIndices, iVIndices, _VISize*sizeof(unsigned)); + + _NISize = iNISize; + _NIndices = new unsigned[_NISize]; + memcpy(_NIndices, iNIndices, _NISize*sizeof(unsigned)); + + _MISize = iMISize; + _MIndices = 0; + if(iMIndices){ + _MIndices = new unsigned[_MISize]; + memcpy(_MIndices, iMIndices, _MISize*sizeof(unsigned)); + } + _TISize = iTISize; + _TIndices = 0; + if(_TISize){ + _TIndices = new unsigned[_TISize]; + memcpy(_TIndices, iTIndices, _TISize*sizeof(unsigned)); + } + } + else + { + _VSize = iVSize; + _Vertices = iVertices; + + _NSize = iNSize; + _Normals = iNormals; + + _MSize = iMSize; + _FrsMaterials = 0; + if(iMaterials) + _FrsMaterials = iMaterials; + + _TSize = iTSize; + _TexCoords = iTexCoords; + + _NumFaces = iNumFaces; + _NumVertexPerFace = iNumVertexPerFace; + _FaceStyle = iFaceStyle; + + _VISize = iVISize; + _VIndices = iVIndices; + + _NISize = iNISize; + _NIndices = iNIndices; + + _MISize = iMISize; + _MIndices = 0; + if(iMISize) + _MIndices = iMIndices; + + _TISize = iTISize; + _TIndices = iTIndices; + } + + _displayList = 0; +} + +IndexedFaceSet::IndexedFaceSet( const IndexedFaceSet& iBrother) +:Rep(iBrother) +{ + _VSize = iBrother.vsize(); + _Vertices = new real[_VSize]; + memcpy(_Vertices, iBrother.vertices(), _VSize*sizeof(real)); + + _NSize = iBrother.nsize(); + _Normals = new real[_NSize]; + memcpy(_Normals, iBrother.normals(), _NSize*sizeof(real)); + + _MSize = iBrother.msize(); + if(_MSize){ + _FrsMaterials = new FrsMaterial*[_MSize]; + for(unsigned i=0; i<_MSize; ++i){ + _FrsMaterials[i] = new FrsMaterial(*(iBrother._FrsMaterials[i])); + } + }else{ + _FrsMaterials = 0; + } + + _TSize = iBrother.tsize(); + _TexCoords = 0; + if(_TSize){ + _TexCoords = new real[_TSize]; + memcpy(_TexCoords, iBrother.texCoords(), _TSize*sizeof(real)); + } + + _NumFaces = iBrother.numFaces(); + _NumVertexPerFace = new unsigned[_NumFaces]; + memcpy(_NumVertexPerFace, iBrother.numVertexPerFaces(), _NumFaces*sizeof(unsigned)); + + _FaceStyle = new TRIANGLES_STYLE[_NumFaces]; + memcpy(_FaceStyle, iBrother.trianglesStyle(), _NumFaces*sizeof(TRIANGLES_STYLE)); + + _VISize = iBrother.visize(); + _VIndices = new unsigned[_VISize]; + memcpy(_VIndices, iBrother.vindices(), _VISize*sizeof(unsigned)); + + _NISize = iBrother.nisize(); + _NIndices = new unsigned[_NISize]; + memcpy(_NIndices, iBrother.nindices(), _NISize*sizeof(unsigned)); + + _MISize = iBrother.misize(); + if(_MISize){ + _MIndices = new unsigned[_MISize]; + memcpy(_MIndices, iBrother.mindices(), _MISize*sizeof(unsigned)); + }else{ + _MIndices=0; + } + + _TISize = iBrother.tisize(); + _TIndices = 0; + if(_TISize){ + _TIndices = new unsigned[_TISize]; + memcpy(_TIndices, iBrother.tindices(), _TISize*sizeof(unsigned)); + } + + _displayList = 0; +} + +IndexedFaceSet::~IndexedFaceSet() +{ + if(NULL != _Vertices) + { + delete [] _Vertices; + _Vertices = NULL; + } + + if(NULL != _Normals) + { + delete [] _Normals; + _Normals = NULL; + } + + if(NULL != _FrsMaterials) + { + for(unsigned i=0; i<_MSize; ++i) + delete _FrsMaterials[i]; + delete [] _FrsMaterials; + _FrsMaterials = NULL; + } + + if(NULL != _TexCoords) + { + delete [] _TexCoords; + _TexCoords = NULL; + } + + if(NULL != _NumVertexPerFace) + { + delete [] _NumVertexPerFace; + _NumVertexPerFace = NULL; + } + + if(NULL != _FaceStyle) + { + delete [] _FaceStyle; + _FaceStyle = NULL; + } + + if(NULL != _VIndices) + { + delete [] _VIndices; + _VIndices = NULL; + } + + if(NULL != _NIndices) + { + delete [] _NIndices; + _NIndices = NULL; + } + + if(NULL != _MIndices) + { + delete [] _MIndices; + _MIndices = NULL; + } + if(NULL != _TIndices) + { + delete [] _TIndices; + _TIndices = NULL; + } + // should find a way to deallocates the displayList + // glDeleteLists(GLuint list, GLSizei range) + _displayList = 0; +} + +void IndexedFaceSet::accept(SceneVisitor& v) { + Rep::accept(v); + v.visitIndexedFaceSet(*this); +} + +void IndexedFaceSet::ComputeBBox() +{ + real XMax = _Vertices[0]; + real YMax = _Vertices[1]; + real ZMax = _Vertices[2]; + + real XMin = _Vertices[0]; + real YMin = _Vertices[1]; + real ZMin = _Vertices[2]; + + // parse all the coordinates to find + // the Xmax, YMax, ZMax + real *v = _Vertices; + + for(unsigned i=0; i<_VSize/3; i++) + { + // X + if(*v > XMax) + XMax = *v; + if(*v < XMin) + XMin = *v; + v++; + + if(*v > YMax) + YMax = *v; + if(*v < YMin) + YMin = *v; + v++; + + if(*v > ZMax) + ZMax = *v; + if(*v < ZMin) + ZMin = *v; + v++; + } + + setBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax))); +} diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h new file mode 100755 index 00000000000..41db4db4c42 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h @@ -0,0 +1,222 @@ +// +// Filename : IndexedFaceSet.h +// Author(s) : Stephane Grabli +// Purpose : A Set of indexed faces to represent a surfacic object +// Date of creation : 22/01/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef INDEXEDFACESET_H +# define INDEXEDFACESET_H + +# include <stdio.h> +# include <memory.h> + +//! inherits from class Rep +# include "Rep.h" + +# include "../system/FreestyleConfig.h" + +class LIB_SCENE_GRAPH_EXPORT IndexedFaceSet : public Rep + { +public: + + /*! Triangles description style:*/ + enum TRIANGLES_STYLE{TRIANGLE_STRIP, TRIANGLE_FAN, TRIANGLES}; + + /*! Builds an empty indexed face set + */ + IndexedFaceSet(); + /*! Builds an indexed face set + iVertices + The array of object vertices 3D coordinates (for all faces). + If iCopy != 0, the array is copied; you must desallocate iVertices. Else you must not. + iVSize + The size of iVertices (must be a multiple of 3) + iNormals + The array of object normals 3D coordinates. + If iCopy != 0, the array is copied; you must desallocate iNormals. Else you must not. + iNSize + The size of iNormals + iMaterials + The array of materials + iMSize + The size of iMaterials + iTexCoords + The array of texture coordinates. + iTSize + The size of iTexCoords (must be multiple of 2) + iNumFaces + The number of faces + iNumVertexPerFace + Array containing the number of vertices per face. + iFaceStyle + Array containing the description style of each faces. + The style belongs to: + - TRIANGLE_STRIP: the face indices describe a triangle strip + - TRIANGLE_FAN : the face indices describe a triangle fan + - TRIANGLES : the face indices describe single triangles + If iCopy != 0, the array is copied; you must desallocate iFaceStyle. Else you must not. + iVIndices, + Array of vertices indices. + The integers contained in this array must be multiple of 3. + If iCopy != 0, the array is copied; you must desallocate iVIndices. Else you must not. + iVISize + The size of iVIndices. + iNIndices + Array of normals indices. + The integers contained in this array must be multiple of 3. + If iCopy != 0, the array is copied; you must desallocate iNIndices. Else you must not. + iNISize + The size of iNIndices + iMIndices + The Material indices (per vertex) + iMISize + The size of iMIndices + iTIndices + The Texture coordinates indices (per vertex). The integers contained in this array must be multiple of 2. + iTISize + The size of iMIndices + iCopy + 0 : the arrays are not copied. The pointers passed as arguments are used. + IndexedFaceSet takes these arrays desallocation in charge. + 1 : the arrays are copied. The caller is in charge of the arrays, passed + as arguments desallocation. + */ + IndexedFaceSet( real *iVertices, unsigned iVSize, + real *iNormals, unsigned iNSize, + FrsMaterial **iMaterials, unsigned iMSize, + real *iTexCoords, unsigned iTSize, + unsigned iNumFaces, unsigned *iNumVertexPerFace, TRIANGLES_STYLE *iFaceStyle, + unsigned *iVIndices, unsigned iVISize, + unsigned *iNIndices, unsigned iNISize, + unsigned *iMIndices, unsigned iMISize, + unsigned *iTIndices, unsigned iTISize, + unsigned iCopy = 1 + ); + + /*! Builds an indexed face set from an other indexed face set */ + IndexedFaceSet(const IndexedFaceSet& iBrother); + + void swap(IndexedFaceSet& ioOther){ + std::swap(_Vertices, ioOther._Vertices); + std::swap(_Normals, ioOther._Normals); + std::swap(_FrsMaterials, ioOther._FrsMaterials); + std::swap(_TexCoords, ioOther._TexCoords); + + std::swap(_VSize, ioOther._VSize); + std::swap(_NSize, ioOther._NSize); + std::swap(_MSize, ioOther._MSize); + std::swap(_TSize, ioOther._TSize); + + std::swap(_NumFaces, ioOther._NumFaces); + std::swap(_NumVertexPerFace, ioOther._NumVertexPerFace); + std::swap(_FaceStyle, ioOther._FaceStyle); + + std::swap(_VIndices, ioOther._VIndices); + std::swap(_NIndices, ioOther._NIndices); + std::swap(_MIndices, ioOther._MIndices); // Material Indices + std::swap(_TIndices, ioOther._TIndices); + + std::swap(_VISize, ioOther._VISize); + std::swap(_NISize, ioOther._NISize); + std::swap(_MISize, ioOther._MISize); + std::swap(_TISize, ioOther._TISize); + + std::swap(_displayList, ioOther._displayList); + + Rep::swap(ioOther); + } + + IndexedFaceSet& operator=(const IndexedFaceSet& iBrother){ + IndexedFaceSet tmp(iBrother); + swap(tmp); + return *this; + } + + /*! Desctructor + desallocates all the ressources */ + virtual ~IndexedFaceSet(); + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); + + /*! Compute the Bounding Box */ + virtual void ComputeBBox(); + + /*! modifiers */ + inline void setDisplayList(unsigned int index) {_displayList = index;} + + /*! Accessors */ + virtual const real * vertices() const {return _Vertices;} + virtual const real * normals() const {return _Normals;} + virtual const FrsMaterial*const* frs_materials() const {return _FrsMaterials;} + virtual const real* texCoords() const {return _TexCoords;} + virtual const unsigned vsize() const {return _VSize;} + virtual const unsigned nsize() const {return _NSize;} + virtual const unsigned msize() const {return _MSize;} + virtual const unsigned tsize() const {return _TSize;} + virtual const unsigned numFaces() const {return _NumFaces;} + virtual const unsigned * numVertexPerFaces() const {return _NumVertexPerFace;} + virtual const TRIANGLES_STYLE * trianglesStyle() const {return _FaceStyle;} + virtual const unsigned* vindices() const {return _VIndices;} + virtual const unsigned* nindices() const {return _NIndices;} + virtual const unsigned* mindices() const {return _MIndices;} + virtual const unsigned* tindices() const {return _TIndices;} + virtual const unsigned visize() const {return _VISize;} + virtual const unsigned nisize() const {return _NISize;} + virtual const unsigned misize() const {return _MISize;} + virtual const unsigned tisize() const {return _TISize;} + inline unsigned int displayList() const {return _displayList;} + +protected: + real *_Vertices; + real *_Normals; + FrsMaterial** _FrsMaterials; + real *_TexCoords; + + unsigned _VSize; + unsigned _NSize; + unsigned _MSize; + unsigned _TSize; + + unsigned _NumFaces; + unsigned *_NumVertexPerFace; + TRIANGLES_STYLE *_FaceStyle; + + unsigned *_VIndices; + unsigned *_NIndices; + unsigned *_MIndices; // Material Indices + unsigned *_TIndices; // Texture coordinates Indices + + unsigned _VISize; + unsigned _NISize; + unsigned _MISize; + unsigned _TISize; + + unsigned int _displayList; + +}; + +#endif // INDEXEDFACESET_H diff --git a/source/blender/freestyle/intern/scene_graph/LineRep.cpp b/source/blender/freestyle/intern/scene_graph/LineRep.cpp new file mode 100755 index 00000000000..504db06acf4 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/LineRep.cpp @@ -0,0 +1,58 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "LineRep.h" + +void LineRep::ComputeBBox() +{ + real XMax = _vertices.front()[0]; + real YMax = _vertices.front()[1]; + real ZMax = _vertices.front()[2]; + + real XMin = _vertices.front()[0]; + real YMin = _vertices.front()[1]; + real ZMin = _vertices.front()[2]; + + // parse all the coordinates to find + // the XMax, YMax, ZMax + vector<Vec3r>::iterator v; + for(v=_vertices.begin(); v!=_vertices.end(); v++) { + // X + if((*v)[0] > XMax) + XMax = (*v)[0]; + if((*v)[0] < XMin) + XMin = (*v)[0]; + + // Y + if((*v)[1] > YMax) + YMax = (*v)[1]; + if((*v)[1] < YMin) + YMin = (*v)[1]; + + // Z + if((*v)[2] > ZMax) + ZMax = (*v)[2]; + if((*v)[2] < ZMin) + ZMin = (*v)[2]; + } + + setBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax))); +} diff --git a/source/blender/freestyle/intern/scene_graph/LineRep.h b/source/blender/freestyle/intern/scene_graph/LineRep.h new file mode 100755 index 00000000000..232557af857 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/LineRep.h @@ -0,0 +1,130 @@ +// +// Filename : LineRep.h +// Author(s) : Stephane Grabli +// Purpose : Class to define the representation of 3D Line. +// Date of creation : 26/03/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef LINEREP_H +# define LINEREP_H + +# include <vector> +# include <list> +# include "Rep.h" +# include "../system/FreestyleConfig.h" + +using namespace std; + +/*! Base class for all lines objects */ +class LIB_SCENE_GRAPH_EXPORT LineRep : public Rep +{ +public: + + /*! Line description style */ + enum LINES_STYLE{LINES, LINE_STRIP, LINE_LOOP}; + inline LineRep() : Rep() {_width = 0.f;} + + /*! Builds a single line from 2 vertices + * v1 + * first vertex + * v2 + * second vertex + */ + inline LineRep(const Vec3r& v1, const Vec3r& v2) + : Rep() + { + setStyle(LINES); + AddVertex(v1); + AddVertex(v2); + _width = 0.f; + } + + /*! Builds a line rep from a vertex chain */ + inline LineRep(const vector<Vec3r>& vertices) + : Rep() + { + _vertices = vertices; + setStyle(LINE_STRIP); + _width = 0.f; + } + + /*! Builds a line rep from a vertex chain */ + inline LineRep(const list<Vec3r>& vertices) + : Rep() + { + for(list<Vec3r>::const_iterator v=vertices.begin(), end=vertices.end(); + v!=end; + v++) + { + _vertices.push_back(*v); + } + setStyle(LINE_STRIP); + _width = 0.f; + } + + virtual ~LineRep() + { + _vertices.clear(); + } + + /*! accessors */ + inline const LINES_STYLE style() const {return _Style;} + inline const vector<Vec3r>& vertices() const {return _vertices;} + inline float width() const {return _width;} + + /*! modifiers */ + inline void setStyle(const LINES_STYLE iStyle) {_Style = iStyle;} + inline void AddVertex(const Vec3r& iVertex) {_vertices.push_back(iVertex);} + inline void setVertices(const vector<Vec3r>& iVertices) + { + if(0 != _vertices.size()) + { + _vertices.clear(); + } + for(vector<Vec3r>::const_iterator v=iVertices.begin(), end=iVertices.end(); + v!=end; + v++) + { + _vertices.push_back(*v); + } + } + inline void setWidth(float iWidth) {_width=iWidth;} + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v) { + Rep::accept(v); + v.visitLineRep(*this); + } + + /*! Computes the line bounding box.*/ + virtual void ComputeBBox(); + +private: + LINES_STYLE _Style; + vector<Vec3r> _vertices; + float _width; +}; + +#endif // LINEREP_H diff --git a/source/blender/freestyle/intern/scene_graph/Node.h b/source/blender/freestyle/intern/scene_graph/Node.h new file mode 100755 index 00000000000..41afaa353be --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/Node.h @@ -0,0 +1,97 @@ +// +// Filename : Node.h +// Author(s) : Stephane Grabli +// Purpose : Abstract class for scene graph nodes. Inherits from +// BaseObject which defines the addRef release mechanism. +// Date of creation : 24/01/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NODE_H +# define NODE_H + +# include "../system/FreestyleConfig.h" +# include "../system/BaseObject.h" +# include "SceneVisitor.h" +# include "../geometry/BBox.h" +# include "../geometry/Geom.h" +# include "../system/Precision.h" + +using namespace std; +using namespace Geometry; + +class LIB_SCENE_GRAPH_EXPORT Node : public BaseObject +{ +public: + + inline Node() : BaseObject() {} + inline Node(const Node& iBrother) : BaseObject() + { + _BBox = iBrother.bbox(); + } + virtual ~Node(){} + + /*! Accept the corresponding visitor + * Each inherited node + * must overload this method + */ + virtual void accept(SceneVisitor& v) { + v.visitNode(*this); + } + + /*! bounding box management */ + /*! Returns the node bounding box + * If no bounding box exists, an empty bbox + * is returned + */ + virtual const BBox<Vec3r>& bbox() const {return _BBox;} + + /*! Sets the Node bounding box */ + virtual void setBBox(const BBox<Vec3r>& iBox) {_BBox = iBox;} + + /*! Makes the union of _BBox and iBox */ + virtual void AddBBox(const BBox<Vec3r>& iBox) + { + if(iBox.empty()) + return; + + if(_BBox.empty()) + _BBox = iBox; + else + _BBox += iBox; + } + + /*! Updates the BBox */ + virtual const BBox<Vec3r>& UpdateBBox() {return _BBox;} + + /*! Clears the bounding box */ + virtual void clearBBox() { _BBox.clear(); } + +protected: + +private: + BBox<Vec3r> _BBox; +}; + +#endif // NODE_H diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp b/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp new file mode 100644 index 00000000000..1d095b35a0d --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp @@ -0,0 +1,120 @@ +#include <string.h> // for memcpy +#include "NodeCamera.h" +#include <math.h> + +void loadIdentity(double * matrix){ + int i; + + // Build Identity matrix + for(i=0;i<16;++i){ + double value ; + if((i % 5) == 0) + value = 1.0; + else + value = 0; + matrix[i] = value; + } +} + +NodeCamera::NodeCamera(CameraType camera_type) +:camera_type_(camera_type){ + loadIdentity(modelview_matrix_); + loadIdentity(projection_matrix_); +} + +NodeCamera::NodeCamera(const NodeCamera& iBrother) +:camera_type_(iBrother.camera_type_){ + memcpy(modelview_matrix_, iBrother.modelview_matrix_, 16*sizeof(double)); + memcpy(projection_matrix_, iBrother.projection_matrix_, 16*sizeof(double)); +} + +void NodeCamera::accept(SceneVisitor& v){ + v.visitNodeCamera(*this) ; +} + +void NodeCamera::setModelViewMatrix(double modelview_matrix[16]){ + memcpy(modelview_matrix_, modelview_matrix,16*sizeof(double)); +} + +void NodeCamera::setProjectionMatrix(double projection_matrix[16]){ + memcpy(projection_matrix_, projection_matrix,16*sizeof(double)); +} + +NodeOrthographicCamera::NodeOrthographicCamera() +:NodeCamera(NodeCamera::ORTHOGRAPHIC), +left_(0),right_(0),bottom_(0),top_(0),zNear_(0),zFar_(0){ + loadIdentity(projection_matrix_); + loadIdentity(modelview_matrix_); +} + +NodeOrthographicCamera::NodeOrthographicCamera(double left + , double right + , double bottom + , double top + , double zNear + , double zFar + ) +:NodeCamera(NodeCamera::ORTHOGRAPHIC), +left_(left), +right_(right), +bottom_(bottom), +top_(top), +zNear_(zNear), +zFar_(zFar){ + + loadIdentity(projection_matrix_); + + projection_matrix_[0] = 2.0/(right-left); + projection_matrix_[3] = -(right + left) / (right - left) ; + projection_matrix_[5] = 2.0/(top-bottom); + projection_matrix_[7] = -(top + bottom) / (top - bottom) ; + projection_matrix_[10] = -2.0/(zFar-zNear); + projection_matrix_[11] = -(zFar + zNear) / (zFar - zNear); + +} + +NodeOrthographicCamera::NodeOrthographicCamera(const NodeOrthographicCamera& iBrother) +:NodeCamera(iBrother),left_(iBrother.left_),right_(iBrother.right_),bottom_(iBrother.bottom_),top_(iBrother.top_),zNear_(iBrother.zNear_),zFar_(iBrother.zFar_){ +} + +NodePerspectiveCamera::NodePerspectiveCamera() +:NodeCamera(NodeCamera::PERSPECTIVE){ +} + +NodePerspectiveCamera::NodePerspectiveCamera(double fovy + , double aspect + , double zNear + , double zFar) +:NodeCamera(NodeCamera::PERSPECTIVE){ + loadIdentity(projection_matrix_); + + double f = cos(fovy/2.0)/sin(fovy/2.0); // cotangent + + projection_matrix_[0] = f/aspect; + projection_matrix_[5] = f; + projection_matrix_[10] = (zNear+zFar)/(zNear-zFar); + projection_matrix_[11] = (2.0*zNear*zFar)/(zNear-zFar); + projection_matrix_[14] = -1.0; + projection_matrix_[15] = 0; + +} + +NodePerspectiveCamera::NodePerspectiveCamera(double left, + double right, + double bottom, + double top, + double zNear, + double zFar) +:NodeCamera(NodeCamera::PERSPECTIVE){ + loadIdentity(projection_matrix_); + + projection_matrix_[0] = (2.0*zNear)/(right-left); + projection_matrix_[2] = (right+left)/(right-left); + projection_matrix_[5] = (2.0*zNear)/(top-bottom); + projection_matrix_[6] = (top+bottom)/(top-bottom); + projection_matrix_[10] = - (zFar+zNear)/(zFar-zNear); + projection_matrix_[11] = - (2.0*zFar*zNear)/(zFar-zNear); + projection_matrix_[14] = -1.0; + projection_matrix_[15] = 0; +} + diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.h b/source/blender/freestyle/intern/scene_graph/NodeCamera.h new file mode 100644 index 00000000000..cdd6fa83048 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.h @@ -0,0 +1,192 @@ +// +// Filename : NodeCamera.h +// Author(s) : Stephane Grabli +// Purpose : Class to represent a light node +// Date of creation : 25/01/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + + +#ifndef NODE_CAMERA_H_ +#define NODE_CAMERA_H_ + +# include "../geometry/Geom.h" +# include "../system/FreestyleConfig.h" +# include "Node.h" + +using namespace Geometry; + +class NodeOrthographicCamera; +class NodePerspectiveCamera; +class LIB_SCENE_GRAPH_EXPORT NodeCamera : public Node +{ +public: + typedef enum {PERSPECTIVE,ORTHOGRAPHIC,GENERIC} CameraType; + + /*! Default matrices: Identity for both projection and modelview. */ + NodeCamera(CameraType camera_type = GENERIC); + NodeCamera(const NodeCamera& iBrother); + + virtual ~NodeCamera() {} + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); + + /*! Matrix is copied */ + void setModelViewMatrix(double modelview_matrix[16]); + /*! Matrix is copied */ + void setProjectionMatrix(double projection_matrix[16]); + + double * modelViewMatrix() {return modelview_matrix_;} + double * projectionMatrix() {return projection_matrix_;} + +protected: + // row major right handed matrix + double modelview_matrix_[16]; + // row major right handed matrix + double projection_matrix_[16]; + + CameraType camera_type_; +}; + +class LIB_SCENE_GRAPH_EXPORT NodeOrthographicCamera : public NodeCamera{ +public: + NodeOrthographicCamera(); + /*! Builds a parallel projection matrix a la glOrtho. + A 0 0 tx + 0 B 0 ty + 0 0 C tz + 0 0 0 1 + + where + + A = + 2 / (right - left) + B = + 2 / (top - bottom) + C = + -2 / (far - near) + tx = + -(right + left) / (right - left) + ty = + -(top + bottom) / (top - bottom) + tz = + -(zFar + zNear) / (zFar - zNear) + */ + NodeOrthographicCamera(double left + , double right + , double bottom + , double top + , double zNear + , double zFar + ); + + double left() const {return left_;} + double right() const {return right_;} + double bottom() const {return bottom_;} + double top() const {return top_;} + double zNear() const {return zNear_;} + double zFar() const {return zFar_;} + + NodeOrthographicCamera(const NodeOrthographicCamera& iBrother); + +private: + double left_; + double right_; + double bottom_; + double top_; + double zNear_; + double zFar_; +}; + +class LIB_SCENE_GRAPH_EXPORT NodePerspectiveCamera : public NodeCamera { +public: + NodePerspectiveCamera(); + /*! Builds a perspective projection matrix a la gluPerspective. + Given f defined as follows: + fovy + f = cotangent(____) + 2 + The generated matrix is + + + ( f ) + | ______ | + | aspect 0 0 0 | + | | + | 0 f 0 0 | + | | + | zNear+zFar 2*zNear*zFar | + | __________ ____________ | + | 0 0 zNear-zFar zNear-zFar | + | | + ( 0 0 -1 0 ) + \param fovy + Field of View specified in radians. + */ + NodePerspectiveCamera(double fovy + , double aspect + , double zNear + , double zFar); + + /*! Builds a perspective projection matrix a la glFrustum. + ( 2*zNear ) + | __________ | + | right-left 0 A 0 | + | | + | 2*zNear | + | 0 __________ B 0 | + | top-bottom | + | | + | 0 0 C D | + | | + | 0 0 -1 0 | + ( ) + + right+left + A = __________ + right-left + + top+bottom + B = __________ + top-bottom + + zFar+zNear + C = - __________ + zFar-zNear + + 2*zFar*zNear + D = - ____________ + zFar-zNear + */ + NodePerspectiveCamera(double left, + double right, + double bottom, + double top, + double zNear, + double zFar); +}; + + +#endif // NODE_CAMERA_H_ diff --git a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.cpp b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.cpp new file mode 100755 index 00000000000..acd740ee055 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.cpp @@ -0,0 +1,34 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "NodeDrawingStyle.h" + +void NodeDrawingStyle::accept(SceneVisitor& v) { + v.visitNodeDrawingStyle(*this); + + v.visitNodeDrawingStyleBefore(*this); + v.visitDrawingStyle(_DrawingStyle); + for(vector<Node*>::iterator node=_Children.begin(), end=_Children.end(); + node!=end; + node++) + (*node)->accept(v); + v.visitNodeDrawingStyleAfter(*this); +} diff --git a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h new file mode 100755 index 00000000000..012f963ea8c --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h @@ -0,0 +1,70 @@ +// +// Filename : NodeDrawingStyle.h +// Author(s) : Stephane Grabli +// Purpose : Class to define a Drawing Style to be applied +// to the underlying children. Inherits from NodeGroup. +// Date of creation : 06/02/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NODEDRAWINGSTYLE_H +# define NODEDRAWINGSTYLE_H + +# include "../system/FreestyleConfig.h" +# include "NodeGroup.h" +# include "DrawingStyle.h" + +class LIB_SCENE_GRAPH_EXPORT NodeDrawingStyle : public NodeGroup +{ +public: + + inline NodeDrawingStyle() : NodeGroup() {} + virtual ~NodeDrawingStyle() {} + + inline const DrawingStyle& drawingStyle() const { return _DrawingStyle; } + inline void setDrawingStyle(const DrawingStyle& iDrawingStyle) { _DrawingStyle = iDrawingStyle; } + + /*! Sets the style. Must be one of FILLED, LINES, POINTS, INVISIBLE. */ + inline void setStyle(const DrawingStyle::STYLE iStyle) { _DrawingStyle.setStyle(iStyle); } + /*! Sets the line width in the LINES style case */ + inline void setLineWidth(const float iLineWidth) { _DrawingStyle.setLineWidth(iLineWidth); } + /*! Sets the Point size in the POINTS style case */ + inline void setPointSize(const float iPointSize) { _DrawingStyle.setPointSize(iPointSize); } + /*! Enables or disables the lighting. TRUE = enable */ + inline void setLightingEnabled(const bool iEnableLighting) { _DrawingStyle.setLightingEnabled(iEnableLighting); } + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); + + /*! accessors */ + inline DrawingStyle::STYLE style() const {return _DrawingStyle.style();} + inline float lineWidth() const {return _DrawingStyle.lineWidth();} + inline float pointSize() const {return _DrawingStyle.pointSize();} + inline bool lightingEnabled() const {return _DrawingStyle.lightingEnabled();} + +private: + DrawingStyle _DrawingStyle; +}; + +#endif // NODEDRAWINGSTYLE_H diff --git a/source/blender/freestyle/intern/scene_graph/NodeGroup.cpp b/source/blender/freestyle/intern/scene_graph/NodeGroup.cpp new file mode 100755 index 00000000000..3d2aa2c8694 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeGroup.cpp @@ -0,0 +1,122 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "NodeGroup.h" + +void NodeGroup::AddChild(Node *iChild) +{ + if(NULL == iChild) + return; + + _Children.push_back(iChild); + iChild->addRef(); +} + +int NodeGroup::destroy() +{ + /*! Node::destroy makes a release on the object + * and then returns the reference counter. + * If the reference counter is equal to 0, + * that means that nobody else is linking + * this node group and that we can destroy the whole + * underlying tree. + * Else, one or several Node link this node group, + * and we only returns the reference counter + * decremented by Node::destroy(); + */ + int refThis = Node::destroy(); + + // if refThis != 0, we can't destroy the tree + if(0 != refThis) + return refThis; + + // If we are here, that means that nobody else + // needs our NodeGroup and we can destroy it. + int refCount = 0; + vector<Node *>::iterator node; + + for(node=_Children.begin(); node!=_Children.end(); node++) + { + refCount = (*node)->destroy(); + if(0 == refCount) + delete (*node); + } + + _Children.clear(); + + return refThis; +} + +void NodeGroup::accept(SceneVisitor& v) { + v.visitNodeGroup(*this); + + v.visitNodeGroupBefore(*this); + for(vector<Node *>::iterator node=_Children.begin(), end=_Children.end(); + node!=end; + node++) + (*node)->accept(v); + v.visitNodeGroupAfter(*this); +} + +void NodeGroup::DetachChildren() +{ + vector<Node *>::iterator node; + + for(node=_Children.begin(); node!=_Children.end(); node++) + { + (*node)->release(); + } + + _Children.clear(); +} + +void NodeGroup::DetachChild(Node *iChild) +{ + int found = 0; + vector<Node*>::iterator node; + + for(node=_Children.begin(); node!=_Children.end(); node++) + { + if((*node) == iChild) + { + (*node)->release(); + _Children.erase(node); + found = 1; + break; + } + } +} + +void NodeGroup::RetrieveChildren(vector<Node*>& oNodes){ + oNodes = _Children; +} + +const BBox<Vec3r>& NodeGroup::UpdateBBox() +{ + vector<Node *>::iterator node; + clearBBox(); + for(node=_Children.begin(); node!=_Children.end(); node++) + { + AddBBox((*node)->UpdateBBox()); + } + + return Node::UpdateBBox(); +} diff --git a/source/blender/freestyle/intern/scene_graph/NodeGroup.h b/source/blender/freestyle/intern/scene_graph/NodeGroup.h new file mode 100755 index 00000000000..a1bd2b57e56 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeGroup.h @@ -0,0 +1,84 @@ +// +// Filename : NodeGroup.h +// Author(s) : Stephane Grabli +// Purpose : Class to represent a group node. This node can contains +// several children. It also contains a transform matrix +// indicating the transform state of the underlying +// children. +// Date of creation : 24/01/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NODEGROUP_H +# define NODEGROUP_H + +# include <vector> +# include "../system/FreestyleConfig.h" +# include "Node.h" + +using namespace std; + +class LIB_SCENE_GRAPH_EXPORT NodeGroup : public Node +{ +public: + + inline NodeGroup(): Node() {} + virtual ~NodeGroup(){} + + /*! Adds a child. Makes a addRef on the + * iChild reference counter */ + virtual void AddChild(Node *iChild); + + /*! destroys all the underlying nodes + * Returns the reference counter + * after having done a release() */ + virtual int destroy(); + + /*! Detaches all the children */ + virtual void DetachChildren(); + + /*! Detached the sepcified child */ + virtual void DetachChild(Node *iChild); + + /*! Retrieve children */ + virtual void RetrieveChildren(vector<Node*>& oNodes); + + + /*! Renders every children */ + // virtual void Render(Renderer *iRenderer); + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); + + /*! Updates the BBox */ + virtual const BBox<Vec3r>& UpdateBBox(); + + /*! Returns the number of children */ + virtual int numberOfChildren() {return _Children.size();} + +protected: + vector<Node*> _Children; +}; + +#endif // NODEGROUP_H diff --git a/source/blender/freestyle/intern/scene_graph/NodeLight.cpp b/source/blender/freestyle/intern/scene_graph/NodeLight.cpp new file mode 100755 index 00000000000..61a46155cfa --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeLight.cpp @@ -0,0 +1,80 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "NodeLight.h" + +int NodeLight::numberOfLights = 0; + +NodeLight::NodeLight() +: Node() +{ + if(numberOfLights > 7) + { + _number = 7; + } + else + { + _number = numberOfLights; + numberOfLights++; + } + + Ambient[0] = Ambient[1] = Ambient[2] = 0.f; + Ambient[3] = 1.f; + + for(int i=0; i<4; i++) + { + Diffuse[i] = 1.f; + Specular[i] = 1.f; + } + + Position[0] = Position[1] = Position[3] = 0.f; + Position[2] = 1.f; + + on = true; +} + +NodeLight::NodeLight(NodeLight& iBrother) +: Node(iBrother) +{ + if(numberOfLights > 7) + { + _number = 7; + } + else + { + _number = numberOfLights; + numberOfLights++; + } + + for(int i=0; i<4; i++) + { + Ambient[i] = iBrother.ambient()[i]; + Diffuse[i] = iBrother.diffuse()[i]; + Specular[i] = iBrother.specular()[i]; + Position[i] = iBrother.position()[i]; + } + + on = iBrother.isOn(); +} + +void NodeLight::accept(SceneVisitor& v) { + v.visitNodeLight(*this); +} diff --git a/source/blender/freestyle/intern/scene_graph/NodeLight.h b/source/blender/freestyle/intern/scene_graph/NodeLight.h new file mode 100755 index 00000000000..0689505fb24 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeLight.h @@ -0,0 +1,86 @@ +// +// Filename : NodeLight.h +// Author(s) : Stephane Grabli +// Purpose : Class to represent a light node +// Date of creation : 25/01/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NODELIGHT_H +# define NODELIGHT_H + +# include "../geometry/Geom.h" +# include "../system/FreestyleConfig.h" +# include "Node.h" + +using namespace Geometry; + +class LIB_SCENE_GRAPH_EXPORT NodeLight : public Node +{ +public: + + NodeLight(); + NodeLight(NodeLight& iBrother); + + virtual ~NodeLight() {} + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); + + /*! Accessors for the light properties */ + inline const float * ambient() const {return Ambient;} + inline const float * diffuse() const {return Diffuse;} + inline const float * specular() const {return Specular;} + inline const float * position() const {return Position;} + inline bool isOn() const {return on;} + inline int number() const {return _number;} + +private: + // Data members + // ============ + + /*! on=true, the light is on */ + bool on; + + /*! The color definition */ + float Ambient[4]; + float Diffuse[4]; + float Specular[4]; + + /*! Light position. if w = 0, the light is + * placed at infinite. + */ + float Position[4]; + + /*! used to manage the number of lights */ + /*! numberOfLights + * the number of lights in the scene. + * Initially, 0. + */ + static int numberOfLights; + /*! The current lignt number */ + int _number; +}; + +#endif // NODELIGHT_H diff --git a/source/blender/freestyle/intern/scene_graph/NodeShape.cpp b/source/blender/freestyle/intern/scene_graph/NodeShape.cpp new file mode 100755 index 00000000000..9083c852d36 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeShape.cpp @@ -0,0 +1,51 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "NodeShape.h" + +NodeShape::~NodeShape() +{ + vector<Rep *>::iterator rep; + + if(0 != _Shapes.size()) + { + for(rep=_Shapes.begin(); rep!=_Shapes.end(); rep++) + { + int refCount = (*rep)->destroy(); + if(0 == refCount) + delete (*rep); + } + + _Shapes.clear(); + } +} + +void NodeShape::accept(SceneVisitor& v) { + v.visitNodeShape(*this); + + v.visitFrsMaterial(_FrsMaterial); + + v.visitNodeShapeBefore(*this); + vector<Rep *>::iterator rep; + for(rep = _Shapes.begin(); rep != _Shapes.end(); rep++) + (*rep)->accept(v); + v.visitNodeShapeAfter(*this); +} diff --git a/source/blender/freestyle/intern/scene_graph/NodeShape.h b/source/blender/freestyle/intern/scene_graph/NodeShape.h new file mode 100755 index 00000000000..9849d4661b8 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeShape.h @@ -0,0 +1,89 @@ +// +// Filename : NodeShape.h +// Author(s) : Stephane Grabli +// Purpose : Class to build a shape node. It contains a Rep, +// which is the shape geometry +// Date of creation : 25/01/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NODESHAPE_H +# define NODESHAPE_H + +# include <vector> +# include "../system/FreestyleConfig.h" +# include "Node.h" +# include "Rep.h" +# include "../geometry/BBox.h" +# include "../geometry/Geom.h" +# include "FrsMaterial.h" + +using namespace std; +using namespace Geometry; + +class LIB_SCENE_GRAPH_EXPORT NodeShape : public Node +{ +public: + + inline NodeShape() : Node() {} + + virtual ~NodeShape(); + + /*! Adds a Rep to the _Shapes list + * The delete of the rep is done + * when it is not used any more by + * the Scene Manager. So, it must not + * be deleted by the caller + */ + virtual void AddRep(Rep *iRep) + { + if(NULL == iRep) + return; + _Shapes.push_back(iRep); + iRep->addRef(); + + // updates bbox: + AddBBox(iRep->bbox()); + } + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); + + /*! Sets the shape material */ + inline void setFrsMaterial(const FrsMaterial& iMaterial) { _FrsMaterial = iMaterial; } + + /*! accessors */ + /*! returns the shape's material */ + inline FrsMaterial& frs_material() { return _FrsMaterial; } + inline const vector<Rep*>& shapes() {return _Shapes;} + +private: + /*! list of shapes */ + vector<Rep*> _Shapes; + + /*! Shape Material */ + FrsMaterial _FrsMaterial; +}; + +#endif // NODESHAPE_H diff --git a/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp b/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp new file mode 100755 index 00000000000..8f706c78259 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp @@ -0,0 +1,166 @@ +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + + +#include "../system/FreestyleConfig.h" +#include "NodeTransform.h" + +void NodeTransform::Translate(real x, real y, real z) +{ + _Matrix(0, 3) += x; + _Matrix(1, 3) += y; + _Matrix(2, 3) += z; +} + +void NodeTransform::Rotate(real iAngle, real x, real y, real z) +{ + //Normalize the x,y,z vector; + real norm = (real)sqrt(x*x+y*y+z*z); + if(0 == norm) + return; + + x /= norm; + y /= norm; + z /= norm; + + // find the corresponding matrix with the Rodrigues formula: + // R = I + sin(iAngle)*Ntilda + (1-cos(iAngle))*Ntilda*Ntilda + Matrix33r Ntilda; + Ntilda(0,0) = Ntilda(1,1) = Ntilda(2,2) = 0.f; + Ntilda(0,1) = -z; + Ntilda(0,2) = y; + Ntilda(1,0) = z; + Ntilda(1,2) = -x; + Ntilda(2,0) = -y; + Ntilda(2,1) = x; + + const Matrix33r Ntilda2(Ntilda * Ntilda); + + + const real sinAngle = (real)sin((iAngle/180.f)*M_PI); + const real cosAngle = (real)cos((iAngle/180.f)*M_PI); + + Matrix33r NS(Ntilda*sinAngle); + Matrix33r NC(Ntilda2*(1.f-cosAngle)); + Matrix33r R; + R = Matrix33r::identity(); + R += NS + NC; + + //R4 is the corresponding 4x4 matrix + Matrix44r R4; + R4 = Matrix44r::identity(); + + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + R4(i,j) = R(i,j); + + // Finally, we multiply our current matrix by R4: + Matrix44r mat_tmp(_Matrix); + _Matrix = mat_tmp * R4; +} + +void NodeTransform::Scale(real x, real y, real z) +{ + _Matrix(0,0) *= x; + _Matrix(1,1) *= y; + _Matrix(2,2) *= z; + + _Scaled = true; +} + +void NodeTransform::MultiplyMatrix(const Matrix44r &iMatrix) +{ + Matrix44r mat_tmp(_Matrix); + _Matrix = mat_tmp * iMatrix; +} + +void NodeTransform::setMatrix(const Matrix44r &iMatrix) +{ + _Matrix = iMatrix; + if(isScaled(iMatrix)) + _Scaled = true; +} + +void NodeTransform::accept(SceneVisitor& v) { + v.visitNodeTransform(*this); + + v.visitNodeTransformBefore(*this); + for(vector<Node *>::iterator node=_Children.begin(), end=_Children.end(); + node!=end; + node++) + (*node)->accept(v); + v.visitNodeTransformAfter(*this); +} + +void NodeTransform::AddBBox(const BBox<Vec3r>& iBBox) +{ + Vec3r oldMin(iBBox.getMin()); + Vec3r oldMax(iBBox.getMax()); + + // compute the 8 corners of the bbox + HVec3r box[8]; + box[0] = HVec3r(iBBox.getMin()); + box[1] = HVec3r(oldMax[0], oldMin[1], oldMin[2]); + box[2] = HVec3r(oldMax[0], oldMax[1], oldMin[2]); + box[3] = HVec3r(oldMin[0], oldMax[1], oldMin[2]); + box[4] = HVec3r(oldMin[0], oldMin[1], oldMax[2]); + box[5] = HVec3r(oldMax[0], oldMin[1], oldMax[2]); + box[6] = HVec3r(oldMax[0], oldMax[1], oldMax[2]); + box[7] = HVec3r(oldMin[0], oldMax[1], oldMax[2]); + + // Computes the transform iBBox + HVec3r tbox[8]; + unsigned i; + for(i = 0; i < 8; i++) + tbox[i] = _Matrix * box[i]; + + Vec3r newMin(tbox[0]); + Vec3r newMax(tbox[0]); + for (i=0; i<8; i++) + { + for (unsigned int j=0; j<3; j++) + { + if (newMin[j] > tbox[i][j]) + newMin[j] = tbox[i][j]; + if (newMax[j] < tbox[i][j]) + newMax[j] = tbox[i][j]; + } + } + + BBox<Vec3r> transformBox(newMin, newMax); + + Node::AddBBox(transformBox); +} + +bool NodeTransform::isScaled(const Matrix44r &M) +{ + for(unsigned int j=0; j<3; j++) + { + real norm = 0; + for(unsigned int i=0; i<3; i++) + { + norm += M(i,j)*M(i,j); + } + if((norm > 1.01) || (norm < 0.99)) + return true; + } + + return false; +} diff --git a/source/blender/freestyle/intern/scene_graph/NodeTransform.h b/source/blender/freestyle/intern/scene_graph/NodeTransform.h new file mode 100755 index 00000000000..e75132466f0 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/NodeTransform.h @@ -0,0 +1,107 @@ +// +// Filename : NodeTransform.h +// Author(s) : Stephane Grabli +// Purpose : Class to represent a transform node. A Transform node +// contains one or several children, all affected by the +// transformation. +// Date of creation : 06/02/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NODETRANSFORM_H +# define NODETRANSFORM_H + +# include "../geometry/Geom.h" +# include "../system/FreestyleConfig.h" +# include "NodeGroup.h" + +using namespace Geometry; + +class LIB_SCENE_GRAPH_EXPORT NodeTransform : public NodeGroup +{ +public: + + inline NodeTransform() : NodeGroup() { + _Matrix = Matrix44r::identity(); + _Scaled=false; + } + + virtual ~NodeTransform() {} + + /*! multiplys the current matrix by the + * x, y, z translation matrix. + */ + void Translate(real x, real y, real z); + + /*! multiplys the current matrix by a + * rotation matrix + * iAngle + * The rotation angle + * x, y, z + * The rotation axis + */ + void Rotate(real iAngle, real x, real y, real z); + + /*! multiplys the current matrix by a + * scaling matrix. + * x, y, z + * The scaling coefficients + * with respect to the x,y,z axis + */ + void Scale(real x, real y, real z); + + /*! Multiplys the current matrix + * by iMatrix + */ + void MultiplyMatrix(const Matrix44r &iMatrix); + + /*! Sets the current matrix to iMatrix */ + void setMatrix(const Matrix44r &iMatrix); + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); + + /*! Overloads the Node::AddBBox in order to take care + * about the transformation + */ + virtual void AddBBox(const BBox<Vec3r>& iBBox); + + /*! Checks whether a matrix contains a scale factor + * or not. + * Returns true if yes. + * iMatrix + * The matrix to check + */ + bool isScaled(const Matrix44r &M); + + /*! accessors */ + inline const Matrix44r& matrix() const { return _Matrix; } + inline bool scaled() const {return _Scaled;} + +private: + Matrix44r _Matrix; + bool _Scaled; +}; + +#endif // NODETRANSFORM_H diff --git a/source/blender/freestyle/intern/scene_graph/OrientedLineRep.cpp b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.cpp new file mode 100755 index 00000000000..94068983596 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.cpp @@ -0,0 +1,31 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "OrientedLineRep.h" +#include "../system/BaseObject.h" + +void OrientedLineRep::accept(SceneVisitor& v) { + Rep::accept(v); + if(!frs_material()) + v.visitOrientedLineRep(*this); + else + v.visitLineRep(*this); +} diff --git a/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h new file mode 100755 index 00000000000..4274581e39a --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h @@ -0,0 +1,67 @@ +// +// Filename : OrientedLineRep.h +// Author(s) : Stephane Grabli +// Purpose : Class to display an oriented line representation. +// Date of creation : 24/10/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef VIEWEDGEREP_H +# define VIEWEDGEREP_H + +# include "../system/FreestyleConfig.h" +# include "LineRep.h" + +class LIB_SCENE_GRAPH_EXPORT OrientedLineRep : public LineRep +{ +public: + + OrientedLineRep() : LineRep() {} + /*! Builds a single line from 2 vertices + * v1 + * first vertex + * v2 + * second vertex + */ + inline OrientedLineRep(const Vec3r& v1, const Vec3r& v2) + : LineRep(v1,v2) + {} + + /*! Builds a line rep from a vertex chain */ + inline OrientedLineRep(const vector<Vec3r>& vertices) + : LineRep(vertices) + {} + + /*! Builds a line rep from a vertex chain */ + inline OrientedLineRep(const list<Vec3r>& vertices) + : LineRep(vertices) + {} + + virtual ~OrientedLineRep() {} + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); +}; + +#endif // VIEWEDGEREP_H diff --git a/source/blender/freestyle/intern/scene_graph/Rep.cpp b/source/blender/freestyle/intern/scene_graph/Rep.cpp new file mode 100755 index 00000000000..84ad2c2a966 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/Rep.cpp @@ -0,0 +1 @@ +#include "Rep.h" diff --git a/source/blender/freestyle/intern/scene_graph/Rep.h b/source/blender/freestyle/intern/scene_graph/Rep.h new file mode 100755 index 00000000000..6b213b01ba7 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/Rep.h @@ -0,0 +1,127 @@ +// +// Filename : Rep.h +// Author(s) : Stephane Grabli +// Purpose : Base class for all shapes. Inherits from BasicObjects +// for references counter management (addRef, release). +// Date of creation : 25/01/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef REP_H +# define REP_H + +# include "../system/BaseObject.h" +# include "SceneVisitor.h" +# include "../geometry/BBox.h" +# include "../geometry/Geom.h" +# include "../system/Precision.h" +# include "FrsMaterial.h" +# include "../system/Id.h" + +using namespace Geometry; + +class LIB_SCENE_GRAPH_EXPORT Rep : public BaseObject +{ +public: + + inline Rep() : BaseObject() {_Id = 0; _FrsMaterial=0;} + inline Rep(const Rep& iBrother) + : BaseObject() + { + _Id = iBrother._Id; + if(0 == iBrother._FrsMaterial) + _FrsMaterial = 0; + else + _FrsMaterial = new FrsMaterial(*(iBrother._FrsMaterial)); + + _BBox = iBrother.bbox(); + } + inline void swap(Rep& ioOther){ + std::swap(_BBox,ioOther._BBox); + std::swap(_Id, ioOther._Id); + std::swap(_FrsMaterial,ioOther._FrsMaterial); + } + Rep& operator=(const Rep& iBrother){ + if(&iBrother != this){ + _Id = iBrother._Id; + if(0 == iBrother._FrsMaterial) + _FrsMaterial = 0; + else{ + if(_FrsMaterial == 0){ + _FrsMaterial = new FrsMaterial(*iBrother._FrsMaterial); + }else{ + (*_FrsMaterial)=(*(iBrother._FrsMaterial)); + } + _BBox = iBrother.bbox(); + } + } + return *this; + } + virtual ~Rep() + { + if(0 != _FrsMaterial) + { + delete _FrsMaterial; + _FrsMaterial = 0; + } + } + + /*! Accept the corresponding visitor + * Must be overload by + * inherited classes + */ + virtual void accept(SceneVisitor& v) { + if(_FrsMaterial) + v.visitFrsMaterial(*_FrsMaterial); + v.visitRep(*this); + } + + /*! Computes the rep bounding box. + * Each Inherited rep must compute + * its bbox depending on the way the data + * are stored. So, each inherited class + * must overload this method + */ + virtual void ComputeBBox() = 0; + + /*! Returns the rep bounding box */ + virtual const BBox<Vec3r>& bbox() const {return _BBox;} + inline Id getId() const {return _Id;} + inline const FrsMaterial * frs_material() const {return _FrsMaterial;} + + /*! Sets the Rep bounding box */ + virtual void setBBox(const BBox<Vec3r>& iBox) {_BBox = iBox;} + inline void setId(const Id& id) {_Id = id;} + inline void setFrsMaterial(const FrsMaterial& iMaterial) + { + _FrsMaterial = new FrsMaterial(iMaterial); + } + +private: + BBox<Vec3r> _BBox; + Id _Id; + FrsMaterial *_FrsMaterial; +}; + +#endif // REP_H diff --git a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp new file mode 100755 index 00000000000..aeee87f8222 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp @@ -0,0 +1,86 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <iomanip> +#include "ScenePrettyPrinter.h" +#include "IndexedFaceSet.h" + +#define VISIT(CLASS) \ + void ScenePrettyPrinter::visit##CLASS(CLASS&) { \ + _ofs << _space << #CLASS << endl; \ + } + +VISIT(Node) +VISIT(NodeShape) +VISIT(NodeGroup) +VISIT(NodeLight) +VISIT(NodeDrawingStyle) +VISIT(NodeTransform) + +void ScenePrettyPrinter::visitNodeShapeBefore(NodeShape&) { + increaseSpace(); +} + +void ScenePrettyPrinter::visitNodeShapeAfter(NodeShape&) { + decreaseSpace(); +} + +void ScenePrettyPrinter::visitNodeGroupBefore(NodeGroup&) { + increaseSpace(); +} + +void ScenePrettyPrinter::visitNodeGroupAfter(NodeGroup&) { + decreaseSpace(); +} + +void ScenePrettyPrinter::visitNodeDrawingStyleBefore(NodeDrawingStyle&) { + increaseSpace(); +} + +void ScenePrettyPrinter::visitNodeDrawingStyleAfter(NodeDrawingStyle&) { + decreaseSpace(); +} + +void ScenePrettyPrinter::visitNodeTransformBefore(NodeTransform&) { + increaseSpace(); +} + +void ScenePrettyPrinter::visitNodeTransformAfter(NodeTransform&) { + decreaseSpace(); +} + +VISIT(LineRep) +VISIT(OrientedLineRep) +VISIT(TriangleRep) +VISIT(VertexRep) + +void ScenePrettyPrinter::visitIndexedFaceSet(IndexedFaceSet& ifs) { + const real* vertices = ifs.vertices(); + unsigned vsize = ifs.vsize(); + + _ofs << _space << "IndexedFaceSet" << endl; + const real *p = vertices; + for (unsigned i = 0; i < vsize / 3; i++) { + _ofs << _space << " " << setw(3) << setfill('0') << i << ": " + << p[0] << ", " << p[1] << ", " << p[2] << endl; + p += 3; + } +} diff --git a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h new file mode 100755 index 00000000000..4e83825ff55 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h @@ -0,0 +1,105 @@ +// +// Filename : ScenePrettyPrinter.h +// Author(s) : Stephane Grabli, Emmanuel Turquin +// Purpose : Class to display textual information +// about a scene graph. +// Date of creation : 26/04/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef SCENE_PRETTY_PRINTER_H +# define SCENE_PRETTY_PRINTER_H + +# include <iostream> +# include <fstream> +# include <string> +# include "SceneVisitor.h" + +using namespace std; + +class ScenePrettyPrinter : public SceneVisitor +{ +public: + + ScenePrettyPrinter(const string filename = "SceneLog.txt") + : SceneVisitor() { + if (!filename.empty()) + _ofs.open(filename.c_str()); + if (!_ofs.is_open()) + cerr << "Warning, unable to open file \"" << filename << "\"" << endl; + _space = ""; + } + + virtual ~ScenePrettyPrinter() { + if (_ofs.is_open()) + _ofs.close(); + } + + + // + // visitClass methods + // + ////////////////////////////////////////////// + + VISIT_DECL(Node) + VISIT_DECL(NodeShape) + VISIT_DECL(NodeGroup) + VISIT_DECL(NodeLight) + VISIT_DECL(NodeDrawingStyle) + VISIT_DECL(NodeTransform) + + VISIT_DECL(LineRep) + VISIT_DECL(OrientedLineRep) + VISIT_DECL(TriangleRep) + VISIT_DECL(VertexRep) + VISIT_DECL(IndexedFaceSet) + + virtual void visitNodeShapeBefore(NodeShape&); + virtual void visitNodeShapeAfter(NodeShape&); + virtual void visitNodeGroupBefore(NodeGroup&); + virtual void visitNodeGroupAfter(NodeGroup&); + virtual void visitNodeDrawingStyleBefore(NodeDrawingStyle&); + virtual void visitNodeDrawingStyleAfter(NodeDrawingStyle&); + virtual void visitNodeTransformBefore(NodeTransform&); + virtual void visitNodeTransformAfter(NodeTransform&); + + protected: + + void increaseSpace() + { + _space += " "; + } + + void decreaseSpace() + { + _space.erase(0, 2); + } + + private: + + ofstream _ofs; + string _space; +}; + +#endif // SCENE_PRETTY_PRINTER_H diff --git a/source/blender/freestyle/intern/scene_graph/SceneVisitor.cpp b/source/blender/freestyle/intern/scene_graph/SceneVisitor.cpp new file mode 100755 index 00000000000..da9c94930bd --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/SceneVisitor.cpp @@ -0,0 +1 @@ +#include "SceneVisitor.h" diff --git a/source/blender/freestyle/intern/scene_graph/SceneVisitor.h b/source/blender/freestyle/intern/scene_graph/SceneVisitor.h new file mode 100755 index 00000000000..5f67b4b44aa --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/SceneVisitor.h @@ -0,0 +1,98 @@ +// +// Filename : SceneVisitor.h +// Author(s) : Emmanuel Turquin +// Purpose : Class to visit (without doing anything) +// a scene graph structure +// Date of creation : 26/04/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef SCENE_VISITOR_H +# define SCENE_VISITOR_H + +# define VISIT_COMPLETE_DEF(type) \ +virtual void visit##type(type&) {} \ +virtual void visit##type##Before(type&) {} \ +virtual void visit##type##After(type&) {} + +# define VISIT_DECL(type) virtual void visit##type(type&); + +# define VISIT_COMPLETE_DECL(type) \ + virtual void visit##type##Before(type&); \ + virtual void visit##type(type&); \ + virtual void visit##type##After(type&); + +#include "../system/FreestyleConfig.h" + +class Node; +class NodeShape; +class NodeGroup; +class NodeLight; +class NodeCamera; +class NodeDrawingStyle; +class NodeTransform; + +class Rep; +class LineRep; +class OrientedLineRep; +class TriangleRep; +class VertexRep; +class IndexedFaceSet; +class DrawingStyle; +class FrsMaterial; + +class LIB_SCENE_GRAPH_EXPORT SceneVisitor +{ +public: + + SceneVisitor() {} + virtual ~SceneVisitor() {} + + virtual void beginScene() {} + virtual void endScene() {} + + // + // visitClass methods + // + ////////////////////////////////////////////// + + VISIT_COMPLETE_DEF(Node) + VISIT_COMPLETE_DEF(NodeShape) + VISIT_COMPLETE_DEF(NodeGroup) + VISIT_COMPLETE_DEF(NodeLight) + VISIT_COMPLETE_DEF(NodeCamera) + VISIT_COMPLETE_DEF(NodeDrawingStyle) + VISIT_COMPLETE_DEF(NodeTransform) + + VISIT_COMPLETE_DEF(Rep) + VISIT_COMPLETE_DEF(LineRep) + VISIT_COMPLETE_DEF(OrientedLineRep) + VISIT_COMPLETE_DEF(TriangleRep) + VISIT_COMPLETE_DEF(VertexRep) + VISIT_COMPLETE_DEF(IndexedFaceSet) + VISIT_COMPLETE_DEF(DrawingStyle) + VISIT_COMPLETE_DEF(FrsMaterial) +}; + +#endif // SCENEVISITOR_H diff --git a/source/blender/freestyle/intern/scene_graph/TriangleRep.cpp b/source/blender/freestyle/intern/scene_graph/TriangleRep.cpp new file mode 100755 index 00000000000..f73a8498714 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/TriangleRep.cpp @@ -0,0 +1,59 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "TriangleRep.h" + +void TriangleRep::ComputeBBox() +{ + real XMax = _vertices[0][0]; + real YMax = _vertices[0][1]; + real ZMax = _vertices[0][2]; + + real XMin = _vertices[0][0]; + real YMin = _vertices[0][1]; + real ZMin = _vertices[0][2]; + + // parse all the coordinates to find + // the XMax, YMax, ZMax + for(int i=0; i<3; ++i) + { + // X + if(_vertices[i][0] > XMax) + XMax = _vertices[i][0]; + if(_vertices[i][0] < XMin) + XMin = _vertices[i][0]; + + // Y + if(_vertices[i][1] > YMax) + YMax = _vertices[i][1]; + if(_vertices[i][1] < YMin) + YMin = _vertices[i][1]; + + // Z + if(_vertices[i][2] > ZMax) + ZMax = _vertices[i][2]; + if(_vertices[i][2] < ZMin) + ZMin = _vertices[i][2]; + + } + + setBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax))); +} diff --git a/source/blender/freestyle/intern/scene_graph/TriangleRep.h b/source/blender/freestyle/intern/scene_graph/TriangleRep.h new file mode 100755 index 00000000000..9d986857060 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/TriangleRep.h @@ -0,0 +1,106 @@ +// +// Filename : TriangleRep.h +// Author(s) : Stephane Grabli +// Purpose : Class to define the represenation of a triangle +// Date of creation : 16/12/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef TRIANGLEREP_H +# define TRIANGLEREP_H + +//! inherits from class Rep +#include "Rep.h" + +/*! Base class for all lines objects */ +class LIB_SCENE_GRAPH_EXPORT TriangleRep : public Rep +{ +public: + + /*! Line description style */ + enum TRIANGLE_STYLE{FILL, LINES}; +private: + TRIANGLE_STYLE _Style; + Vec3r _vertices[3]; + Vec3r _colors[3]; +public: + inline TriangleRep() : Rep() {_Style = FILL;} + + /*! Builds a triangle from 3 vertices + * v0 + * first vertex + * v1 + * second vertex + * v2 + * third vertex + */ + inline TriangleRep(const Vec3r& v0, const Vec3r& v1, const Vec3r& v2) + : Rep() + { + _vertices[0] = v0; + _vertices[1] = v1; + _vertices[2] = v2; + _Style = FILL; + } + inline TriangleRep( const Vec3r& v0, const Vec3r& c0, + const Vec3r& v1, const Vec3r& c1, + const Vec3r& v2, const Vec3r& c2) + : Rep() + { + _vertices[0] = v0; + _vertices[1] = v1; + _vertices[2] = v2; + _colors[0] = c0; + _colors[1] = c1; + _colors[2] = c2; + _Style = FILL; + } + + virtual ~TriangleRep() + {} + + /*! accessors */ + inline const TRIANGLE_STYLE style() const {return _Style;} + inline const Vec3r& vertex(int index) const {return _vertices[index];} + inline const Vec3r& color(int index) const {return _colors[index];} + /*! modifiers */ + inline void setStyle(const TRIANGLE_STYLE iStyle) {_Style = iStyle;} + inline void setVertex(int index, const Vec3r& iVertex) {_vertices[index] = iVertex;} + inline void setColor(int index, const Vec3r& iColor) {_colors[index] = iColor;} + inline void setVertices(const Vec3r& v0, const Vec3r& v1, const Vec3r& v2) {_vertices[0] = v0; _vertices[1] = v1; _vertices[2] = v2;} + inline void setColors(const Vec3r& c0, const Vec3r& c1, const Vec3r& c2) {_colors[0] = c0; _colors[1] = c1; _colors[2] = c2;} + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v) { + Rep::accept(v); + v.visitTriangleRep(*this); + } + + /*! Computes the triangle bounding box.*/ + virtual void ComputeBBox(); + + +}; + +#endif diff --git a/source/blender/freestyle/intern/scene_graph/VertexRep.cpp b/source/blender/freestyle/intern/scene_graph/VertexRep.cpp new file mode 100755 index 00000000000..e4f774bfb84 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/VertexRep.cpp @@ -0,0 +1,29 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "VertexRep.h" + +void VertexRep::ComputeBBox() +{ + + setBBox(BBox<Vec3r>(Vec3r(_coordinates[0], _coordinates[1], _coordinates[2]), + Vec3r(_coordinates[0], _coordinates[1], _coordinates[2]))); +} diff --git a/source/blender/freestyle/intern/scene_graph/VertexRep.h b/source/blender/freestyle/intern/scene_graph/VertexRep.h new file mode 100755 index 00000000000..9e31b4b8ef9 --- /dev/null +++ b/source/blender/freestyle/intern/scene_graph/VertexRep.h @@ -0,0 +1,87 @@ +// +// Filename : VertexRep.h +// Author(s) : Stephane Grabli +// Purpose : Class to define the representation of a vertex for +// displaying purpose. +// Date of creation : 03/04/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef VERTEXREP_H +# define VERTEXREP_H + +#include "Rep.h" + +class LIB_SCENE_GRAPH_EXPORT VertexRep : public Rep +{ +public: + + inline VertexRep() : Rep() {_vid = 0;_PointSize = 0.f;} + inline VertexRep(real x, real y, real z, int id = 0) + : Rep() + { + _coordinates[0] = x; + _coordinates[1] = y; + _coordinates[2] = z; + + _vid = id; + _PointSize = 0.f; + } + + inline ~VertexRep() {} + + /*! Accept the corresponding visitor */ + + virtual void accept(SceneVisitor& v) { + Rep::accept(v); + v.visitVertexRep(*this); + } + + /*! Computes the rep bounding box. + */ + virtual void ComputeBBox(); + + /*! accessors */ + inline const int vid() const {return _vid;} + inline const real * coordinates() const {return _coordinates;} + inline real x() const {return _coordinates[0];} + inline real y() const {return _coordinates[1];} + inline real z() const {return _coordinates[2];} + inline float pointSize() const {return _PointSize;} + + /*! modifiers */ + inline void setVid(int id) {_vid = id;} + inline void setX(real x) {_coordinates[0] = x;} + inline void setY(real y) {_coordinates[1] = y;} + inline void setZ(real z) {_coordinates[2] = z;} + inline void setCoordinates(real x, real y, real z) {_coordinates[0] = x;_coordinates[1] = y; _coordinates[2] = z;} + inline void setPointSize(float iPointSize) {_PointSize = iPointSize;} + +private: + int _vid; // vertex id + real _coordinates[3]; + float _PointSize; +}; + +#endif // VERTEXREP_H diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp new file mode 100755 index 00000000000..7a51a1a78df --- /dev/null +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp @@ -0,0 +1,92 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +# include "../view_map/Functions0D.h" +# include "AdvancedFunctions0D.h" +# include "../view_map/SteerableViewMap.h" +# include "Canvas.h" + +namespace Functions0D { + + int DensityF0D::operator()(Interface0DIterator& iter) { + Canvas* canvas = Canvas::getInstance(); + int bound = _filter.getBound(); + if( (iter->getProjectedX()-bound < 0) || (iter->getProjectedX()+bound>canvas->width()) + || (iter->getProjectedY()-bound < 0) || (iter->getProjectedY()+bound>canvas->height())) { + result = 0.0; + return 0; + } + RGBImage image; + canvas->readColorPixels((int)iter->getProjectedX() - bound, + (int)iter->getProjectedY() - bound, + _filter.maskSize(), + _filter.maskSize(), + image); + result = _filter.getSmoothedPixel<RGBImage>(&image, (int)iter->getProjectedX(), + (int)iter->getProjectedY()); + return 0; + } + + + int LocalAverageDepthF0D::operator()(Interface0DIterator& iter) { + Canvas * iViewer = Canvas::getInstance(); + int bound = _filter.getBound(); + + if( (iter->getProjectedX()-bound < 0) || (iter->getProjectedX()+bound>iViewer->width()) + || (iter->getProjectedY()-bound < 0) || (iter->getProjectedY()+bound>iViewer->height())) { + result = 0.0; + return 0; + } + GrayImage image ; + iViewer->readDepthPixels((int)iter->getProjectedX()-bound,(int)iter->getProjectedY()-bound,_filter.maskSize(),_filter.maskSize(),image); + result = _filter.getSmoothedPixel(&image, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; + } + + int ReadMapPixelF0D::operator()(Interface0DIterator& iter) { + Canvas * canvas = Canvas::getInstance(); + result = canvas->readMapPixel(_mapName, _level, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; + } + + int ReadSteerableViewMapPixelF0D::operator()(Interface0DIterator& iter) { + SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); + result = svm->readSteerableViewMapPixel(_orientation, _level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; + } + + int ReadCompleteViewMapPixelF0D::operator()(Interface0DIterator& iter) { + SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); + result = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; + } + + int GetViewMapGradientNormF0D::operator()(Interface0DIterator& iter){ + SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); + float pxy = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); + float gx = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX()+_step, (int)iter->getProjectedY()) + - pxy; + float gy = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()+_step) + - pxy; + result = Vec2f(gx,gy).norm(); + return 0; + } +} // end of namespace Functions0D diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h new file mode 100755 index 00000000000..5d62ea8d9eb --- /dev/null +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h @@ -0,0 +1,209 @@ +// +// Filename : AdvancedFunctions0D.h +// Author(s) : Stephane Grabli +// Emmanuel Turquin +// Purpose : Functions taking 0D input +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef ADVANCED_FUNCTIONS0D_HPP +# define ADVANCED_FUNCTIONS0D_HPP + + +# include "../image/Image.h" +# include "../image/GaussianFilter.h" +# include "../view_map/Functions0D.h" + +// +// Functions definitions +// +/////////////////////////////////////////////////////////// + +namespace Functions0D { + + // DensityF0D + /*! Returns the density of the (result) image evaluated at an Interface0D. + * This density is evaluated using a pixels square window around the + * evaluation point and integrating these values using + * a gaussian. + */ + class LIB_STROKE_EXPORT DensityF0D : public UnaryFunction0D<double> + { + public: + /*! Builds the functor from the gaussian sigma value. + * \param sigma + * sigma indicates the x value for which the gaussian + * function is 0.5. It leads to the window size + * value. (the larger, the smoother) + */ + DensityF0D(double sigma = 2) : UnaryFunction0D<double>() { + _filter.setSigma((float)sigma); + } + /*! Returns the string "DensityF0D"*/ + string getName() const { + return "DensityF0D"; + } + /*! The () operator. */ + int operator()(Interface0DIterator& iter); + + private: + + GaussianFilter _filter; + }; + + // LocalAverageDepthF0D + /*! Returns the average depth around a point. + * The result is obtained by querying the + * depth buffer on a window around that point. + */ + class LIB_STROKE_EXPORT LocalAverageDepthF0D : public UnaryFunction0D<double> + { + private: + GaussianFilter _filter; + public: + /*! Builds the functor from the size of the mask that + * will be used. + */ + LocalAverageDepthF0D(real maskSize=5.f) : UnaryFunction0D<double>() { + _filter.setSigma((float)maskSize/2.f); + } + /*! Returns the string "LocalAverageDepthF0D"*/ + string getName() const { + return "LocalAverageDepthF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // ReadMapPixel + /*! Reads a pixel in a map. + */ + class LIB_STROKE_EXPORT ReadMapPixelF0D : public UnaryFunction0D<float> + { + private: + const char * _mapName; + int _level; + public: + /*! Builds the functor from name of the + * Map that must be read. + * \param iMapName + * The name of the map. + * \param level + * The level of the pyramid from which + * the pixel must be read. + */ + ReadMapPixelF0D(const char *iMapName, int level) : UnaryFunction0D<float>() { + _mapName = iMapName; + _level = level; + } + /*! Returns the string "ReadMapPixelF0D"*/ + string getName() const { + return "ReadMapPixelF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // ReadSteerableViewMapPixel + /*! Reads a pixel in one of the level of one of the steerable viewmaps. + */ + class LIB_STROKE_EXPORT ReadSteerableViewMapPixelF0D : public UnaryFunction0D<float> + { + private: + unsigned _orientation; + int _level; + public: + /*! Builds the functor + * \param nOrientation + * The integer belonging to [0,4] indicating the orientation (E,NE,N,NW) + * we are interested in. + * \param level + * The level of the pyramid from which + * the pixel must be read. + */ + ReadSteerableViewMapPixelF0D(unsigned nOrientation, int level) : UnaryFunction0D<float>() { + _orientation = nOrientation; + _level = level; + } + /*! Returns the string "ReadSteerableViewMapPixelF0D"*/ + string getName() const { + return "ReadSteerableViewMapPixelF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // ReadCompleteViewMapPixel + /*! Reads a pixel in one of the level of the complete viewmap. + */ + class LIB_STROKE_EXPORT ReadCompleteViewMapPixelF0D : public UnaryFunction0D<float> + { + private: + int _level; + public: + /*! Builds the functor + * \param level + * The level of the pyramid from which + * the pixel must be read. + */ + ReadCompleteViewMapPixelF0D(int level) : UnaryFunction0D<float>() { + _level = level; + } + /*! Returns the string "ReadCompleteViewMapPixelF0D"*/ + string getName() const { + return "ReadCompleteViewMapPixelF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // GetViewMapGradientNormF0D + /*! Returns the norm of the gradient of the global viewmap density image. + */ + class LIB_STROKE_EXPORT GetViewMapGradientNormF0D: public UnaryFunction0D< float> + { + private: + int _level; + float _step; + public: + /*! Builds the functor + * \param level + * The level of the pyramid from which + * the pixel must be read. + */ + GetViewMapGradientNormF0D(int level) : UnaryFunction0D<float>() { + _level = level; + _step = (float)pow(2.0,_level); + } + /*! Returns the string "GetOccludeeF0D"*/ + string getName() const { + return "GetViewMapGradientNormF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; +} // end of namespace Functions0D + +#endif // ADVANCED_FUNCTIONS0D_HPP diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp new file mode 100755 index 00000000000..2548ce38659 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp @@ -0,0 +1,110 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +# include "AdvancedFunctions1D.h" +# include "../view_map/SteerableViewMap.h" +# include "Canvas.h" + +// FIXME +namespace Functions1D { + + int GetSteerableViewMapDensityF1D::operator()(Interface1D& inter) { + SteerableViewMap * svm = Canvas::getInstance()->getSteerableViewMap(); + Interface0DIterator it = inter.pointsBegin(_sampling); + Interface0DIterator itnext = it;++itnext; + FEdge *fe; + unsigned nSVM; + vector<float> values; + while(!itnext.isEnd()){ + Interface0D& i0D = (*it); + Interface0D& i0Dnext = (*itnext); + fe = i0D.getFEdge(i0Dnext); + if(fe == 0){ + cerr << "GetSteerableViewMapDensityF1D warning: no FEdge between " << i0D.getId() << " and " << i0Dnext.getId() << endl; + // compute the direction between these two ??? + Vec2f dir = i0Dnext.getPoint2D()-i0D.getPoint2D(); + nSVM = svm->getSVMNumber(dir); + }else{ + nSVM = svm->getSVMNumber(fe->getId().getFirst()); + } + Vec2r m((i0D.getProjectedX()+i0Dnext.getProjectedX())/2.0, + (i0D.getProjectedY()+i0Dnext.getProjectedY())/2.0); + values.push_back(svm->readSteerableViewMapPixel(nSVM,_level,(int)m[0],(int)m[1])); + ++it;++itnext; + } + float res, res_tmp; + vector<float>::iterator v = values.begin(), vend=values.end(); + unsigned size = 1; + switch(_integration) { + case MIN: + res = *v;++v; + for (; v!=vend; ++v) { + res_tmp = *v; + if (res_tmp < res) + res = res_tmp; + } + break; + case MAX: + res = *v;++v; + for (; v!=vend; ++v) { + res_tmp = *v; + if (res_tmp > res) + res = res_tmp; + } + break; + case FIRST: + res = *v; + break; + case LAST: + --vend; + res = *vend; + break; + case MEAN: + default: + res = *v;++v; + for (; v!=vend; ++v, ++size) + res += *v; + res /= (size ? size : 1); + break; + } + result = res; + return 0; + } + + int GetDirectionalViewMapDensityF1D::operator()(Interface1D& inter) { + //soc unsigned size; + result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; + } + + int GetCompleteViewMapDensityF1D::operator()(Interface1D& inter) { + //soc unsigned size; + Id id = inter.getId(); + result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; + } + + int GetViewMapGradientNormF1D::operator()(Interface1D& inter){ + result = integrate(_func, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; + } +} + diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h new file mode 100755 index 00000000000..46a28c20917 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h @@ -0,0 +1,288 @@ +// +// Filename : AdvancedFunctions1D.h +// Author(s) : Stephane Grabli, Emmanuel Turquin +// Purpose : Functions taking 1D input +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef ADVANCED_FUNCTIONS1D_HPP +# define ADVANCED_FUNCTIONS1D_HPP + + +# include "AdvancedFunctions0D.h" +# include "../view_map/Functions1D.h" + +// +// Functions definitions +// +/////////////////////////////////////////////////////////// + +namespace Functions1D { + + // DensityF1D + /*! Returns the density evaluated for an Interface1D. + * The density is evaluated for a set of points along + * the Interface1D (using the DensityF0D functor) + * with a user-defined sampling and + * then integrated into a single value using + * a user-defined integration method. + */ + class DensityF1D : public UnaryFunction1D<double> + { + private: + float _sampling; + public: + /*! Builds the functor. + * \param sigma + * Thesigma used in DensityF0D and determining + * the window size used in each density query. + * \param iType + * The integration method used to compute + * a single value from a set of values. + * \param sampling + * The resolution used to sample the chain: the corresponding 0D function + * is evaluated at each sample point and the result is obtained by + * combining the resulting values into a single one, following the + * method specified by iType. + */ + DensityF1D(double sigma = 2, IntegrationType iType = MEAN, float sampling=2.f) : UnaryFunction1D<double>(iType), _fun(sigma) { + _sampling = sampling; + } + /*! Destructor */ + virtual ~DensityF1D(){} + + /*! Returns the string "DensityF1D"*/ + string getName() const { + return "DensityF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter) { + result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; + } + private: + Functions0D::DensityF0D _fun; + }; + + // LocalAverageDepthF1D + /*! Returns the average depth evaluated for an Interface1D. + * The average depth is evaluated for a set of points along + * the Interface1D (using the LocalAverageDepthF0D functor) + * with a user-defined sampling and + * then integrated into a single value using + * a user-defined integration method. + */ + class LocalAverageDepthF1D : public UnaryFunction1D<double> + { + public: + /*! Builds the functor. + * \param sigma + * The sigma used in DensityF0D and determining + * the window size used in each density query. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + LocalAverageDepthF1D(real sigma, IntegrationType iType = MEAN) + : UnaryFunction1D<double>(iType), _fun(sigma){ + } + /*! Returns the string "LocalAverageDepthF1D"*/ + string getName() const { + return "LocalAverageDepthF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter) { + result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + private: + Functions0D::LocalAverageDepthF0D _fun; + }; + + // GetCompleteViewMapDensity + /*! Returns the density evaluated for an Interface1D in the + * complete viewmap image. + * The density is evaluated for a set of points along + * the Interface1D (using the ReadCompleteViewMapPixelF0D functor) + * and then integrated into a single value using + * a user-defined integration method. + */ + class LIB_STROKE_EXPORT GetCompleteViewMapDensityF1D : public UnaryFunction1D<double> + { + public: + /*! Builds the functor. + * \param level + * The level of the pyramid from which + * the pixel must be read. + * \param iType + * The integration method used to compute + * a single value from a set of values. + * \param sampling + * The resolution used to sample the chain: the corresponding 0D function + * is evaluated at each sample point and the result is obtained by + * combining the resulting values into a single one, following the + * method specified by iType. + */ + GetCompleteViewMapDensityF1D(unsigned level, IntegrationType iType = MEAN, float sampling=2.f) + : UnaryFunction1D<double>(iType), _fun(level){_sampling = sampling;} + /*! Returns the string "GetCompleteViewMapDensityF1D"*/ + string getName() const { + return "GetCompleteViewMapDensityF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + + private: + Functions0D::ReadCompleteViewMapPixelF0D _fun; + float _sampling; + }; + + // GetDirectionalViewMapDensity + /*! Returns the density evaluated for an Interface1D in of the + * steerable viewmaps image. + * The direction telling which Directional map to choose + * is explicitely specified by the user. + * The density is evaluated for a set of points along + * the Interface1D (using the ReadSteerableViewMapPixelF0D functor) + * and then integrated into a single value using + * a user-defined integration method. + */ + class LIB_STROKE_EXPORT GetDirectionalViewMapDensityF1D : public UnaryFunction1D<double> + { + public: + /*! Builds the functor. + * \param iOrientation + * The number of the directional map + * we must work with. + * \param level + * The level of the pyramid from which + * the pixel must be read. + * \param iType + * The integration method used to compute + * a single value from a set of values. + * \param sampling + * The resolution used to sample the chain: the corresponding 0D function + * is evaluated at each sample point and the result is obtained by + * combining the resulting values into a single one, following the + * method specified by iType. + */ + GetDirectionalViewMapDensityF1D(unsigned iOrientation, unsigned level, IntegrationType iType = MEAN, float sampling=2.f) + : UnaryFunction1D<double>(iType), _fun(iOrientation,level){_sampling = sampling;} + /*! Returns the string "GetDirectionalViewMapDensityF1D"*/ + string getName() const { + return "GetDirectionalViewMapDensityF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + + private: + Functions0D::ReadSteerableViewMapPixelF0D _fun; + float _sampling; + }; + + // GetSteerableViewMapDensityF1D + /*! Returns the density of the viewmap + * for a given Interface1D. The density of each + * FEdge is evaluated in the proper steerable + * ViewMap depending on its oorientation. + */ + class LIB_STROKE_EXPORT GetSteerableViewMapDensityF1D : public UnaryFunction1D<real> + { + private: + int _level; + float _sampling; + public: + /*! Builds the functor from the level + * of the pyramid from which the pixel must be read. + * \param level + * The level of the pyramid from which + * the pixel must be read. + * \param iType + * The integration method used to compute + * a single value from a set of values. + * \param sampling + * The resolution used to sample the chain: the corresponding 0D function + * is evaluated at each sample point and the result is obtained by + * combining the resulting values into a single one, following the + * method specified by iType. + */ + GetSteerableViewMapDensityF1D(int level,IntegrationType iType = MEAN, float sampling=2.f) : UnaryFunction1D<real>(iType) { + _level = level; + _sampling = sampling; + } + /*! Destructor */ + virtual ~GetSteerableViewMapDensityF1D(){} + + /*! Returns the string "GetSteerableViewMapDensityF1D"*/ + string getName() const { + return "GetSteerableViewMapDensityF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // GetViewMapGradientNormF1D + /*! Returns the density of the viewmap + * for a given Interface1D. The density of each + * FEdge is evaluated in the proper steerable + * ViewMap depending on its oorientation. + */ + class LIB_STROKE_EXPORT GetViewMapGradientNormF1D : public UnaryFunction1D<real> + { + private: + int _level; + float _sampling; + Functions0D::GetViewMapGradientNormF0D _func; + public: + /*! Builds the functor from the level + * of the pyramid from which the pixel must be read. + * \param level + * The level of the pyramid from which + * the pixel must be read. + * \param iType + * The integration method used to compute + * a single value from a set of values. + * \param sampling + * The resolution used to sample the chain: the corresponding 0D function + * is evaluated at each sample point and the result is obtained by + * combining the resulting values into a single one, following the + * method specified by iType. + */ + GetViewMapGradientNormF1D(int level,IntegrationType iType = MEAN, float sampling=2.f) + : UnaryFunction1D<real>(iType), _func(level) { + _level = level; + _sampling = sampling; + } + + /*! Returns the string "GetSteerableViewMapDensityF1D"*/ + string getName() const { + return "GetViewMapGradientNormF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; +} // end of namespace Functions1D + +#endif // ADVANCED_FUNCTIONS1D_HPP diff --git a/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h b/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h new file mode 100755 index 00000000000..91b63168aa9 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h @@ -0,0 +1,84 @@ +// +// Filename : AdvancedPredicates1D.h +// Author(s) : Stephane Grabli +// Purpose : Class gathering stroke creation algorithms +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef ADVANCED_PREDICATES1D_H +# define ADVANCED_PREDICATES1D_H + +# include <string> +# include "../view_map/Interface1D.h" +# include "AdvancedFunctions1D.h" +# include "Predicates1D.h" + +// +// Predicates definitions +// +/////////////////////////////////////////////////////////// + +namespace Predicates1D { + + // DensityLowerThanUP1D + /*! Returns true if the density evaluated for the + * Interface1D is less than a user-defined density value. + */ + class DensityLowerThanUP1D : public UnaryPredicate1D + { + public: + /*! Builds the functor. + * \param threshold + * The value of the threshold density. + * Any Interface1D having a density lower than + * this threshold will match. + * \param sigma + * The sigma value defining the density evaluation window size + * used in the DensityF0D functor. + */ + DensityLowerThanUP1D(double threshold, double sigma = 2) { + _threshold = threshold; + _sigma = sigma; + } + /*! Returns the string "DensityLowerThanUP1D"*/ + string getName() const { + return "DensityLowerThanUP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& inter) { + Functions1D::DensityF1D fun(_sigma); + if (fun(inter) < 0) + return -1; + result = (fun.result < _threshold); + return 0; + } + private: + double _sigma; + double _threshold; + }; + +} // end of namespace Predicates1D + +#endif // ADVANCED_PREDICATES1D_H diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp new file mode 100755 index 00000000000..2075f7ca6ad --- /dev/null +++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp @@ -0,0 +1,431 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "../system/PseudoNoise.h" +#include "../system/RandGen.h" +#include "AdvancedStrokeShaders.h" +#include "StrokeIterators.h" + +///////////////////////////////////////// +// +// CALLIGRAPHICS SHADER +// +///////////////////////////////////////// + + +CalligraphicShader::CalligraphicShader (real iMinThickness, real iMaxThickness, + const Vec2f &iOrientation, bool clamp) + : StrokeShader() +{ + _minThickness=iMinThickness; + _maxThickness=iMaxThickness; + _orientation = iOrientation; + _orientation.normalize(); + _clamp = clamp; +} + +float ksinToto=0; + +int +CalligraphicShader::shade(Stroke &ioStroke) const +{ + Interface0DIterator v; + Functions0D::VertexOrientation2DF0D fun; + StrokeVertex* sv; + for(v=ioStroke.verticesBegin(); + !v.isEnd(); + ++v) + { + real thickness; + if (fun(v) < 0) + return -1; + Vec2f vertexOri(fun.result); + Vec2r ori2d(-vertexOri[1], vertexOri[0]); + ori2d.normalizeSafe(); + real scal = ori2d * _orientation; + sv = dynamic_cast<StrokeVertex*>(&(*v)); + if (_clamp && (scal<0)) { + scal=0.0; + sv->attribute().setColor(1,1,1); + } + else { + scal=fabs(scal); + sv->attribute().setColor(0,0,0); + } + thickness=_minThickness+scal*(_maxThickness-_minThickness); + if (thickness<0.0) + thickness=0.0; + sv->attribute().setThickness(thickness/2.0,thickness/2.0); + } + + return 0; +} + +//void +//TipRemoverShader::shade(Stroke &ioStroke) const +//{ +// +// StrokeInternal::StrokeVertexIterator v, vend; +// for(v=ioStroke.strokeVerticesBegin(), vend=ioStroke.strokeVerticesEnd(); +// v!=vend; +// ++v) +// { +// if (((*v)->curvilinearAbscissa()<_tipLength) || +// ((*v)->strokeLength()-(*v)->curvilinearAbscissa()<_tipLength)) +// { +// (*v)->attribute().setThickness(0.0, 0.0); +// (*v)->attribute().setColor(1,1,1); +// } +// } +// +//} + + + +///////////////////////////////////////// +// +// SPATIAL NOISE SHADER +// +///////////////////////////////////////// + +static const unsigned NB_VALUE_NOISE = 512; + +SpatialNoiseShader::SpatialNoiseShader (float ioamount, float ixScale, int nbOctave, + bool smooth, bool pureRandom) + : StrokeShader() +{ + _amount = ioamount; + if (ixScale==0) _xScale=0; + else _xScale=1.0/ixScale/real(NB_VALUE_NOISE); + _nbOctave=nbOctave; + _smooth=smooth; + _pureRandom=pureRandom; +} +int +SpatialNoiseShader::shade(Stroke &ioStroke) const +{ + Interface0DIterator v, v2; + v=ioStroke.verticesBegin(); + Vec2r p(v->getProjectedX(), v->getProjectedY()); + v2=v; ++v2; + Vec2r p0(v2->getProjectedX(), v2->getProjectedY()); + p0=p+2*(p-p0); + StrokeVertex* sv; + sv = dynamic_cast<StrokeVertex*>(&(*v)); + real initU = sv->strokeLength()*real(NB_VALUE_NOISE); + if (_pureRandom) initU+=RandGen::drand48()*real(NB_VALUE_NOISE); + + Functions0D::VertexOrientation2DF0D fun; + while (!v.isEnd()) + { + sv = dynamic_cast<StrokeVertex*>(&(*v)); + Vec2r p(sv->getPoint()); + if (fun(v) < 0) + return -1; + Vec2r vertexOri(fun.result); + Vec2r ori2d(vertexOri[0], vertexOri[1]); + ori2d = Vec2r(p-p0); + ori2d.normalizeSafe(); + + PseudoNoise mynoise; + real bruit; + + if (_smooth) + bruit=mynoise.turbulenceSmooth(_xScale*sv->curvilinearAbscissa()+initU, + _nbOctave); + else + bruit=mynoise.turbulenceLinear(_xScale*sv->curvilinearAbscissa()+initU, + _nbOctave); + + Vec2r noise(-ori2d[1]*_amount*bruit, + ori2d[0]*_amount*bruit); + + sv->setPoint(p[0]+noise[0], p[1]+noise[1]); + p0=p; + + ++v; + } + + return 0; +} + + + +///////////////////////////////////////// +// +// SMOOTHING SHADER +// +///////////////////////////////////////// + + +SmoothingShader::SmoothingShader (int ionbIteration, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, + real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real iCarricatureFactor) + : StrokeShader() +{ + _nbIterations=ionbIteration; + _factorCurvature=ifactorCurvature; + _factorCurvatureDifference=iFactorCurvatureDifference; + _anisoNormal=iAnisoNormal; + _anisoCurvature=iAnisoCurvature; + _carricatureFactor=iCarricatureFactor; + _factorPoint=iFactorPoint; + _anisoPoint=iAnisoPoint; +} + + + +int +SmoothingShader::shade(Stroke &ioStroke) const +{ + //cerr<<" Smoothing a stroke "<<endl; + + Smoother smoother(ioStroke); + smoother.smooth(_nbIterations, _factorPoint, _factorCurvature, _factorCurvatureDifference, + _anisoPoint, _anisoNormal, _anisoCurvature, _carricatureFactor); + return 0; +} + +// SMOOTHER +//////////////////////////// + +Smoother::Smoother(Stroke &ioStroke) +{ + _stroke=&ioStroke; + + _nbVertices=ioStroke.vertices_size(); + _vertex=new Vec2r[_nbVertices]; + _curvature=new real[_nbVertices]; + _normal=new Vec2r[_nbVertices]; + StrokeInternal::StrokeVertexIterator v, vend; + int i=0; + for(v = ioStroke.strokeVerticesBegin(), vend = ioStroke.strokeVerticesEnd(); + v != vend; + ++v) + { + _vertex[i]=(v)->getPoint(); + i++; + } + Vec2r vec_tmp(_vertex[0]-_vertex[_nbVertices-1]); + _isClosedCurve = (vec_tmp.norm() < M_EPSILON); + + _safeTest=(_nbVertices>4); +} + +void Smoother::smooth(int nbIteration, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, + real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real iCarricatureFactor) +{ + _factorCurvature=ifactorCurvature; + _factorCurvatureDifference=iFactorCurvatureDifference; + _anisoNormal=iAnisoNormal; + _anisoCurvature=iAnisoCurvature; + _carricatureFactor=iCarricatureFactor; + _factorPoint=iFactorPoint; + _anisoPoint=iAnisoPoint; + + for (int i=0; i<nbIteration; i++) + iteration (); + copyVertices(); +} + +real edgeStopping (real x, real sigma) +{ + if (sigma==0.0) return 1.0; + return exp(-x*x/(sigma*sigma)); +} + +void +Smoother::iteration () +{ + computeCurvature(); + for (int i=1; i<_nbVertices-1; i++) + { + real motionNormal=_factorCurvature*_curvature[i]* + edgeStopping(_curvature[i], _anisoNormal); + + real diffC1=_curvature[i]-_curvature[i-1]; + real diffC2=_curvature[i]-_curvature[i+1]; + real motionCurvature=edgeStopping(diffC1, _anisoCurvature)*diffC1 + + edgeStopping(diffC2, _anisoCurvature)*diffC2;//_factorCurvatureDifference; + motionCurvature*=_factorCurvatureDifference; + //motionCurvature=_factorCurvatureDifference*(diffC1+diffC2); + if (_safeTest) + _vertex[i]=Vec2r(_vertex[i]+(motionNormal+motionCurvature)*_normal[i]); + Vec2r v1(_vertex[i-1]-_vertex[i]); + Vec2r v2(_vertex[i+1]-_vertex[i]); + real d1 = v1.norm(); + real d2 = v2.norm(); + _vertex[i]=Vec2r(_vertex[i]+ + _factorPoint*edgeStopping(d2, _anisoPoint)*(_vertex[i-1]-_vertex[i]) + + _factorPoint*edgeStopping(d1, _anisoPoint)*(_vertex[i+1]-_vertex[i]) ); + } + + if (_isClosedCurve) + { + real motionNormal=_factorCurvature*_curvature[0]* + edgeStopping(_curvature[0], _anisoNormal); + + real diffC1=_curvature[0]-_curvature[_nbVertices-2]; + real diffC2=_curvature[0]-_curvature[1]; + real motionCurvature=edgeStopping(diffC1, _anisoCurvature)*diffC1 + + edgeStopping(diffC2, _anisoCurvature)*diffC2;//_factorCurvatureDifference; + motionCurvature*=_factorCurvatureDifference; + //motionCurvature=_factorCurvatureDifference*(diffC1+diffC2); + _vertex[0]=Vec2r(_vertex[0]+(motionNormal+motionCurvature)*_normal[0]); + _vertex[_nbVertices-1]=_vertex[0]; + } +} + + +void +Smoother::computeCurvature () +{ + int i; + Vec2r BA, BC, normalCurvature; + for (i = 1; i < _nbVertices - 1; i++) + { + BA=_vertex[i-1]-_vertex[i]; + BC=_vertex[i+1]-_vertex[i]; + real lba=BA.norm(), lbc=BC.norm(); + BA.normalizeSafe(); + BC.normalizeSafe(); + normalCurvature = BA + BC; + + _normal[i]=Vec2r(-(BC-BA)[1], (BC-BA)[0]); + _normal[i].normalizeSafe(); + + _curvature[i] = normalCurvature * _normal[i]; + if (lba+lbc > M_EPSILON) + _curvature[i]/=(0.5*lba+lbc); + } + _curvature[0]=_curvature[1]; + _curvature[_nbVertices-1]=_curvature[_nbVertices-2]; + Vec2r di(_vertex[1]-_vertex[0]); + _normal[0] = Vec2r(-di[1], di[0]); + _normal[0].normalizeSafe(); + di=_vertex[_nbVertices-1]-_vertex[_nbVertices-2]; + _normal[_nbVertices-1]=Vec2r(-di[1], di[0]); + _normal[_nbVertices-1].normalizeSafe(); + + if (_isClosedCurve) + { + BA=_vertex[_nbVertices-2]-_vertex[0]; + BC=_vertex[1]-_vertex[0]; + real lba=BA.norm(), lbc=BC.norm(); + BA.normalizeSafe(); + BC.normalizeSafe(); + normalCurvature = BA + BC; + + _normal[i]=Vec2r(-(BC-BA)[1], (BC-BA)[0]); + _normal[i].normalizeSafe(); + + _curvature[i] = normalCurvature * _normal[i]; + if (lba+lbc > M_EPSILON) + _curvature[i]/=(0.5*lba+lbc); + + _normal[_nbVertices-1]=_normal[0]; + _curvature[_nbVertices-1]=_curvature[0]; + } +} + +void +Smoother::copyVertices () +{ + int i=0; + StrokeInternal::StrokeVertexIterator v, vend; + for(v=_stroke->strokeVerticesBegin(), vend=_stroke->strokeVerticesEnd(); + v!=vend; + ++v) + { + const Vec2r p0((v)->getPoint()); + const Vec2r p1(_vertex[i]); + Vec2r p(p0 + _carricatureFactor * (p1 - p0)); + + (v)->setPoint(p[0], p[1]); + i++; + } + +} + + +///////////////////////////////////////// +// +// OMISSION SHADER +// +///////////////////////////////////////// + +OmissionShader::OmissionShader (real sizeWindow, real thrVari, real thrFlat, real lFlat) +{ + _sizeWindow=sizeWindow; + _thresholdVariation=thrVari; + _thresholdFlat=thrFlat; + _lengthFlat=lFlat; +} + +int +OmissionShader::shade(Stroke &ioStroke) const +{ + Omitter omi(ioStroke); + omi.omit(_sizeWindow, _thresholdVariation, _thresholdFlat, _lengthFlat); + + return 0; +} + + +// OMITTER +/////////////////////////// + +Omitter::Omitter (Stroke &ioStroke) + :Smoother (ioStroke) +{ + StrokeInternal::StrokeVertexIterator v, vend; + int i=0; + for(v=ioStroke.strokeVerticesBegin(), vend=ioStroke.strokeVerticesEnd(); + v!=vend; + ++v) + { + _u[i]=(v)->curvilinearAbscissa(); + i++; + } + +} + +void +Omitter::omit (real sizeWindow, real thrVari, real thrFlat, real lFlat) +{ + _sizeWindow=sizeWindow; + _thresholdVariation=thrVari; + _thresholdFlat=thrFlat; + _lengthFlat=lFlat; + + for (int i=1; i<_nbVertices-1; i++) + { + if (_u[i]<_lengthFlat) continue; + // is the previous segment flat? + int j=i-1; + while ((j>=0) && (_u[i]-_u[j]<_lengthFlat)) + { + if ((_normal[j] * _normal[i]) < _thresholdFlat) + ; // FIXME + j--; + } + + } +} diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h new file mode 100755 index 00000000000..f2e56222cc0 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h @@ -0,0 +1,222 @@ +// +// Filename : AdvancedStrokeShaders.h +// Author : Fredo Durand +// Purpose : Fredo's stroke shaders +// Date of creation : 17/12/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef ADVANCEDSTROKESHADERS_H +# define ADVANCEDSTROKESHADERS_H + +# include "BasicStrokeShaders.h" + +/*! [ Thickness Shader ]. + * Assigns thicknesses to the stroke vertices + * so that the stroke looks like made with a calligraphic tool. + * i.e. The stroke will be the thickest in a main direction, + * the thinest in the direction perpendicular to this one, + * and an interpolation inbetween. + */ +class LIB_STROKE_EXPORT CalligraphicShader : public StrokeShader +{ + +public: + /*! Builds the shader. + * \param iMinThickness + * The minimum thickness in the direction perpandicular + * to the main direction. + * \param iMaxThickness + * The maximum thickness in the main direction. + * \param iOrientation + * The 2D vector giving the main direction. + * \param clamp + * Tells ??? + */ + CalligraphicShader (real iMinThickness, real iMaxThickness, + const Vec2f &iOrientation, bool clamp); + /*! Destructor. */ + virtual ~CalligraphicShader () {} + /*! The shading method */ + virtual int shade(Stroke &ioStroke) const; +protected: + real _maxThickness; + real _minThickness; + Vec2f _orientation; + bool _clamp; +}; + +/*! [ Geometry Shader ]. + * Spatial Noise stroke shader. + * Moves the vertices to make the stroke more noisy. + * @see \htmlonly <a href=noise/noise.html>noise/noise.html</a> \endhtmlonly + */ +class LIB_STROKE_EXPORT SpatialNoiseShader : public StrokeShader +{ +public: + /*! Builds the shader. + * \param iAmount + * The amplitude of the noise. + * \param ixScale + * The noise frequency + * \param nbOctave + * The number of octaves + * \param smooth + * If you want the noise to be smooth + * \param pureRandom + * If you don't want any coherence + */ + SpatialNoiseShader (float iAmount, float ixScale, int nbOctave, bool smooth, bool pureRandom); + /*! Destructor. */ + virtual ~SpatialNoiseShader () {} + /*! The shading method. */ + virtual int shade(Stroke &ioStroke) const; + +protected: + + float _amount; + float _xScale; + int _nbOctave; + bool _smooth; + bool _pureRandom; +}; + +/*! [ Geometry Shader ]. + * Smoothes the stroke. + * (Moves the vertices to make the stroke smoother). + * Uses curvature flow to converge towards a curve of constant + * curvature. The diffusion method we use is anisotropic + * to prevent the diffusion accross corners. + * @see \htmlonly <a href=/smoothing/smoothing.html>smoothing/smoothing.html</a> endhtmlonly + */ +class LIB_STROKE_EXPORT SmoothingShader : public StrokeShader +{ +public: + /*! Builds the shader. + * \param iNbIteration + * The number of iterations. (400) + * \param iFactorPoint + * 0 + * \param ifactorCurvature + * 0 + * \param iFactorCurvatureDifference + * 0.2 + * \param iAnisoPoint + * 0 + * \param iAnisNormal + * 0 + * \param iAnisoCurvature + * 0 + * \param icarricatureFactor + * 1 + */ + SmoothingShader (int iNbIteration, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, + real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real icarricatureFactor); + /*! Destructor. */ + virtual ~SmoothingShader () {} + + /*! The shading method. */ + virtual int shade(Stroke &ioStroke) const; + +protected: + + int _nbIterations; + real _factorPoint; + real _factorCurvature; + real _factorCurvatureDifference; + real _anisoPoint; + real _anisoNormal; + real _anisoCurvature; + real _carricatureFactor; +}; + +class LIB_STROKE_EXPORT Smoother +{ +public: + Smoother (Stroke &ioStroke); + + virtual ~Smoother () {} + + void smooth (int nbIterations, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, + real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real icarricatureFactor); + void computeCurvature (); + +protected: + real _factorPoint; + real _factorCurvature; + real _factorCurvatureDifference; + real _anisoPoint; + real _anisoNormal; + real _anisoCurvature; + real _carricatureFactor; + + void iteration(); + void copyVertices (); + + Stroke *_stroke; + int _nbVertices; + Vec2r *_vertex; + Vec2r *_normal; + real *_curvature; + bool *_isFixedVertex; + + bool _isClosedCurve; + bool _safeTest; +}; + +class LIB_STROKE_EXPORT Omitter : public Smoother +{ +public: + Omitter (Stroke &ioStroke); + virtual ~Omitter () {} + + void omit (real sizeWindow, real thrVari, real thrFlat, real lFlat); +protected: + real *_u; + + real _sizeWindow; + real _thresholdVariation; + real _thresholdFlat; + real _lengthFlat; +}; + +/*! Omission shader + */ +class LIB_STROKE_EXPORT OmissionShader : public StrokeShader +{ +public: + OmissionShader (real sizeWindow, real thrVari, real thrFlat, real lFlat); + virtual ~OmissionShader () {} + + virtual int shade(Stroke &ioStroke) const; + +protected: + + real _sizeWindow; + real _thresholdVariation; + real _thresholdFlat; + real _lengthFlat; +}; + +#endif // ADVANCEDSTROKESHADERS_H diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp new file mode 100755 index 00000000000..828c13338ae --- /dev/null +++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp @@ -0,0 +1,1160 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <fstream> +#include "BasicStrokeShaders.h" +#include "../system/PseudoNoise.h" +#include "../system/RandGen.h" +#include "../view_map/Functions0D.h" +#include "../view_map/Functions1D.h" +#include "AdvancedFunctions0D.h" +#include "AdvancedFunctions1D.h" +#include "StrokeIterators.h" +#include "../system/StringUtils.h" +#include "StrokeRenderer.h" +#include "StrokeIO.h" + +//soc #include <qimage.h> +//soc #include <QString> +extern "C" { +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +} + +// Internal function + +// soc +// void convert(const QImage& iImage, float **oArray, unsigned &oSize) { +// oSize = iImage.width(); +// *oArray = new float[oSize]; +// for(unsigned i=0; i<oSize; ++i) { +// QRgb rgb = iImage.pixel(i,0); +// (*oArray)[i] = ((float)qBlue(rgb))/255.f; +// } +// } +void convert(ImBuf *imBuf, float **oArray, unsigned &oSize) { + oSize = imBuf->x; + *oArray = new float[oSize]; + + char *pix; + for(unsigned i=0; i < oSize; ++i) { + pix = (char*) imBuf->rect + i*4; + (*oArray)[i] = ((float) pix[2] )/255.f; + } +} + +namespace StrokeShaders { + + // + // Thickness modifiers + // + ////////////////////////////////////////////////////////// + + int ConstantThicknessShader::shade(Stroke& stroke) const + { + StrokeInternal::StrokeVertexIterator v, vend; + int i=0; + int size = stroke.strokeVerticesSize(); + for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + v!=vend; + ++v) + { + if((1 == i) || (size-2 == i)) + v->attribute().setThickness(_thickness/4.0,_thickness/4.0); + if((0 == i) || (size-1 == i)) + v->attribute().setThickness(0,0); + + v->attribute().setThickness(_thickness/2.0, _thickness/2.0); + } + return 0; + } + + int ConstantExternThicknessShader::shade(Stroke& stroke) const + { + StrokeInternal::StrokeVertexIterator v, vend; + int i=0; + int size = stroke.strokeVerticesSize(); + for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + v!=vend; + ++v) + { + if((1 == i) || (size-2 == i)) + v->attribute().setThickness(_thickness/2.0,0); + if((0 == i) || (size-1 == i)) + v->attribute().setThickness(0,0); + + v->attribute().setThickness(_thickness, 0); + } + return 0; + } + + int IncreasingThicknessShader::shade(Stroke& stroke) const + { + + int n=stroke.strokeVerticesSize()-1; + StrokeInternal::StrokeVertexIterator v, vend; + int i=0; + for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + v!=vend; + + ++v) + { + float t; + if(i < (float)n/2.f) + t = (1.0-(float)i/(float)n)*_ThicknessMin + (float)i/(float)n*_ThicknessMax; + else + t = (1.0-(float)i/(float)n)*_ThicknessMax + (float)i/(float)n*_ThicknessMin; + v->attribute().setThickness(t/2.0, t/2.0); + ++i; + } + return 0; + } + + int ConstrainedIncreasingThicknessShader::shade(Stroke& stroke) const + { + float slength = stroke.getLength2D(); + float maxT = min(_ratio*slength,_ThicknessMax); + int n=stroke.strokeVerticesSize()-1; + StrokeInternal::StrokeVertexIterator v, vend; + int i=0; + for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + v!=vend; + + ++v) + { + float t; + if(i < (float)n/2.f) + t = (1.0-(float)i/(float)n)*_ThicknessMin + (float)i/(float)n*maxT; + else + t = (1.0-(float)i/(float)n)*maxT + (float)i/(float)n*_ThicknessMin; + v->attribute().setThickness(t/2.0, t/2.0); + if(i == n-1) + v->attribute().setThickness(_ThicknessMin/2.0, _ThicknessMin/2.0); + ++i; + } + return 0; + } + + + int LengthDependingThicknessShader::shade(Stroke& stroke) const + { + float step = (_maxThickness-_minThickness)/3.f; + float l = stroke.getLength2D(); + float thickness = 0.0; + if(l>300.f) + thickness = _minThickness+3.f*step; + else if((l< 300.f) && (l>100.f)) + thickness = _minThickness+2.f*step; + else if((l<100.f) && (l>50.f)) + thickness = _minThickness+1.f*step; + else if(l< 50.f) + thickness = _minThickness; + + StrokeInternal::StrokeVertexIterator v, vend; + int i=0; + int size = stroke.strokeVerticesSize(); + for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + v!=vend; + ++v) + { + if((1 == i) || (size-2 == i)) + v->attribute().setThickness(thickness/4.0,thickness/4.0); + if((0 == i) || (size-1 == i)) + v->attribute().setThickness(0,0); + + v->attribute().setThickness(thickness/2.0, thickness/2.0); + } + return 0; + } + + + ThicknessVariationPatternShader::ThicknessVariationPatternShader(const string pattern_name, + float iMinThickness, + float iMaxThickness, + bool stretch) + : StrokeShader() { + _stretch = stretch; + _minThickness = iMinThickness; + _maxThickness = iMaxThickness; + ImBuf *image = 0; //soc + vector<string> pathnames; + StringUtils::getPathName(TextureManager::Options::getPatternsPath(), + pattern_name, + pathnames); + for (vector<string>::const_iterator j = pathnames.begin(); j != pathnames.end(); j++) { + ifstream ifs(j->c_str()); + if (ifs.is_open()) { + //soc image.load(j->c_str()); + image = IMB_loadiffname(j->c_str(), 0); + break; + } + } + if (image == 0) //soc + cerr << "Error: cannot find pattern \"" << pattern_name + << "\" - check the path in the Options" << endl; + else + convert(image, &_aThickness, _size); + } + + int ThicknessVariationPatternShader::shade(Stroke& stroke) const + { + StrokeInternal::StrokeVertexIterator v, vend; + float *array = 0; + int size; + array = _aThickness; + size = _size; + // } + int vert_size = stroke.strokeVerticesSize(); + int sig = 0; + unsigned index; + const float* originalThickness; + for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + v!=vend; + ++v) + { + originalThickness = v->attribute().getThickness(); + if (_stretch) { + float tmp = v->u()*(_size-1); + index = (unsigned)floor(tmp); + if((tmp-index) > (index+1-tmp)) + ++index; + } + else + index = (unsigned)floor(v->curvilinearAbscissa()); + index %= _size; + float thicknessR = array[index]*originalThickness[0]; + float thicknessL = array[index]*originalThickness[1]; + if(thicknessR+thicknessL < _minThickness) + { + thicknessL = _minThickness/2.f; + thicknessR = _minThickness/2.f; + } + if(thicknessR+thicknessL > _maxThickness) + { + thicknessL = _maxThickness/2.f; + thicknessR = _maxThickness/2.f; + } + if((sig==0) || (sig==vert_size-1)) + v->attribute().setThickness(1, 1); + else + v->attribute().setThickness(thicknessR, thicknessL); + ++sig; + } + return 0; + } + + + static const unsigned NB_VALUE_NOISE = 512; + ThicknessNoiseShader::ThicknessNoiseShader() + :StrokeShader() + {_amplitude=1.f;_scale=1.f/2.f/(float)NB_VALUE_NOISE;} + + ThicknessNoiseShader::ThicknessNoiseShader(float iAmplitude, float iPeriod) + :StrokeShader() + {_amplitude=iAmplitude;_scale=1.f/iPeriod/(float)NB_VALUE_NOISE;} + + + int ThicknessNoiseShader::shade(Stroke& stroke) const + { + StrokeInternal::StrokeVertexIterator v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + real initU1=v->strokeLength()*real(NB_VALUE_NOISE)+RandGen::drand48()*real(NB_VALUE_NOISE); + real initU2=v->strokeLength()*real(NB_VALUE_NOISE)+RandGen::drand48()*real(NB_VALUE_NOISE); + + real bruit, bruit2; + PseudoNoise mynoise, mynoise2; + for(; + v!=vend; + ++v) + { + + bruit=mynoise.turbulenceSmooth(_scale*v->curvilinearAbscissa()+initU1, + 2); //2 : nbOctaves + bruit2=mynoise2.turbulenceSmooth(_scale*v->curvilinearAbscissa()+initU2, + 2); //2 : nbOctaves + const float *originalThickness = v->attribute().getThickness(); + float r = bruit*_amplitude+originalThickness[0]; + float l = bruit2*_amplitude+originalThickness[1]; + v->attribute().setThickness(r,l); + } + + return 0; + } + + // + // Color shaders + // + /////////////////////////////////////////////////////////////////////////////// + + int ConstantColorShader::shade(Stroke& stroke) const + { + StrokeInternal::StrokeVertexIterator v, vend; + for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + v!=vend; + ++v) + { + v->attribute().setColor(_color[0], _color[1], _color[2]); + v->attribute().setAlpha(_color[3]); + } + return 0; + } + + int IncreasingColorShader::shade(Stroke& stroke) const + { + StrokeInternal::StrokeVertexIterator v, vend; + int n=stroke.strokeVerticesSize()-1; + int yo=0; + float newcolor[4]; + for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + v!=vend; + + ++v) + { + for(int i=0; i<4; ++i) + { + newcolor[i] = (1.0-(float)yo/(float)n)*_colorMin[i] + (float)yo/(float)n*_colorMax[i]; + } + v->attribute().setColor(newcolor[0], newcolor[1], newcolor[2]); + v->attribute().setAlpha(newcolor[3]); + ++yo; + } + return 0; + } + + ColorVariationPatternShader::ColorVariationPatternShader(const string pattern_name, + bool stretch) + : StrokeShader() { + _stretch = stretch; + ImBuf *image = 0; //soc + vector<string> pathnames; + StringUtils::getPathName(TextureManager::Options::getPatternsPath(), + pattern_name, + pathnames); + for (vector<string>::const_iterator j = pathnames.begin(); j != pathnames.end(); j++) { + ifstream ifs(j->c_str()); + if (ifs.is_open()) { + image = IMB_loadiffname(j->c_str(), 0); //soc + break; + } + } + if (image == 0) //soc + cerr << "Error: cannot find pattern \"" << pattern_name + << "\" - check the path in the Options" << endl; + else + convert(image, &_aVariation, _size); + } + + int ColorVariationPatternShader::shade(Stroke& stroke) const + { + StrokeInternal::StrokeVertexIterator v, vend; + unsigned index; + for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + v!=vend; + ++v) + { + const float *originalColor = v->attribute().getColor(); + if (_stretch) { + float tmp = v->u()*(_size-1); + index = (unsigned)floor(tmp); + if((tmp-index) > (index+1-tmp)) + ++index; + } + else + index = (unsigned)floor(v->curvilinearAbscissa()); + index %= _size; + float r = _aVariation[index]*originalColor[0]; + float g = _aVariation[index]*originalColor[1]; + float b = _aVariation[index]*originalColor[2]; + v->attribute().setColor(r,g,b); + } + return 0; + } + + int MaterialColorShader::shade(Stroke& stroke) const + { + Interface0DIterator v, vend; + Functions0D::MaterialF0D fun; + StrokeVertex *sv; + for(v=stroke.verticesBegin(), vend=stroke.verticesEnd(); + v!=vend; + ++v) + { + if (fun(v) < 0) + return -1; + const float *diffuse = fun.result.diffuse(); + sv = dynamic_cast<StrokeVertex*>(&(*v)); + sv->attribute().setColor(diffuse[0]*_coefficient, diffuse[1]*_coefficient, diffuse[2]*_coefficient); + sv->attribute().setAlpha(diffuse[3]); + } + return 0; + } + + + int CalligraphicColorShader::shade(Stroke& stroke) const + { + Interface0DIterator v; + Functions0D::VertexOrientation2DF0D fun; + StrokeVertex* sv; + for(v=stroke.verticesBegin(); + !v.isEnd(); + ++v) + { + if (fun(v) < 0) + return -1; + Vec2f vertexOri(fun.result); + Vec2d ori2d(-vertexOri[1], vertexOri[0]); + ori2d.normalizeSafe(); + real scal = ori2d * _orientation; + sv = dynamic_cast<StrokeVertex*>(&(*v)); + if ((scal<0)) + sv->attribute().setColor(0,0,0); + else + sv->attribute().setColor(1,1,1); + } + return 0; + } + + + ColorNoiseShader::ColorNoiseShader() + :StrokeShader() + {_amplitude=1.f;_scale=1.f/2.f/(float)NB_VALUE_NOISE;} + + ColorNoiseShader::ColorNoiseShader(float iAmplitude, float iPeriod) + :StrokeShader() + {_amplitude=iAmplitude;_scale=1.f/iPeriod/(float)NB_VALUE_NOISE;} + + + int ColorNoiseShader::shade(Stroke& stroke) const + { + StrokeInternal::StrokeVertexIterator v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + real initU=v->strokeLength()*real(NB_VALUE_NOISE)+RandGen::drand48()*real(NB_VALUE_NOISE); + + real bruit; + PseudoNoise mynoise; + for(; + v!=vend; + ++v) + { + + bruit=mynoise.turbulenceSmooth(_scale*v->curvilinearAbscissa()+initU, + 2); //2 : nbOctaves + const float *originalColor = v->attribute().getColor(); + float r = bruit*_amplitude+originalColor[0]; + float g = bruit*_amplitude+originalColor[1]; + float b = bruit*_amplitude+originalColor[2]; + v->attribute().setColor(r,g,b); + } + + return 0; + } + + + // + // Texture Shaders + // + /////////////////////////////////////////////////////////////////////////////// + + int TextureAssignerShader::shade(Stroke& stroke) const + { + // getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/oil.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/oilnoblend.bmp", Stroke::HUMID_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::DRY_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::DRY_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueDryBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM); + // getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM); + + TextureManager * instance = TextureManager::getInstance(); + if(!instance) + return 0; + string pathname; + Stroke::MediumType mediumType; + bool hasTips = false; + switch(_textureId) + { + case 0: + //pathname = TextureManager::Options::getBrushesPath() + "/charcoalAlpha.bmp"; + pathname = "/charcoalAlpha.bmp"; + mediumType = Stroke::HUMID_MEDIUM; + hasTips = false; + break; + case 1: + pathname = "/washbrushAlpha.bmp"; + mediumType = Stroke::HUMID_MEDIUM; + hasTips = true; + break; + case 2: + pathname = "/oil.bmp"; + mediumType = Stroke::HUMID_MEDIUM; + hasTips = true; + break; + case 3: + pathname = "/oilnoblend.bmp"; + mediumType = Stroke::HUMID_MEDIUM; + hasTips = true; + break; + case 4: + pathname = "/charcoalAlpha.bmp"; + mediumType = Stroke::DRY_MEDIUM; + hasTips = false; + break; + case 5: + mediumType = Stroke::DRY_MEDIUM; + hasTips = true; + break; + case 6: + pathname = "/opaqueDryBrushAlpha.bmp"; + mediumType = Stroke::OPAQUE_MEDIUM; + hasTips = true; + break; + case 7: + pathname = "/opaqueBrushAlpha.bmp"; + mediumType = Stroke::OPAQUE_MEDIUM; + hasTips = true; + break; + default: + pathname = "/smoothAlpha.bmp"; + mediumType = Stroke::OPAQUE_MEDIUM; + hasTips = false; + break; + } + unsigned int texId = instance->getBrushTextureIndex(pathname, mediumType); + stroke.setMediumType(mediumType); + stroke.setTips(hasTips); + stroke.setTextureId(texId); + return 0; + } + + // FIXME + int StrokeTextureShader::shade(Stroke& stroke) const + { + TextureManager * instance = TextureManager::getInstance(); + if(!instance) + return 0; + string pathname = TextureManager::Options::getBrushesPath() + "/" + _texturePath; + unsigned int texId = instance->getBrushTextureIndex(pathname, _mediumType); + stroke.setMediumType(_mediumType); + stroke.setTips(_tips); + stroke.setTextureId(texId); + return 0; + } + + // + // Geometry Shaders + // + /////////////////////////////////////////////////////////////////////////////// + + int BackboneStretcherShader::shade(Stroke& stroke) const + { + float l=stroke.getLength2D(); + if(l <= 50) + return 0; + + StrokeInternal::StrokeVertexIterator v0=stroke.strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator v1=v0;++v1; + StrokeInternal::StrokeVertexIterator vn=stroke.strokeVerticesEnd();--vn; + StrokeInternal::StrokeVertexIterator vn_1=vn;--vn_1; + + + Vec2d first((v0)->x(), (v0)->y()); + Vec2d last((vn)->x(), (vn)->y()); + + Vec2d d1(first-Vec2d((v1)->x(), (v1)->y())); + d1.normalize(); + Vec2d dn(last-Vec2d((vn_1)->x(), (vn_1)->y())); + dn.normalize(); + + Vec2d newFirst(first+_amount*d1); + (v0)->setPoint(newFirst[0], newFirst[1]); + Vec2d newLast(last+_amount*dn); + (vn)->setPoint(newLast[0], newLast[1]); + return 0; + } + + int SamplingShader::shade(Stroke& stroke) const + { + stroke.Resample(_sampling); + return 0; + } + + int ExternalContourStretcherShader::shade(Stroke& stroke) const + { + //float l=stroke.getLength2D(); + Interface0DIterator it=stroke.verticesBegin(); + Functions0D::Normal2DF0D fun; + StrokeVertex* sv; + while (!it.isEnd()) + { + if (fun(it) < 0) + return -1; + Vec2f n(fun.result); + sv = dynamic_cast<StrokeVertex*>(&(*it)); + Vec2d newPoint(sv->x()+_amount*n.x(), sv->y()+_amount*n.y()); + sv->setPoint(newPoint[0], newPoint[1]); + ++it; + } + return 0; + } + + int BSplineShader::shade(Stroke& stroke) const + { + if(stroke.strokeVerticesSize() < 4) + return 0; + + // Find the new vertices + vector<Vec2d> newVertices; + double t=0.f; + float _sampling = 5.f; + + StrokeInternal::StrokeVertexIterator p0,p1,p2,p3, end; + p0 = stroke.strokeVerticesBegin(); + p1 = p0; + p2 = p1; + p3 = p2; + end = stroke.strokeVerticesEnd(); + double a[4],b[4]; + int n=0; + while(p1 != end) + { + // if(p1 == end) + // p1 = p0; + if(p2 == end) + p2 = p1; + if(p3 == end) + p3 = p2; + // compute new matrix + a[0] = (-(p0)->x()+3*(p1)->x()-3*(p2)->x()+(p3)->x())/6.0; + a[1] = (3*(p0)->x()-6*(p1)->x()+3*(p2)->x())/6.0; + a[2] = (-3*(p0)->x()+3*(p2)->x())/6.0; + a[3] = ((p0)->x()+4*(p1)->x()+(p2)->x())/6.0; + + b[0] = (-(p0)->y()+3*(p1)->y()-3*(p2)->y()+(p3)->y())/6.0; + b[1] = (3*(p0)->y()-6*(p1)->y()+3*(p2)->y())/6.0; + b[2] = (-3*(p0)->y()+3*(p2)->y())/6.0; + b[3] = ((p0)->y()+4*(p1)->y()+(p2)->y())/6.0; + + + // draw the spline depending on resolution: + Vec2d p1p2((p2)->x()-(p1)->x(), (p2)->y()-(p1)->y()); + double norm = p1p2.norm(); + //t = _sampling/norm; + t=0; + while(t<1) + { + newVertices.push_back(Vec2d((a[3] + t*(a[2] + t*(a[1] + t*a[0]))), + (b[3] + t*(b[2] + t*(b[1] + t*b[0]))))); + t = t + _sampling/norm; + } + if(n > 2) + { + ++p0; + ++p1; + ++p2; + ++p3; + } + else + { + if(n==0) + ++p3; + if(n==1) + {++p2;++p3;} + if(n==2) + {++p1;++p2;++p3;} + ++n; + } + } + //last point: + newVertices.push_back(Vec2d((p0)->x(), (p0)->y())); + + int originalSize = newVertices.size(); + _sampling = stroke.ComputeSampling(originalSize); + + // Resample and set x,y coordinates + stroke.Resample(_sampling); + int newsize = stroke.strokeVerticesSize(); + + int nExtraVertex=0; + if(newsize < originalSize) + cerr << "Warning: unsufficient resampling" << endl; + else + { + nExtraVertex = newsize - originalSize; + } + + // assigns the new coordinates: + vector<Vec2d>::iterator p,pend; + p=newVertices.begin();pend=newVertices.end(); + vector<Vec2d>::iterator last = p; + n=0; + StrokeInternal::StrokeVertexIterator it=stroke.strokeVerticesBegin(), itend=stroke.strokeVerticesEnd(); + it=stroke.strokeVerticesBegin(); + for(; + ((it!=itend) && (p!=pend)); + ++it) + { + it->setX(p->x()); + it->setY(p->y()); + last = p; + ++p; + ++n; + } + // nExtraVertex should stay unassigned + for(int i=0; i< nExtraVertex; ++i) + { + it->setX(last->x()); + it->setY(last->y()); + if(it.isEnd()) + cerr << "Warning: Problem encountered while creating B-spline" << endl; + ++it; + ++n; + } + return 0; + } + + //!! Bezier curve stroke shader + int BezierCurveShader::shade(Stroke& stroke) const + { + if(stroke.strokeVerticesSize() < 4) + return 0; + + // Build the Bezier curve from this set of data points: + vector<Vec2d> data; + StrokeInternal::StrokeVertexIterator v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); + data.push_back(Vec2d(v->x(), v->y()));//first one + StrokeInternal::StrokeVertexIterator previous = v;++v; + for(; + v!=vend; + ++v) + { + if(!((fabs(v->x() -(previous)->x())<M_EPSILON) && ((fabs(v->y() - (previous)->y())<M_EPSILON)))) + data.push_back(Vec2d(v->x(), v->y())); + previous = v; + } + + // Vec2d tmp;bool equal=false; + // if(data.front() == data.back()) + // { + // tmp = data.back(); + // data.pop_back(); + // equal=true; + // } + // here we build the bezier curve + BezierCurve bcurve(data, _error); + + // bad performances are here !!! // FIXME + vector<Vec2d> CurveVertices; + vector<BezierCurveSegment*>& bsegments = bcurve.segments(); + vector<BezierCurveSegment*>::iterator s=bsegments.begin(),send=bsegments.end(); + vector<Vec2d>& segmentsVertices = (*s)->vertices(); + vector<Vec2d>::iterator p,pend; + // first point + CurveVertices.push_back(segmentsVertices[0]); + for(; + s!=send; + ++s) + { + segmentsVertices = (*s)->vertices(); + p=segmentsVertices.begin(); pend=segmentsVertices.end(); + ++p; + for(; + p!=pend; + ++p) + { + CurveVertices.push_back((*p)); + } + } + + //if(equal) + // if(data.back() == data.front()) + // { + // vector<Vec2d>::iterator d=data.begin(), dend=data.end(); + // cout << "ending point = starting point" << endl; + // cout << "---------------DATA----------" << endl; + // for(; + // d!=dend; + // ++d) + // { + // cout << d->x() << "-" << d->y() << endl; + // } + // cout << "--------------BEZIER RESULT----------" << endl; + // d=CurveVertices.begin(), dend=CurveVertices.end(); + // for(;d!=dend;++d) + // { + // cout << d->x() << "-" << d->y() << endl; + // } + // } + + // Resample the Stroke depending on the number of + // vertices of the bezier curve: + int originalSize = CurveVertices.size(); + //float sampling = stroke.ComputeSampling(originalSize); + //stroke.Resample(sampling); + stroke.Resample(originalSize); + int newsize = stroke.strokeVerticesSize(); + int nExtraVertex=0; + if(newsize < originalSize) + cerr << "Warning: unsufficient resampling" << endl; + else + { + //cout << "Oversampling" << endl; + nExtraVertex = newsize - originalSize; + if(nExtraVertex != 0) + cout << "Bezier Shader : Stroke " << stroke.getId() << " have not been resampled" << endl; + } + + // assigns the new coordinates: + p=CurveVertices.begin();pend=CurveVertices.end(); + vector<Vec2d>::iterator last = p; + int n=0; + StrokeInternal::StrokeVertexIterator it=stroke.strokeVerticesBegin(), itend=stroke.strokeVerticesEnd(); + // while(p!=pend) + // { + // ++n; + // ++p; + // } + it=stroke.strokeVerticesBegin(); + for(; + ((it!=itend) && (p!=pend)); + ++it) + { + it->setX(p->x()); + it->setY(p->y()); + // double x = p->x(); + // double y = p->y(); + // cout << "x = " << x << "-" << "y = " << y << endl; + last = p; + ++p; + ++n; + } + + // Deal with extra vertices: + if(nExtraVertex == 0) + return 0; + + // nExtraVertex should stay unassigned + vector<StrokeAttribute> attributes; + vector<StrokeVertex*> verticesToRemove; + for(int i=0; i< nExtraVertex; ++i) + { + verticesToRemove.push_back(&(*it)); + if(it.isEnd()) + cout << "fucked up" << endl; + ++it; + ++n; + } + it=stroke.strokeVerticesBegin(); + for(; + it!=itend; + ++it) + { + attributes.push_back(it->attribute()); + } + + for(vector<StrokeVertex*>::iterator vr=verticesToRemove.begin(), vrend=verticesToRemove.end(); + vr!=vrend; + ++vr) + { + stroke.RemoveVertex(*vr); + } + it=stroke.strokeVerticesBegin(); + itend=stroke.strokeVerticesEnd(); + vector<StrokeAttribute>::iterator a=attributes.begin(), aend=attributes.end(); + int index = 0; + int index1 = (int)floor((float)originalSize/2.0); + int index2 = index1+nExtraVertex; + for(; + (it!=itend) && (a!=aend); + ++it) + { + (it)->setAttribute(*a); + if((index <= index1)||(index>index2)) + ++a; + ++index; + } + return 0; + } + + int InflateShader::shade(Stroke& stroke) const + { + // we're computing the curvature variance of the stroke.(Combo 5) + // If it's too high, forget about it + Functions1D::Curvature2DAngleF1D fun; + if (fun(stroke) < 0) + return -1; + if (fun.result > _curvatureThreshold) + return 0; + + Functions0D::VertexOrientation2DF0D ori_fun; + Functions0D::Curvature2DAngleF0D curv_fun; + Functions1D::Normal2DF1D norm_fun; + Interface0DIterator it=stroke.verticesBegin(); + StrokeVertex* sv; + while (!it.isEnd()) + { + if (ori_fun(it) < 0) + return -1; + Vec2f ntmp(ori_fun.result); + Vec2f n(ntmp.y(), -ntmp.x()); + if (norm_fun(stroke) < 0) + return -1; + Vec2f strokeN(norm_fun.result); + if(n*strokeN < 0) + { + n[0] = -n[0]; + n[1] = -n[1]; + } + sv = dynamic_cast<StrokeVertex*>(&(*it)); + float u=sv->u(); + float t = 4.f*(0.25f - (u-0.5)*(u-0.5)); + if (curv_fun(it) < 0) + return -1; + float curvature_coeff = (M_PI-curv_fun.result)/M_PI; + Vec2d newPoint(sv->x()+curvature_coeff*t*_amount*n.x(), sv->y()+curvature_coeff*t*_amount*n.y()); + sv->setPoint(newPoint[0], newPoint[1]); + ++it; + } + return 0; + } + + class CurvePiece + { + public: + StrokeInternal::StrokeVertexIterator _begin; + StrokeInternal::StrokeVertexIterator _last; + Vec2d A; + Vec2d B; + int size; + float _error; + + CurvePiece(StrokeInternal::StrokeVertexIterator b, StrokeInternal::StrokeVertexIterator l, int iSize) + { + _begin = b; + _last = l; + A = Vec2d((_begin)->x(),(_begin)->y()); + B = Vec2d((_last)->x(),(_last)->y()); + size = iSize; + } + + float error() + { + float maxE = 0.f; + for(StrokeInternal::StrokeVertexIterator it=_begin; + it!=_last; + ++it) + { + Vec2d P(it->x(), it->y()); + float d = GeomUtils::distPointSegment(P,A,B); + if(d > maxE) + maxE = d; + } + _error = maxE; + return maxE; + } + //! Subdivides the curve into two pieces. + // The first piece is this same object (modified) + // the second piece is returned by the method + CurvePiece * subdivide() + { + StrokeInternal::StrokeVertexIterator it=_begin; + int actualSize = 1; + for(int i=0; i<size/2; ++i) + { + ++it; + ++actualSize; + } + CurvePiece * second = new CurvePiece(it, _last, size-actualSize+1); + size = actualSize; + _last = it; + B = Vec2d((_last)->x(), (_last)->y()); + return second; + } + }; + + int PolygonalizationShader::shade(Stroke& stroke) const + { + vector<CurvePiece*> _pieces; + vector<CurvePiece*> _results; + vector<CurvePiece*>::iterator cp,cpend; + + // Compute first approx: + StrokeInternal::StrokeVertexIterator a=stroke.strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator b=stroke.strokeVerticesEnd();--b; + int size = stroke.strokeVerticesSize(); + + CurvePiece * piece = new CurvePiece(a,b,size); + _pieces.push_back(piece); + + while(!_pieces.empty()) + { + piece = _pieces.back();_pieces.pop_back(); + if(piece->error() > _error) + { + CurvePiece * second = piece->subdivide(); + _pieces.push_back(second); + _pieces.push_back(piece); + } + else + { + _results.push_back(piece); + } + } + + // actually modify the geometry for each piece: + for(cp=_results.begin(), cpend=_results.end(); + cp!=cpend; + ++cp) + { + a = (*cp)->_begin; + b = (*cp)->_last; + Vec2d u = (*cp)->B-(*cp)->A; + Vec2d n(u[1], -u[0]);n.normalize(); + //Vec2d n(0,0); + float offset = ((*cp)->_error); + StrokeInternal::StrokeVertexIterator v,vlast; + for(v=a; + v!=b; + ++v) + { + v->setPoint((*cp)->A.x()+v->u()*u.x()+n.x()*offset, (*cp)->A.y()+v->u()*u.y()+n.y()*offset); + } + // u.normalize(); + // (*a)->setPoint((*a)->x()-u.x()*10, (*a)->y()-u.y()*10); + } + + // delete stuff + for(cp=_results.begin(), cpend=_results.end(); + cp!=cpend; + ++cp) + { + delete (*cp); + } + _results.clear(); + return 0; + } + + int GuidingLinesShader::shade(Stroke& stroke) const + { + Functions1D::Normal2DF1D norm_fun; + StrokeInternal::StrokeVertexIterator a=stroke.strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator b=stroke.strokeVerticesEnd();--b; + int size = stroke.strokeVerticesSize(); + CurvePiece piece(a,b,size); + + Vec2d u = piece.B-piece.A; + Vec2f n(u[1], -u[0]);n.normalize(); + if (norm_fun(stroke) < 0) + return -1; + Vec2f strokeN(norm_fun.result); + if(n*strokeN < 0) + { + n[0] = -n[0]; + n[1] = -n[1]; + } + float offset = (piece.error())/2.f*_offset; + StrokeInternal::StrokeVertexIterator v=a,vend=stroke.strokeVerticesEnd(); + for(; + v!=vend; + ++v) + { + v->setPoint(piece.A.x()+v->u()*u.x()+n.x()*offset, piece.A.y()+v->u()*u.y()+n.y()*offset); + } + return 0; + } + + ///////////////////////////////////////// + // + // Tip Remover + // + ///////////////////////////////////////// + + + TipRemoverShader::TipRemoverShader(real tipLength) + : StrokeShader() + { + _tipLength = tipLength; + } + + int + TipRemoverShader::shade(Stroke& stroke) const + { + int originalSize = stroke.strokeVerticesSize(); + + if(originalSize<4) + return 0; + + StrokeInternal::StrokeVertexIterator v, vend; + vector<StrokeVertex*> verticesToRemove; + vector<StrokeAttribute> oldAttributes; + v=stroke.strokeVerticesBegin(); vend=stroke.strokeVerticesEnd(); + for(; + v!=vend; + ++v) + { + if ((v->curvilinearAbscissa()<_tipLength) || + (v->strokeLength()-v->curvilinearAbscissa()<_tipLength)) + { + verticesToRemove.push_back(&(*v)); + } + oldAttributes.push_back(v->attribute()); + } + + if(originalSize-verticesToRemove.size() < 2) + return 0; + + vector<StrokeVertex*>::iterator sv=verticesToRemove.begin(), svend=verticesToRemove.end(); + for(; + sv!=svend; + ++sv) + { + stroke.RemoveVertex((*sv)); + } + + // Resample so that our new stroke have the same + // number of vertices than before + stroke.Resample(originalSize); + + if((int)stroke.strokeVerticesSize() != originalSize) //soc + cerr << "Warning: resampling problem" << endl; + + // assign old attributes to new stroke vertices: + v=stroke.strokeVerticesBegin(); vend=stroke.strokeVerticesEnd(); + vector<StrokeAttribute>::iterator a=oldAttributes.begin(), aend=oldAttributes.end(); + //cout << "-----------------------------------------------" << endl; + for(;(v!=vend)&&(a!=aend);++v,++a) + { + v->setAttribute(*a); + //cout << "thickness = " << (*a).getThickness()[0] << "-" << (*a).getThickness()[1] << endl; + } + // we're done! + return 0; + } + + int streamShader::shade(Stroke& stroke) const{ + cout << stroke << endl; + return 0; + } + int fstreamShader::shade(Stroke& stroke) const{ + _stream << stroke << endl; + return 0; + } + +} // end of namespace StrokeShaders + diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h new file mode 100755 index 00000000000..a0c0a44c9b6 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h @@ -0,0 +1,890 @@ +// +// Filename : BasicStrokeShaders.h +// Author : Stephane Grabli +// Purpose : Class gathering basic stroke shaders +// Date of creation : 17/12/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BASIC_STROKE_SHADERS_H +# define BASIC_STROKE_SHADERS_H + +# include "Stroke.h" +# include "../geometry/Geom.h" +# include "../geometry/Bezier.h" +# include "StrokeShader.h" +# include <fstream> + +using namespace std; +using namespace Geometry; + +namespace StrokeShaders { + + // + // Thickness modifiers + // + ////////////////////////////////////////////////////// + /*! [ Thickness Shader ]. + * Assigns an absolute constant thickness to every + * vertices of the Stroke. + */ + class LIB_STROKE_EXPORT ConstantThicknessShader : public StrokeShader + { + public: + /*! Builds the shader. + * \param thickness + * The thickness that must be assigned + * to the stroke. + */ + ConstantThicknessShader(float thickness) : StrokeShader() { + _thickness = thickness; + } + /*! Destructor. */ + virtual ~ConstantThicknessShader() {} + /*! Returns the string "ConstantThicknessShader".*/ + virtual string getName() const { + return "ConstantThicknessShader"; + } + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + + private: + float _thickness; + }; + + /* [ Thickness Shader ]. + * Assigns an absolute constant external thickness to every + * vertices of the Stroke. The external thickness of a point + * is its thickness from the point to the strip border + * in the direction pointing outside the object the + * Stroke delimitates. + */ + class LIB_STROKE_EXPORT ConstantExternThicknessShader : public StrokeShader + { + public: + + ConstantExternThicknessShader(float thickness) : StrokeShader() { + _thickness = thickness; + } + + virtual ~ConstantExternThicknessShader() {} + + virtual string getName() const { + return "ConstantExternThicknessShader"; + } + + virtual int shade(Stroke& stroke) const; + + private: + + float _thickness; + }; + + /*! [ Thickness Shader ]. + * Assigns thicknesses values such as the thickness + * increases from a thickness value A to a thickness value B + * between the first vertex to the midpoint vertex and + * then decreases from B to a A between this midpoint vertex + * and the last vertex. + * The thickness is linearly interpolated from A to B. + */ + class LIB_STROKE_EXPORT IncreasingThicknessShader : public StrokeShader + { + public: + /*! Builds the shader. + * \param iThicknessMin + * The first thickness value. + * \param iThicknessMax + * The second thickness value. + */ + IncreasingThicknessShader(float iThicknessMin, float iThicknessMax) + : StrokeShader() + { + _ThicknessMin = iThicknessMin; + _ThicknessMax = iThicknessMax; + } + /*! Destructor.*/ + virtual ~IncreasingThicknessShader() {} + + virtual string getName() const { + return "IncreasingThicknessShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + + private: + + float _ThicknessMin; + float _ThicknessMax; + }; + + /*! [ Thickness shader ]. + * Same as previous but + * here we allow the user to control the ratio thickness/length so that + * we don't get fat short lines + */ + class LIB_STROKE_EXPORT ConstrainedIncreasingThicknessShader : public StrokeShader + { + private: + float _ThicknessMin; + float _ThicknessMax; + float _ratio; + public: + /*! Builds the shader. + * \param iThicknessMin + * The first thickness value. + * \param iThicknessMax + * The second thickness value. + * \param iRatio + * The ration thickness/length we don't want to + * exceed. + */ + ConstrainedIncreasingThicknessShader(float iThicknessMin, float iThicknessMax, float iRatio) + : StrokeShader() + { + _ThicknessMin = iThicknessMin; + _ThicknessMax = iThicknessMax; + _ratio = iRatio; + } + /*! Destructor.*/ + virtual ~ConstrainedIncreasingThicknessShader() {} + + virtual string getName() const { + return "ConstrainedIncreasingThicknessShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + }; + + /* [ Thickness Shader ]. + * Modifys the thickness in a relative way + * depending on its length. + */ + class LIB_STROKE_EXPORT LengthDependingThicknessShader : public StrokeShader + { + private: + float _minThickness; + float _maxThickness; + // We divide the strokes in 4 categories: + // l > 300 + // 100 < l < 300 + // 50 < l < 100 + // l < 50 + public: + LengthDependingThicknessShader(float iMinThickness, float iMaxThickness) + : StrokeShader() + { + _minThickness = iMinThickness; + _maxThickness = iMaxThickness; + } + virtual ~LengthDependingThicknessShader() {} + + virtual string getName() const { + return "LengthDependingThicknessShader"; + } + + virtual int shade(Stroke& stroke) const; + }; + + /*! [ Thickness Shader ]. + * Applys a pattern (texture) to vary thickness. + * The new thicknesses are the result of the multiplication + * of the pattern and the original thickness + */ + class LIB_STROKE_EXPORT ThicknessVariationPatternShader : public StrokeShader + { + public: + + /*! Builds the shader. + * \param pattern_name + * The texture file name. + * \param iMinThickness + * The minimum thickness we don't want to exceed. + * \param iMaxThickness + * The maximum thickness we don't want to exceed. + * \param stretch + * Tells whether the pattern texture must + * be stretched or repeted to fit the stroke. + */ + ThicknessVariationPatternShader(const string pattern_name, + float iMinThickness = 1.f, + float iMaxThickness = 5.f, + bool stretch = true); + /*! Destructor.*/ + virtual ~ThicknessVariationPatternShader() + { + if(0 != _aThickness) + { + delete [] _aThickness; + _aThickness = 0; + } + } + + virtual string getName() const { + return "ThicknessVariationPatternShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + + private: + + float* _aThickness; // array of thickness values, in % of the max (i.e comprised between 0 and 1) + unsigned _size; + float _minThickness; + float _maxThickness; + bool _stretch; + }; + + /*! [ Thickness Shader ]. + * Adds some noise to the stroke thickness. + * \see \htmlonly <a href=noise/noise.html>noise/noise.html</a>\endhtmlonly + */ + class LIB_STROKE_EXPORT ThicknessNoiseShader : public StrokeShader + { + private: + float _amplitude; + float _scale; + public: + ThicknessNoiseShader(); + /*! Builds a Thickness Noise Shader + * \param iAmplitude + * The amplitude of the noise signal + * \param iPeriod + * The period of the noise signal + */ + ThicknessNoiseShader(float iAmplitude, float iPeriod); + + virtual string getName() const { + return "ThicknessNoiseShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + }; + + + // + // Color shaders + // + ///////////////////////////////////////////////////////// + /*! [ Color Shader ]. + * Assigns a constant color to every vertices of the Stroke. + */ + class LIB_STROKE_EXPORT ConstantColorShader : public StrokeShader + { + public: + /*! Builds the shader from a user-specified color. + * \param iR + * The red component + * \param iG + * The green component + * \param iB + * The blue component + * \param iAlpha + * The alpha value + */ + ConstantColorShader(float iR, float iG, float iB, float iAlpha=1.f) + : StrokeShader() + { + _color[0] = iR; + _color[1] = iG; + _color[2] = iB; + _color[3] = iAlpha; + } + + virtual string getName() const { + return "ConstantColorShader"; + } + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + + private: + + float _color[4]; + }; + + /*! [ Color Shader ]. + * Assigns a varying color to the stroke. + * The user specifies 2 colors A and B. The stroke + * color will change linearly from A to B between the + * first and the last vertex. + */ + class LIB_STROKE_EXPORT IncreasingColorShader : public StrokeShader + { + private: + float _colorMin[4]; + float _colorMax[4]; + public: + /*! Builds the shader from 2 user-specified colors. + * \param iRm + * The first color red component + * \param iGm + * The first color green component + * \param iBm + * The first color blue component + * \param iAlpham + * The first color alpha value + * \param iRM + * The second color red component + * \param iGM + * The second color green component + * \param iBM + * The second color blue component + * \param iAlphaM + * The second color alpha value + */ + IncreasingColorShader(float iRm, float iGm, float iBm, float iAlpham, + float iRM, float iGM, float iBM, float iAlphaM) + : StrokeShader() + { + _colorMin[0] = iRm; + _colorMin[1] = iGm; + _colorMin[2] = iBm; + _colorMin[3] = iAlpham; + + _colorMax[0] = iRM; + _colorMax[1] = iGM; + _colorMax[2] = iBM; + _colorMax[3] = iAlphaM; + } + + virtual string getName() const { + return "IncreasingColorShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + }; + + /*! [ Color Shader ]. + * Applys a pattern to vary original color. + * The new color is the result of the multiplication + * of the pattern and the original color + */ + class LIB_STROKE_EXPORT ColorVariationPatternShader : public StrokeShader + { + public: + /*! Builds the shader from the pattern texture file name. + * \param pattern_name + * The file name of the texture file to use as pattern + * \param stretch + * Tells whether the texture must be strecthed or repeted + * to fit the stroke. + */ + ColorVariationPatternShader(const string pattern_name, bool stretch = true); + /*! Destructor */ + virtual ~ColorVariationPatternShader() + { + if(0 != _aVariation) + { + delete [] _aVariation; + _aVariation = 0; + } + } + + virtual string getName() const { + return "ColorVariationPatternShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + + private: + + float* _aVariation; // array of coef values, in % of the max (i.e comprised between 0 and 1) + unsigned _size; + bool _stretch; + }; + + /* [ Color Shader ]. + * Assigns a color to the stroke depending + * on the material of the shape to which ot belongs + * to. (Disney shader) + */ + class LIB_STROKE_EXPORT MaterialColorShader : public StrokeShader + { + private: + float _coefficient; + public: + MaterialColorShader(float coeff=1.f) + : StrokeShader() + {_coefficient=coeff;} + + virtual string getName() const { + return "MaterialColorShader"; + } + + virtual int shade(Stroke& stroke) const; + }; + + class LIB_STROKE_EXPORT CalligraphicColorShader : public StrokeShader + { + private: + int _textureId; + Vec2d _orientation; + public: + CalligraphicColorShader( + const Vec2d &iOrientation) + : StrokeShader() + { + _orientation=iOrientation; + _orientation.normalize(); + } + + virtual string getName() const { + return "CalligraphicColorShader"; + } + + virtual int shade(Stroke& stroke) const; + + }; + + /*! [ Color Shader ]. + * Shader to add noise to the stroke colors. + */ + class LIB_STROKE_EXPORT ColorNoiseShader : public StrokeShader + { + private: + float _amplitude; + float _scale; + + public: + ColorNoiseShader(); + /*! Builds a Color Noise Shader + * \param iAmplitude + * The amplitude of the noise signal + * \param iPeriod + * The period of the noise signal + */ + ColorNoiseShader(float iAmplitude, float iPeriod); + + virtual string getName() const { + return "ColorNoiseShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + }; + + // + // Texture Shaders + // + /////////////////////////////////////////////////////////////////////////////// + /*! [ Texture Shader ]. + * Assigns a texture to the stroke in order to simulate + * its marks system. This shader takes as input an integer value + * telling which texture and blending mode to use among a set of + * predefined textures. + * Here are the different presets: + * 0) -> /brushes/charcoalAlpha.bmp, HUMID_MEDIUM + * 1) -> /brushes/washbrushAlpha.bmp, HUMID_MEDIUM + * 2) -> /brushes/oil.bmp, HUMID_MEDIUM + * 3) -> /brushes/oilnoblend.bmp, HUMID_MEDIUM + * 4) -> /brushes/charcoalAlpha.bmp, DRY_MEDIUM + * 5) -> /brushes/washbrushAlpha.bmp, DRY_MEDIUM + * 6) -> /brushes/opaqueDryBrushAlpha.bmp, OPAQUE_MEDIUM + * 7) -> /brushes/opaqueBrushAlpha.bmp, Stroke::OPAQUE_MEDIUM + * Any other value will lead to the following preset: + * default) -> /brushes/smoothAlpha.bmp, OPAQUE_MEDIUM. + */ + class LIB_STROKE_EXPORT TextureAssignerShader : public StrokeShader // FIXME + { + private: + int _textureId; + public: + /*! Builds the shader. + * \param id + * The number of the preset to use. + */ + TextureAssignerShader(int id) + : StrokeShader() + { + _textureId = id; + } + + virtual string getName() const { + return "TextureAssignerShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; + + }; + /*! [ Texture Shader ]. + * Assigns a texture and a blending mode to the stroke + * in order to simulate its marks system. + */ + class LIB_STROKE_EXPORT StrokeTextureShader : public StrokeShader + { + private: + string _texturePath; + Stroke::MediumType _mediumType; + bool _tips; // 0 or 1 + + public: + /*! Builds the shader from the texture file name and the blending mode to use. + * \param textureFile + * The the texture file name. + * \attention The textures must be placed in the $FREESTYLE_DIR/data/textures/brushes + * directory. + * \param mediumType + * The medium type and therefore, the blending mode that must + * be used for the rendering of this stroke. + * \param iTips + * Tells whether the texture includes tips or not. + * If it is the case, the texture image must respect the following + * format: + * \verbatim + * __________ + * | | + * | A | + * |__________| + * | | | + * | B | C | + * |_____|____| + * + * \endverbatim + * - A : The stroke's corpus texture + * - B : The stroke's left extremity texture + * - C : The stroke's right extremity texture + */ + StrokeTextureShader(const string textureFile, Stroke::MediumType mediumType = Stroke::OPAQUE_MEDIUM, bool iTips = false) + : StrokeShader() + { + _texturePath = textureFile; + _mediumType = mediumType; + _tips = iTips; + } + + virtual string getName() const { + return "StrokeTextureShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; + + }; + + + // + // Geometry Shaders + // + /////////////////////////////////////////////////////////////////////////////// + /*! [ Geometry Shader ]. + * Stretches the stroke at its two extremities and following the + * respective directions: v(1)v(0) and v(n-1)v(n). + */ + class LIB_STROKE_EXPORT BackboneStretcherShader : public StrokeShader + { + private: + float _amount; + public: + /*! Builds the shader. + * \param iAmount + * The stretching amount value. + */ + BackboneStretcherShader(float iAmount=2.f) + : StrokeShader() + { + _amount = iAmount; + } + + virtual string getName() const { + return "BackboneStretcherShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; + }; + + /*! [ Geometry Shader. ] + * Resamples the stroke. + * @see Stroke::Resample(float). + */ + class LIB_STROKE_EXPORT SamplingShader: public StrokeShader + { + private: + float _sampling; + public: + /*! Builds the shader. + * \param sampling + * The sampling to use for the + * stroke resampling + */ + SamplingShader(float sampling) + : StrokeShader() + { + _sampling = sampling; + } + + virtual string getName() const { + return "SamplingShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; + }; + + + class LIB_STROKE_EXPORT ExternalContourStretcherShader : public StrokeShader + { + private: + float _amount; + public: + ExternalContourStretcherShader(float iAmount=2.f) + : StrokeShader() + { + _amount = iAmount; + } + + virtual string getName() const { + return "ExternalContourStretcherShader"; + } + + virtual int shade(Stroke& stroke) const; + }; + + // B-Spline stroke shader + class LIB_STROKE_EXPORT BSplineShader: public StrokeShader + { + public: + BSplineShader() + : StrokeShader() + {} + + virtual string getName() const { + return "BSplineShader"; + } + + virtual int shade(Stroke& stroke) const; + }; + + + // Bezier curve stroke shader + /*! [ Geometry Shader ]. + * Transforms the stroke backbone geometry + * so that it corresponds to a Bezier Curve + * approximation of the original backbone geometry. + * @see \htmlonly <a href=bezier/bezier.html>bezier/bezier.html</a> \endhtmlonly + */ + class LIB_STROKE_EXPORT BezierCurveShader : public StrokeShader + { + private: + float _error; + public: + /*! Builds the shader. + * \param error + * The error we're allowing for the approximation. + * This error is the max distance allowed between + * the new curve and the original geometry. + */ + BezierCurveShader(float error = 4.0) + : StrokeShader() + {_error=error;} + + virtual string getName() const { + return "BezierCurveShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; + }; + + /* Shader to inflate the curves. It keeps the extreme + * points positions and moves the other ones along + * the 2D normal. The displacement value is proportional + * to the 2d curvature at the considered point (the higher + * the curvature, the smaller the displacement) and to a value + * specified by the user. + */ + class LIB_STROKE_EXPORT InflateShader : public StrokeShader + { + private: + float _amount; + float _curvatureThreshold; + public: + /*! Builds an inflate shader + * \param iAmount + * A multiplicative coefficient that + * acts on the amount and direction of displacement + * \param iThreshold + * The curves having a 2d curvature > iThreshold + * at one of their points is not inflated + */ + InflateShader(float iAmount,float iThreshold) + : StrokeShader() + { + _amount = iAmount; + _curvatureThreshold = iThreshold; + } + + virtual string getName() const { + return "InflateShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; + }; + + /*! [ Geometry Shader ]. + * Shader to modify the Stroke geometry so that + * it looks more "polygonal". + * The basic idea is to start from the + * minimal stroke approximation consisting in + * a line joining the first vertex to the last one and + * to subdivide using the original stroke vertices + * until a certain error is reached. + */ + class LIB_STROKE_EXPORT PolygonalizationShader : public StrokeShader + { + private: + float _error; + public: + /*! Builds the shader. + * \param iError + * The error we want our polygonal approximation + * to have with respect to the original geometry. + * The smaller, the closer the new stroke to + * the orinal one. + * This error corresponds to the maximum distance + * between the new stroke and the old one. + */ + PolygonalizationShader(float iError) : StrokeShader() + {_error = iError;} + + virtual string getName() const { + return "PolygonalizationShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; + }; + + + /*! [ Geometry Shader ]. + * Shader to modify the Stroke geometry so that + * it corresponds to its main direction line. + * This shader must be used together with the + * splitting operator using the curvature criterion. + * Indeed, the precision of the approximation + * will depend on the size of the stroke's pieces. + * The bigger the pieces, the rougher the approximation. + */ + class LIB_STROKE_EXPORT GuidingLinesShader : public StrokeShader + { + private: + float _offset; + public: + /*! Builds a Guiding Lines shader + * \param iOffset + * The line that replaces the stroke + * is initially in the middle + * of the initial stroke "bbox". + * iOffset is the value of the displacement + * which is applied to this line along its + * normal. + */ + GuidingLinesShader(float iOffset) : StrokeShader() + {_offset = iOffset;} + + virtual string getName() const { + return "GuidingLinesShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; + }; + + /*! [ Geometry Shader ]. + * Removes the stroke's extremities. + */ + class LIB_STROKE_EXPORT TipRemoverShader : public StrokeShader + { + public: + /*! Builds the shader. + * \param tipLength + * The length of the piece of stroke + * we want to remove at each extremity. + */ + TipRemoverShader (real tipLength); + /*! Destructor. */ + virtual ~TipRemoverShader () {} + /*! The shading method */ + virtual string getName() const { + return "TipRemoverShader"; + } + + virtual int shade(Stroke &stroke) const; + + protected: + + real _tipLength; + }; + + /*! [ output Shader ]. + * streams the Stroke + */ + class LIB_STROKE_EXPORT streamShader : public StrokeShader + { + public: + /*! Destructor. */ + virtual ~streamShader() {} + /*! Returns the string "streamShader".*/ + virtual string getName() const { + return "streamShader"; + } + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + }; + + /*! [ output Shader ]. + * streams the Stroke in a file + */ + class LIB_STROKE_EXPORT fstreamShader : public StrokeShader + { + protected: + mutable ofstream _stream; + public: + /*! Builds the shader from the output file name */ + fstreamShader(const char *iFileName) : StrokeShader(){ + _stream .open(iFileName); + if(!_stream.is_open()){ + cout << "couldn't open file " << iFileName << endl; + } + } + /*! Destructor. */ + virtual ~fstreamShader() {_stream.close();} + /*! Returns the string "fstreamShader".*/ + virtual string getName() const { + return "fstreamShader"; + } + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + }; +} // end of namespace StrokeShaders + +#endif // BASIC_STROKE_SHADERS_H diff --git a/source/blender/freestyle/intern/stroke/Canvas.cpp b/source/blender/freestyle/intern/stroke/Canvas.cpp new file mode 100755 index 00000000000..7be2b54a036 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Canvas.cpp @@ -0,0 +1,454 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <vector> +#include "../system/FreestyleConfig.h" +#include "StrokeRenderer.h" +#include "../system/TimeStamp.h" +#include "../system/PseudoNoise.h" +#include "Canvas.h" +#include "../image/Image.h" +#include "../image/GaussianFilter.h" +#include "../image/ImagePyramid.h" +#include "../view_map/SteerableViewMap.h" +#include "StyleModule.h" + +//soc #include <qimage.h> +//soc #include <QString> +#include <sstream> + +extern "C" { +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +#include "intern/IMB_bmp.h" +} + +using namespace std; + +LIB_STROKE_EXPORT +Canvas * Canvas::_pInstance = 0; + +LIB_STROKE_EXPORT +const char * Canvas::_MapsPath = 0; + +using namespace std; + +Canvas::Canvas() +{ + _SelectedFEdge = 0; + _pInstance = this; + PseudoNoise::init(42); + _Renderer = 0; + _current_sm = NULL; + _steerableViewMap = new SteerableViewMap(NB_STEERABLE_VIEWMAP-1); + _basic = false; +} + +Canvas::Canvas(const Canvas& iBrother) +{ + _SelectedFEdge = iBrother._SelectedFEdge; + _pInstance = this; + PseudoNoise::init(42); + _Renderer = iBrother._Renderer; + _current_sm = iBrother._current_sm; + _steerableViewMap = new SteerableViewMap(*(iBrother._steerableViewMap)); + _basic = iBrother._basic; +} + +Canvas::~Canvas() +{ + _pInstance = 0; + + Clear(); + if(_Renderer) + { + delete _Renderer; + _Renderer = 0; + } + // FIXME: think about an easy control + // for the maps memory management... + if(!_maps.empty()){ + for(mapsMap::iterator m=_maps.begin(), mend=_maps.end(); + m!=mend; + ++m){ + delete ((*m).second); + } + _maps.clear(); + } + if(_steerableViewMap) + delete _steerableViewMap; +} + +void Canvas::preDraw() {} + +void Canvas::Draw() +{ + if(_StyleModules.empty()) + return; + preDraw(); + TimeStamp *timestamp = TimeStamp::instance(); + + for(unsigned i = 0; i < _StyleModules.size(); i++) { + _current_sm = _StyleModules[i]; + + if (i < _Layers.size() && _Layers[i]) + delete _Layers[i]; + + _Layers[i] = _StyleModules[i]->execute(); + if (!_Layers[i]) + continue; + + stroke_count += _Layers[i]->strokes_size(); + + timestamp->increment(); + } + postDraw(); +} + +void Canvas::postDraw() +{ + update(); +} + + +void Canvas::Clear() +{ + if(!_Layers.empty()) { + for (deque<StrokeLayer*>::iterator sl=_Layers.begin(), slend=_Layers.end(); + sl != slend; + ++sl) + if (*sl) + delete (*sl); + _Layers.clear(); + } + + if(!_StyleModules.empty()) { + for (deque<StyleModule*>::iterator s=_StyleModules.begin(), send=_StyleModules.end(); + s != send; + ++s) + if (*s) + delete (*s); + _StyleModules.clear(); + } + if(_steerableViewMap) + _steerableViewMap->Reset(); + + stroke_count = 0; +} + +void Canvas::Erase() +{ + if(!_Layers.empty()) + { + for (deque<StrokeLayer*>::iterator sl=_Layers.begin(), slend=_Layers.end(); + sl != slend; + ++sl) + if (*sl) + (*sl)->clear(); + } + if(_steerableViewMap) + _steerableViewMap->Reset(); + update(); + +stroke_count = 0; +} + +void Canvas::PushBackStyleModule(StyleModule *iStyleModule) { + StrokeLayer* layer = new StrokeLayer(); + _StyleModules.push_back(iStyleModule); + _Layers.push_back(layer); +} + +void Canvas::InsertStyleModule(unsigned index, StyleModule *iStyleModule) { + unsigned size = _StyleModules.size(); + StrokeLayer* layer = new StrokeLayer(); + if((_StyleModules.empty()) || (index == size)) { + _StyleModules.push_back(iStyleModule); + _Layers.push_back(layer); + return; + } + _StyleModules.insert(_StyleModules.begin() + index, iStyleModule); + _Layers.insert(_Layers.begin()+index, layer); +} + +void Canvas::RemoveStyleModule(unsigned index) +{ + unsigned i=0; + if (!_StyleModules.empty()) + { + for(deque<StyleModule*>::iterator s=_StyleModules.begin(), send=_StyleModules.end(); + s!=send; + ++s) + { + if(i == index) + { + // remove shader + if (*s) + delete *s; + _StyleModules.erase(s); + break; + } + ++i; + } + } + i=0; + if(!_Layers.empty()) + { + for(deque<StrokeLayer*>::iterator sl=_Layers.begin(), slend=_Layers.end(); + sl!=slend; + ++sl) + { + if(i == index) + { + // remove layer + if (*sl) + delete *sl; + _Layers.erase(sl); + break; + } + ++i; + } + } +} + + +void Canvas::SwapStyleModules(unsigned i1, unsigned i2) +{ + StyleModule* tmp; + tmp = _StyleModules[i1]; + _StyleModules[i1] = _StyleModules[i2]; + _StyleModules[i2] = tmp; + + StrokeLayer* tmp2; + tmp2 = _Layers[i1]; + _Layers[i1] = _Layers[i2]; + _Layers[i2] = tmp2; +} + +void Canvas::ReplaceStyleModule(unsigned index, StyleModule *iStyleModule) +{ + unsigned i=0; + for(deque<StyleModule*>::iterator s=_StyleModules.begin(), send=_StyleModules.end(); + s != send; + ++s) + { + if(i == index) + { + if (*s) + delete *s; + *s = iStyleModule; + break; + } + ++i; + } +} + +void Canvas::setVisible(unsigned index, bool iVisible) { + _StyleModules[index]->setDisplayed(iVisible); +} + +void Canvas::setModified(unsigned index, bool iMod) +{ + _StyleModules[index]->setModified(iMod); +} + +void Canvas::resetModified(bool iMod/* =false */) +{ + unsigned size = _StyleModules.size(); + for(unsigned i = 0; i < size; ++i) + setModified(i,iMod); +} + +void Canvas::causalStyleModules(vector<unsigned>& vec, unsigned index) { + unsigned size = _StyleModules.size(); + + for(unsigned i = index; i < size; ++i) + if (_StyleModules[i]->getCausal()) + vec.push_back(i); +} + +void Canvas::Render(const StrokeRenderer *iRenderer) +{ + for (unsigned i = 0; i < _StyleModules.size(); i++) { + if(!_StyleModules[i]->getDisplayed() || !_Layers[i]) + continue; + _Layers[i]->Render(iRenderer); + } +} + +void Canvas::RenderBasic(const StrokeRenderer *iRenderer) + +{ + for (unsigned i = 0; i < _StyleModules.size(); i++) { + if(!_StyleModules[i]->getDisplayed() || !_Layers[i]) + continue; + _Layers[i]->RenderBasic(iRenderer); + } +} + +void Canvas::loadMap(const char *iFileName, const char *iMapName, unsigned int iNbLevels, float iSigma){ + // check whether this map was already loaded: + if(!_maps.empty()){ + mapsMap::iterator m = _maps.find(iMapName); + if(m!=_maps.end()){ + // lazy check for size changes + ImagePyramid * pyramid = (*m).second; + if((pyramid->width() != width()) || (pyramid->height() != height())){ + delete pyramid; + }else{ + return; + } + } + } + string filePath; + if(_MapsPath){ + filePath = _MapsPath; + filePath += iFileName; + }else{ + filePath = iFileName; + } + + //soc + // QImage *qimg; + // QImage newMap(filePath.c_str()); + // if(newMap.isNull()){ + // cout << "Could not load image file " << filePath << endl; + // return; + // } + // qimg = &newMap; + ImBuf *qimg = IMB_loadiffname(filePath.c_str(), 0);; + if( qimg == 0 ){ + cout << "Could not load image file " << filePath << endl; + return; + } + + // soc + //resize + // QImage scaledImg; + // if((newMap.width()!=width()) || (newMap.height()!=height())){ + // scaledImg = newMap.scaled(width(), height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + // qimg = &scaledImg; + // } + ImBuf *scaledImg; + if( ( qimg->x != width() ) || ( qimg->y != height() ) ){ + scaledImg = IMB_dupImBuf(qimg); + IMB_scaleImBuf(scaledImg, width(), height()); + } + + + // deal with color image + // if(newMap->depth() != 8){ + // int w = newMap->width(); + // int h = newMap->height(); + // QImage *tmp = new QImage(w, h, 8); + // for(unsigned y=0;y<h;++y){ + // for(unsigned x=0;x<w;++x){ + // int c = qGray(newMap->pixel(x,y)); + // tmp->setPixel(x,y,c); + // } + // } + // delete newMap; + // newMap = tmp; + // } + + int x,y; + int w = qimg->x; + int h = qimg->y; +int rowbytes = w*4; + GrayImage tmp(w,h); + char *pix; + + for(y=0; y<h;++y){ + for(x=0;x<w;++x){ + pix = (char*)qimg->rect + y*rowbytes + x*4; + float c = (pix[0]*11 + pix[1]*16 + pix[2]*5)/32; + tmp.setPixel(x,y,c); + } + } + + // GrayImage blur(w,h); + // GaussianFilter gf(4.f); + // //int bound = gf.getBound(); + // for(y=0; y<h;++y){ + // for(x=0;x<w;++x){ + // int c = gf.getSmoothedPixel<GrayImage>(&tmp, x,y); + // blur.setPixel(x,y,c); + // } + // } + + GaussianPyramid *pyramid = new GaussianPyramid(tmp, iNbLevels, iSigma); + int ow = pyramid->width(0); + int oh = pyramid->height(0); + string base(iMapName); //soc + for(int i=0; i<pyramid->getNumberOfLevels(); ++i){ + // save each image: + // w = pyramid.width(i); + // h = pyramid.height(i); + + //soc QImage qtmp(ow, oh, QImage::Format_RGB32); + ImBuf *qtmp = IMB_allocImBuf(ow, oh, 32, IB_rect, 0); + +//int k = (1<<i); + for(y=0;y<oh;++y){ + for(x=0;x<ow;++x){ + int c = pyramid->pixel(x,y,i);//255*pyramid->pixel(x,y,i); + //soc qtmp.setPixel(x,y,qRgb(c,c,c)); + pix = (char*)qtmp->rect + y*rowbytes + x*4; + pix[0] = pix [1] = pix[2] = c; + } + } + //soc qtmp.save(base+QString::number(i)+".bmp", "BMP"); + stringstream filename; + filename << base; + filename << i << ".bmp"; + imb_savebmp(qtmp, const_cast<char *>(filename.str().c_str()), 0); + + } + // QImage *qtmp = new QImage(w, h, 32); + // for(y=0;y<h;++y){ + // for(x=0;x<w;++x){ + // int c = (int)blur.pixel(x,y); + // qtmp->setPixel(x,y,qRgb(c,c,c)); + // } + // } + // delete newMap; + // newMap = qtmp; + // + _maps[iMapName] = pyramid; + // newMap->save("toto.bmp", "BMP"); +} + +float Canvas::readMapPixel(const char *iMapName, int level, int x, int y){ + if(_maps.empty()){ + cout << "readMapPixel warning: no map was loaded "<< endl; + return -1; + } + mapsMap::iterator m = _maps.find(iMapName); + if(m==_maps.end()){ + cout << "readMapPixel warning: no map was loaded with the name " << iMapName << endl; + return -1; + } + ImagePyramid *pyramid = (*m).second; + if((x<0) || (x>=pyramid->width()) || (y<0) || (y>=pyramid->height())) + return 0; + + return pyramid->pixel(x,height()-1-y,level); +} diff --git a/source/blender/freestyle/intern/stroke/Canvas.h b/source/blender/freestyle/intern/stroke/Canvas.h new file mode 100755 index 00000000000..707455c87f6 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Canvas.h @@ -0,0 +1,196 @@ +// +// Filename : Canvas.h +// Author(s) : Stephane Grabli +// Purpose : Class to define a canvas designed to draw style modules +// Date of creation : 20/10/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CANVAS_H +# define CANVAS_H + +# include <cstring> +# include <deque> +# include <vector> +# include <map> +# include "../system/FreestyleConfig.h" +# include "StrokeLayer.h" +# include "../geometry/BBox.h" +# include "../geometry/Geom.h" + +using namespace Geometry; + +struct ltstr +{ + bool operator()(const char* s1, const char* s2) const + { + return strcmp(s1, s2) < 0; + } +}; + +class InformationMap; +class StrokeRenderer; +class ViewMap; +class ViewEdge; +class FEdge; +class RGBImage; +class GrayImage; +class QImage; +class ImagePyramid; +class SteerableViewMap; +class StyleModule; + +/*! Class to define the canvas on which strokes are drawn. + * It's used to store state information about the drawing. + */ +class LIB_STROKE_EXPORT Canvas +{ +public: + /*! Returns a pointer on the Canvas instance */ + static Canvas * getInstance() {return _pInstance;} + typedef std::map<const char*, ImagePyramid*, ltstr> mapsMap ; + static const int NB_STEERABLE_VIEWMAP = 5; +protected: + static Canvas *_pInstance; + std::deque<StrokeLayer*> _Layers; + std::deque<StyleModule*> _StyleModules; + FEdge *_SelectedFEdge; + + StrokeRenderer *_Renderer; + StyleModule* _current_sm; + mapsMap _maps; + static const char * _MapsPath; + SteerableViewMap *_steerableViewMap; + bool _basic; + +public: + /* Builds the Canvas */ + Canvas(); + /* Copy constructor */ + Canvas(const Canvas& iBrother); + /* Destructor */ + virtual ~Canvas(); + + /* operations that need to be done before a draw */ + virtual void preDraw(); + + /* Draw the canvas using the current shader */ + virtual void Draw(); + + /* operations that need to be done after a draw */ + virtual void postDraw(); + + /* Renders the created strokes */ + virtual void Render(const StrokeRenderer *iRenderer); + /* Basic Renders the created strokes */ + virtual void RenderBasic(const StrokeRenderer *iRenderer); + /* Renders a stroke */ + virtual void RenderStroke(Stroke *iStroke) = 0; + + /* init the canvas */ + virtual void init() = 0; + + /* Clears the Canvas (shaders stack, layers stack...)*/ + void Clear(); + + /* Erases the layers */ + virtual void Erase(); + + /* Reads a pixel area from the canvas */ + virtual void readColorPixels(int x, int y,int w, int h, RGBImage& oImage) const = 0; + /* Reads a depth pixel area from the canvas */ + virtual void readDepthPixels(int x, int y,int w, int h, GrayImage& oImage) const = 0; + + /* update the canvas (display) */ + virtual void update() = 0; + + /* checks whether the canvas is empty or not */ + bool isEmpty() const {return (_Layers.empty());} + + /* Maps management */ + /*! Loads an image map. The map will be scaled + * (without preserving the ratio in order + * to fit the actual canvas size.) + * The image must be a gray values image... + * \param iFileName + * The name of the image file + * \param iMapName + * The name that will be used to access + * this image + * \param iNbLevels + * The number of levels in the map pyramid. (default = 4). + * If iNbLevels == 0, the complete pyramid is built. + */ + void loadMap(const char *iFileName, const char *iMapName, unsigned iNbLevels=4, float iSigma = 1.f); + + /*! Reads a pixel value in a map. + * Returns a value between 0 and 1. + * \param iMapName + * The name of the map + * \param level + * The level of the pyramid from which the pixel must + * be read. + * \param x + * The abscissa of the desired pixel specified in level0 coordinate + * system. The origin is the lower left corner. + * \param y + * The ordinate of the desired pixel specified in level0 coordinate + * system. The origin is the lower left corner. + */ + float readMapPixel(const char *iMapName, int level, int x, int y); + + /*! Sets the steerable viewmap */ + void loadSteerableViewMap(SteerableViewMap * iSVM) {_steerableViewMap = iSVM;} + + /*! Returns the steerable VM */ + SteerableViewMap * getSteerableViewMap() {return _steerableViewMap;} + + /*! accessors */ + inline const FEdge * selectedFEdge() const {return _SelectedFEdge;} + inline FEdge * selectedFEdge() {return _SelectedFEdge;} + virtual int width() const = 0; + virtual int height() const = 0; + virtual BBox<Vec3r> scene3DBBox() const = 0; + inline const StrokeRenderer * renderer() const {return _Renderer;} + inline StyleModule* getCurrentStyleModule() { return _current_sm; } + virtual bool getRecordFlag() const {return false;} + int stroke_count; + + /*! modifiers */ + inline void setSelectedFEdge(FEdge *iFEdge) {_SelectedFEdge = iFEdge;} + /*! inserts a shader at pos index+1 */ + void PushBackStyleModule(StyleModule *iStyleModule); + void InsertStyleModule(unsigned index, StyleModule *iStyleModule); + void RemoveStyleModule(unsigned index); + void SwapStyleModules(unsigned i1, unsigned i2); + void ReplaceStyleModule(unsigned index, StyleModule *iStyleModule); + void setVisible(unsigned index, bool iVisible) ; + //inline void setDensityMap(InformationMap<RGBImage>* iMap) {_DensityMap = iMap;} + inline void AddLayer(StrokeLayer *iLayer) {_Layers.push_back(iLayer);} + void resetModified(bool iMod=false); + void causalStyleModules(std::vector<unsigned>& vec, unsigned index = 0); + void setModified(unsigned index, bool b); +}; + +#endif // CANVAS_H diff --git a/source/blender/freestyle/intern/stroke/Chain.cpp b/source/blender/freestyle/intern/stroke/Chain.cpp new file mode 100755 index 00000000000..3776cd58a03 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Chain.cpp @@ -0,0 +1,126 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "Chain.h" +#include "../view_map/ViewMapIterators.h" +#include "../view_map/ViewMapAdvancedIterators.h" + +void Chain::push_viewedge_back(ViewEdge *iViewEdge, bool orientation) +{ + ViewEdge::vertex_iterator v; + ViewEdge::vertex_iterator vend; + ViewEdge::vertex_iterator vfirst; + Vec3r previous, current; + if(true == orientation) + { + v=iViewEdge->vertices_begin(); + vfirst = v; + vend=iViewEdge->vertices_end(); + } + else + { + v=iViewEdge->vertices_last(); + vfirst = v; + vend=iViewEdge->vertices_end(); + } + + if(!_Vertices.empty()) + { + previous = _Vertices.back()->point2d(); + if(orientation) + ++v; + else + --v; + } + else + previous = (*v)->point2d(); + do{ + current = (*v)->point2d(); + Curve::push_vertex_back(*v); + //_Length += (current-previous).norm(); + previous = current; + if(orientation) + ++v; + else + --v; + }while((v!=vend) && (v!=vfirst)); + + if(v==vfirst) + { + //Add last one: + current = (*v)->point2d(); + Curve::push_vertex_back(*v); + //_Length += (current-previous).norm(); + } +} + +void Chain::push_viewedge_front(ViewEdge *iViewEdge, bool orientation) +{ + orientation = !orientation; + ViewEdge::vertex_iterator v; + ViewEdge::vertex_iterator vend; + ViewEdge::vertex_iterator vfirst; + Vec3r previous, current; + if(true == orientation) + { + v=iViewEdge->vertices_begin(); + vfirst = v; + vend=iViewEdge->vertices_end(); + } + else + { + v=iViewEdge->vertices_last(); + vfirst = v; + vend=iViewEdge->vertices_end(); + } + + if(!_Vertices.empty()) + { + previous = _Vertices.front()->point2d(); + if(orientation) + ++v; + else + --v; + } + else + previous = (*v)->point2d(); + do{ + current = (*v)->point2d(); + Curve::push_vertex_front((*v)); + //_Length += (current-previous).norm(); + previous = current; + if(orientation) + ++v; + else + --v; + }while((v!=vend) && (v!=vfirst)); + + if(v==vfirst) + { + //Add last one: + current = (*v)->point2d(); + Curve::push_vertex_front(*v); + //_Length += (current-previous).norm(); + } +} + + + diff --git a/source/blender/freestyle/intern/stroke/Chain.h b/source/blender/freestyle/intern/stroke/Chain.h new file mode 100755 index 00000000000..711ae16a1a0 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Chain.h @@ -0,0 +1,86 @@ +// +// Filename : Chain.h +// Author(s) : Stephane Grabli +// Purpose : Class to define a chain of viewedges. +// Date of creation : 09/01/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CHAIN_H +# define CHAIN_H + +# include "../view_map/ViewMap.h" +# include "Curve.h" +/*! Class to represent a 1D elements issued + * from the chaining process. + * A Chain is the last step before the Stroke and + * is used in the Splitting and Creation processes. + */ +class Chain : public Curve +{ +protected: + // tmp + Id * _splittingId; +public: + /*! Defult constructor. */ + Chain() : Curve() {_splittingId=0;} + /*! Builds a chain from its Id. */ + Chain(const Id& id) : Curve(id) {_splittingId=0;} + /*! Copy Constructor */ + Chain(const Chain& iBrother) : Curve(iBrother) {_splittingId=iBrother._splittingId;} + /*! Destructor. */ + virtual ~Chain() { + // only the last splitted deletes this id + if(_splittingId){ + if(*_splittingId == _Id) + delete _splittingId; + } + } + /*! Returns the string "Chain" */ + virtual string getExactTypeName() const { + return "Chain"; + } + + /*! Adds a ViewEdge at the end of the chain + * \param iViewEdge + * The ViewEdge that must be added. + * \param orientation + * The orientation with which this ViewEdge + * must be processed. + */ + void push_viewedge_back(ViewEdge *iViewEdge, bool orientation) ; + /*! Adds a ViewEdge at the beginning of the chain + * \param iViewEdge + * The ViewEdge that must be added. + * \param orientation + * The orientation with which this ViewEdge + * must be processed. + */ + void push_viewedge_front(ViewEdge *iViewEdge, bool orientation) ; + + inline void setSplittingId(Id * sid){_splittingId = sid;} + inline Id* getSplittingId() {return _splittingId;} +}; + +#endif // CHAIN_H diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp new file mode 100755 index 00000000000..c54ee6ea1ee --- /dev/null +++ b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp @@ -0,0 +1,170 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// +#include "ChainingIterators.h" +#include "../system/TimeStamp.h" + +ViewEdge* AdjacencyIterator::operator*() { + return (*_internalIterator).first; +} +bool AdjacencyIterator::isIncoming() const{ + return (*_internalIterator).second; +} + +int AdjacencyIterator::increment(){ + ++_internalIterator; + while((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first))) + ++_internalIterator; + return 0; +} + +bool AdjacencyIterator::isValid(ViewEdge* edge){ + if(_restrictToSelection) + if(edge->getTimeStamp() != TimeStamp::instance()->getTimeStamp()) + return false; + if(_restrictToUnvisited) + if(edge->getChainingTimeStamp() > TimeStamp::instance()->getTimeStamp()) + return false; + return true; +} + +int ChainingIterator::increment() { + _increment = true; + ViewVertex * vertex = getVertex(); + if(!vertex){ + _edge = 0; + return 0; + } + AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited); + if(it.isEnd()) { + _edge = 0; + return 0; + } + if (traverse(it) < 0) + return -1; + _edge = result; + if(_edge == 0) + return 0; + if(_edge->A() == vertex) + _orientation = true; + else + _orientation = false; + return 0; +} + +int ChainingIterator::decrement() { + _increment = false; + ViewVertex * vertex = getVertex(); + if(!vertex){ + _edge = 0; + return 0; + } + AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited); + if(it.isEnd()) { + _edge = 0; + return 0; + } + if (traverse(it) < 0) + return -1; + _edge = result; + if(_edge == 0) + return 0; + if(_edge->B() == vertex) + _orientation = true; + else + _orientation = false; + return 0; +} + +// +// ChainSilhouetteIterators +// +/////////////////////////////////////////////////////////// + +int ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait){ + AdjacencyIterator it(ait); + ViewVertex* nextVertex = getVertex(); + // we can't get a NULL nextVertex here, it was intercepted + // before + if(nextVertex->getNature() & Nature::T_VERTEX){ + TVertex * tvertex = (TVertex*)nextVertex; + ViewEdge *mate = (tvertex)->mate(getCurrentEdge()); + while(!it.isEnd()){ + ViewEdge *ve = *it; + if(ve == mate) { + result = ve; + return 0; + } + ++it; + } + result = 0; + return 0; + } + if(nextVertex->getNature() & Nature::NON_T_VERTEX){ + //soc NonTVertex * nontvertex = (NonTVertex*)nextVertex; + ViewEdge * newEdge(0); + // we'll try to chain the edges by keeping the same nature... + // the preseance order is : SILHOUETTE, BORDER, CREASE, SUGGESTIVE, VALLEY, RIDGE + Nature::EdgeNature natures[6] = {Nature::SILHOUETTE, Nature::BORDER, Nature::CREASE, Nature::SUGGESTIVE_CONTOUR, Nature::VALLEY, Nature::RIDGE}; + for(unsigned i=0; i<6; ++i){ + if(getCurrentEdge()->getNature() & natures[i]){ + int n = 0; + while(!it.isEnd()){ + ViewEdge *ve = *it; + if(ve->getNature() & natures[i]){ + ++n; + newEdge = ve; + } + ++it; + } + if(n == 1){ + result = newEdge; + }else{ + result = 0; + } + return 0; + } + } + } + result = 0; + return 0; +} + +int ChainPredicateIterator::traverse(const AdjacencyIterator& ait){ + AdjacencyIterator it(ait); + // Iterates over next edges to see if one of them + // respects the predicate: + while(!it.isEnd()) { + ViewEdge *ve = *it; + if (_unary_predicate->operator()(*ve) < 0) + return -1; + if (_unary_predicate->result) { + if (_binary_predicate->operator()(*(getCurrentEdge()), *(ve)) < 0) + return -1; + if (_binary_predicate->result) { + result = ve; + return 0; + } + } + ++it; + } + result = 0; + return 0; +} diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.h b/source/blender/freestyle/intern/stroke/ChainingIterators.h new file mode 100755 index 00000000000..ec093888aea --- /dev/null +++ b/source/blender/freestyle/intern/stroke/ChainingIterators.h @@ -0,0 +1,394 @@ +// +// Filename : ChainingIterators +// Author : Stephane Grabli +// Purpose : Chaining iterators +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef CHAININGITERATORS_H +# define CHAININGITERATORS_H + +# include <iostream> +# include "../view_map/ViewMap.h" +# include "../view_map/ViewMapIterators.h" +# include "../view_map/ViewMapAdvancedIterators.h" +# include "Predicates1D.h" + +#include "../system/Iterator.h" //soc + +# include "../python/Director.h" + +//using namespace ViewEdgeInternal; + +// +// Adjacency iterator used in the chaining process +// +/////////////////////////////////////////////////////////// +class LIB_STROKE_EXPORT AdjacencyIterator : public Iterator { +protected: + ViewVertexInternal::orientedViewEdgeIterator _internalIterator; + bool _restrictToSelection; + bool _restrictToUnvisited; +public: + AdjacencyIterator(){ + _restrictToSelection = true; + _restrictToUnvisited = true; + } + AdjacencyIterator(ViewVertex *iVertex, bool iRestrictToSelection = true, bool iRestrictToUnvisited = true){ + _restrictToSelection = iRestrictToSelection; + _restrictToUnvisited = iRestrictToUnvisited; + _internalIterator = iVertex->edgesBegin(); + while((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first))) + ++_internalIterator; + } + AdjacencyIterator(const AdjacencyIterator& iBrother){ + _internalIterator = iBrother._internalIterator; + _restrictToSelection = iBrother._restrictToSelection; + _restrictToUnvisited = iBrother._restrictToUnvisited; + } + AdjacencyIterator& operator=(const AdjacencyIterator& iBrother) { + _internalIterator = iBrother._internalIterator; + _restrictToSelection = iBrother._restrictToSelection; + _restrictToUnvisited = iBrother._restrictToUnvisited; + return *this; + } + virtual ~AdjacencyIterator(){ + } + + virtual string getExactTypeName() const { + return "AdjacencyIterator"; + } + + virtual inline bool isEnd() const { + return _internalIterator.isEnd(); + } + virtual inline bool isBegin() const { + return _internalIterator.isBegin(); + } + /*! Returns true if the current ViewEdge is is coming + * towards the iteration vertex. False otherwise. + */ + bool isIncoming() const ; + + /*! Returns a *pointer* to the pointed ViewEdge. */ + virtual ViewEdge* operator*() ; + virtual ViewEdge* operator->() {return operator*();} + virtual AdjacencyIterator& operator++() { + increment(); + return *this; + } + virtual AdjacencyIterator operator++(int) { + AdjacencyIterator tmp(*this); + increment(); + return tmp; + } + virtual int increment(); + + virtual int decrement(){ + cerr << "Warning: method decrement() not implemented" << endl; + return 0; + } + +protected: + bool isValid(ViewEdge* edge); +}; + +// +// Base class for Chaining Iterators +// +/////////////////////////////////////////////////////////// + +/*! Base class for chaining iterators. + * This class is designed to be overloaded + * in order to describe chaining rules. + * It makes the works of chaining rules description + * easier. + * The two main methods that need to overloaded are + * traverse() and init(). + * traverse() tells which ViewEdge to follow, among the adjacent ones. + * If you specify restriction rules (such as "Chain only + * ViewEdges of the selection"), they will be included + * in the adjacency iterator. (i.e, the adjacent iterator + * will only stop on "valid" edges). + */ +class LIB_STROKE_EXPORT ChainingIterator : public ViewEdgeInternal::ViewEdgeIterator{ +protected: + bool _restrictToSelection; + bool _restrictToUnvisited; + bool _increment; //true if we're currently incrementing, false when decrementing + +public: + + ViewEdge *result; + PyObject *py_c_it; + + /*! Builds a Chaining Iterator from the first ViewEdge used for iteration + * and its orientation. + * \param iRestrictToSelection + * Indicates whether to force the chaining to stay within + * the set of selected ViewEdges or not. + * \param iRestrictToUnvisited + * Indicates whether a ViewEdge that has already been chained + * must be ignored ot not. + * \param begin + * The ViewEdge from which to start the chain. + * \param orientation + * The direction to follow to explore the graph. If true, + * the direction indicated by the first ViewEdge is used. + */ + ChainingIterator(bool iRestrictToSelection = true, bool iRestrictToUnvisited = true, ViewEdge* begin = 0, bool orientation = true) + : ViewEdgeIterator(begin, orientation) { + _restrictToSelection = iRestrictToSelection; + _restrictToUnvisited = iRestrictToUnvisited; + _increment = true; + py_c_it = 0; + } + + /*! Copy constructor */ + ChainingIterator(const ChainingIterator& brother) + : ViewEdgeIterator(brother) { + _restrictToSelection = brother._restrictToSelection; + _restrictToUnvisited = brother._restrictToUnvisited; + _increment = brother._increment; + py_c_it = brother.py_c_it; + } + + /*! Returns the string "ChainingIterator" */ + virtual string getExactTypeName() const { + return "ChainingIterator"; + } + + /*! Inits the iterator context. + * This method is called each time + * a new chain is started. + * It can be used to reset some + * history information that you + * might want to keep. + */ + virtual int init() { + return Director_BPy_ChainingIterator_init( this ); + } + + /*! This method iterates over the potential next + * ViewEdges and returns the one that will be + * followed next. + * returns the next ViewEdge to follow or + * 0 when the end of the chain is reached. + * \param it + * The iterator over the ViewEdges adjacent to + * the end vertex of the current ViewEdge. + * The Adjacency iterator reflects the restriction + * rules by only iterating over the valid ViewEdges. + */ + virtual int traverse(const AdjacencyIterator &it){ + return Director_BPy_ChainingIterator_traverse( this, const_cast<AdjacencyIterator &>(it) ); + } + + /* accessors */ + /*! Returns true if the orientation of the current ViewEdge + * corresponds to its natural orientation + */ + //inline bool getOrientation() const {} + /*! Returns the vertex which is the next crossing */ + inline ViewVertex * getVertex() { + if(_increment){ + if(_orientation){ + return _edge->B(); + }else{ + return _edge->A(); + } + }else{ + if(_orientation){ + return _edge->A(); + }else{ + return _edge->B(); + } + } + } + + /*! Returns true if the current iteration is an incrementation */ + inline bool isIncrementing() const{ + return _increment; + } + + /* increments.*/ + virtual int increment() ; + virtual int decrement() ; +}; + +// +// Chaining iterators definitions +// +/////////////////////////////////////////////////////////// + +/*! A ViewEdge Iterator used to follow ViewEdges the most naturally. + * For example, it will follow visible ViewEdges of same nature. + * As soon, as the nature or the visibility changes, the iteration + * stops (by setting the pointed ViewEdge to 0). + * In the case of an iteration over a set of ViewEdge that are both + * Silhouette and Crease, there will be a precedence of the silhouette + * over the crease criterion. + */ +class LIB_STROKE_EXPORT ChainSilhouetteIterator : public ChainingIterator +{ +public: + /*! Builds a ChainSilhouetteIterator from the first ViewEdge used for iteration + * and its orientation. + * \param iRestrictToSelection + * Indicates whether to force the chaining to stay within + * the set of selected ViewEdges or not. + * \param begin + * The ViewEdge from where to start the iteration. + * \param orientation + * If true, we'll look for the next ViewEdge among the + * ViewEdges that surround the ending ViewVertex of begin. + * If false, we'll search over the ViewEdges surrounding + * the ending ViewVertex of begin. + */ + ChainSilhouetteIterator(bool iRestrictToSelection = true, ViewEdge* begin = NULL, bool orientation = true) + : ChainingIterator(iRestrictToSelection, true, begin, orientation) {} + + /*! Copy constructor */ + ChainSilhouetteIterator(const ChainSilhouetteIterator& brother) + : ChainingIterator(brother) {} + + /*! Returns the string "ChainSilhouetteIterator" */ + virtual string getExactTypeName() const { + return "ChainSilhouetteIterator"; + } + + /*! This method iterates over the potential next + * ViewEdges and returns the one that will be + * followed next. + * When reaching the end of a chain, 0 is returned. + */ + virtual int traverse(const AdjacencyIterator& it); + + /*! Inits the iterator context */ + virtual int init() { + return 0; + } +}; + +// +// ChainPredicateIterator +// +/////////////////////////////////////////////////////////// + +/*! A "generic" user-controlled ViewEdge iterator. This iterator + * is in particular built from a unary predicate and a binary predicate. + * First, the unary predicate is evaluated for all potential next ViewEdges + * in order to only keep the ones respecting a certain constraint. + * Then, the binary predicate is evaluated on the current ViewEdge + * together with each ViewEdge of the previous selection. The first + * ViewEdge respecting both the unary predicate and the binary predicate + * is kept as the next one. If none of the potential next ViewEdge respects + * these 2 predicates, 0 is returned. + */ +class LIB_STROKE_EXPORT ChainPredicateIterator : public ChainingIterator +{ +protected: + BinaryPredicate1D *_binary_predicate; // the caller is responsible for the deletion of this object + UnaryPredicate1D *_unary_predicate; // the caller is responsible for the deletion of this object +public: + + /*! Builds a ChainPredicateIterator from a starting ViewEdge and its orientation. + * \param iRestrictToSelection + * Indicates whether to force the chaining to stay within + * the set of selected ViewEdges or not. + * \param iRestrictToUnvisited + * Indicates whether a ViewEdge that has already been chained + * must be ignored ot not. + * \param begin + * The ViewEdge from where to start the iteration. + * \param orientation + * If true, we'll look for the next ViewEdge among the + * ViewEdges that surround the ending ViewVertex of begin. + * If false, we'll search over the ViewEdges surrounding + * the ending ViewVertex of begin. + */ + ChainPredicateIterator(bool iRestrictToSelection = true, bool iRestrictToUnvisited = true, ViewEdge* begin = NULL, bool orientation = true) + : ChainingIterator(iRestrictToSelection, iRestrictToUnvisited, begin, orientation) { + _binary_predicate = 0; + _unary_predicate = 0; + } + + /*! Builds a ChainPredicateIterator from a unary predicate, a binary predicate, a starting ViewEdge and its orientation. + * \param iRestrictToSelection + * Indicates whether to force the chaining to stay within + * the set of selected ViewEdges or not. + * \param iRestrictToUnvisited + * Indicates whether a ViewEdge that has already been chained + * must be ignored ot not. + * \param upred + * The unary predicate that the next ViewEdge must satisfy. + * \param bpred + * The binary predicate that the next ViewEdge must satisfy + * together with the actual pointed ViewEdge. + * \param begin + * The ViewEdge from where to start the iteration. + * \param orientation + * If true, we'll look for the next ViewEdge among the + * ViewEdges that surround the ending ViewVertex of begin. + * If false, we'll search over the ViewEdges surrounding + * the ending ViewVertex of begin. + */ + ChainPredicateIterator(UnaryPredicate1D& upred, BinaryPredicate1D& bpred, bool iRestrictToSelection = true, bool iRestrictToUnvisited = true, ViewEdge* begin = NULL, bool orientation = true) + : ChainingIterator(iRestrictToSelection, iRestrictToUnvisited, begin, orientation) { + _unary_predicate = &upred; + _binary_predicate = &bpred; + } + + /*! Copy constructor */ + ChainPredicateIterator(const ChainPredicateIterator& brother) + : ChainingIterator(brother){ + _unary_predicate = brother._unary_predicate; + _binary_predicate = brother._binary_predicate; + } + + /*! Destructor. */ + virtual ~ChainPredicateIterator(){ + _unary_predicate = 0; + _binary_predicate = 0; + } + + /*! Returns the string "ChainPredicateIterator" */ + virtual string getExactTypeName() const { + return "ChainPredicateIterator"; + } + + /*! This method iterates over the potential next + * ViewEdges and returns the one that will be + * followed next. + * When reaching the end of a chain, 0 is returned. + */ + virtual int traverse(const AdjacencyIterator &it); + + /*! Inits the iterator context */ + virtual int init() { + return 0; + } + +}; + +#endif // CHAININGITERATORS_H diff --git a/source/blender/freestyle/intern/stroke/ContextFunctions.cpp b/source/blender/freestyle/intern/stroke/ContextFunctions.cpp new file mode 100755 index 00000000000..b55da1fb0f8 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/ContextFunctions.cpp @@ -0,0 +1,60 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "ContextFunctions.h" +#include "../view_map/SteerableViewMap.h" +#include "../system/TimeStamp.h" +namespace ContextFunctions { + + unsigned GetTimeStampCF(){ + return TimeStamp::instance()->getTimeStamp(); + } + + unsigned GetCanvasWidthCF(){ + return Canvas::getInstance()->width(); + } + + unsigned GetCanvasHeightCF(){ + return Canvas::getInstance()->height(); + } + void LoadMapCF(const char *iFileName, const char *iMapName, unsigned iNbLevels, float iSigma ){ + return Canvas::getInstance()->loadMap(iFileName, iMapName, iNbLevels,iSigma); + } + + float ReadMapPixelCF(const char *iMapName, int level, unsigned x, unsigned y){ + Canvas * canvas = Canvas::getInstance(); + return canvas->readMapPixel(iMapName, level, x,y); + } + + float ReadCompleteViewMapPixelCF(int level, unsigned x, unsigned y){ + SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); + return svm->readCompleteViewMapPixel(level,x,y); + } + + float ReadDirectionalViewMapPixelCF(int iOrientation, int level, unsigned x, unsigned y){ + SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); + return svm->readSteerableViewMapPixel(iOrientation, level,x,y); + } + + FEdge * GetSelectedFEdgeCF(){ + return Canvas::getInstance()->selectedFEdge(); + } +} diff --git a/source/blender/freestyle/intern/stroke/ContextFunctions.h b/source/blender/freestyle/intern/stroke/ContextFunctions.h new file mode 100755 index 00000000000..37c98656fa7 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/ContextFunctions.h @@ -0,0 +1,124 @@ +// +// Filename : AdvancedFunctions0D.h +// Author(s) : Stephane Grabli +// Purpose : Functions related to context queries +// Date of creation : 20/12/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CONTEXT_FUNCTIONS_HPP +# define CONTEXT_FUNCTIONS_HPP + +# include "Canvas.h" +# include "../image/Image.h" +# include "../image/GaussianFilter.h" + +/*! \file ContextFunctions.h + * Interface to access the context related + * information. + */ +// +// Context Functions definitions +// +/////////////////////////////////////////////////////////// +/*! namespace containing all the Context related functions */ +namespace ContextFunctions { + + // GetTimeStamp + LIB_STROKE_EXPORT + /*! Returns the system time stamp */ + unsigned GetTimeStampCF(); + + // GetCanvasWidth + /*! Returns the canvas width */ + LIB_STROKE_EXPORT + unsigned GetCanvasWidthCF(); + + // GetCanvasHeight + /*! Returns the canvas width */ + LIB_STROKE_EXPORT + unsigned GetCanvasHeightCF(); + + // Load map + /*! Loads an image map for further reading */ + LIB_STROKE_EXPORT + void LoadMapCF(const char *iFileName, const char *iMapName, unsigned iNbLevels=4, float iSigma=1.f); + + // ReadMapPixel + /*! Reads a pixel in a user-defined map + * \return the floating value stored for that pixel + * \param iMapName + * The name of the map + * \param level + * The level of the pyramid in which we wish to read the pixel + * \param x + * The x-coordinate of the pixel we wish to read. The origin is + * in the lower-left corner. + * \param y + * The y-coordinate of the pixel we wish to read. The origin is + * in the lower-left corner. + */ + LIB_STROKE_EXPORT + float ReadMapPixelCF(const char *iMapName, int level, unsigned x, unsigned y); + + // ReadCompleteViewMapPixel + /*! Reads a pixel in the complete view map + * \return the floating value stored for that pixel + * \param level + * The level of the pyramid in which we wish to read the pixel + * \param x + * The x-coordinate of the pixel we wish to read. The origin is + * in the lower-left corner. + * \param y + * The y-coordinate of the pixel we wish to read. The origin is + * in the lower-left corner. + */ + LIB_STROKE_EXPORT + float ReadCompleteViewMapPixelCF(int level, unsigned x, unsigned y); + + // ReadOrientedViewMapPixel + /*! Reads a pixel in one of the oriented view map images + * \return the floating value stored for that pixel + * \param iOrientation + * The number telling which orientation we want to check + * \param level + * The level of the pyramid in which we wish to read the pixel + * \param x + * The x-coordinate of the pixel we wish to read. The origin is + * in the lower-left corner. + * \param y + * The y-coordinate of the pixel we wish to read. The origin is + * in the lower-left corner. + */ + LIB_STROKE_EXPORT + float ReadDirectionalViewMapPixelCF(int iOrientation, int level, unsigned x, unsigned y); + + // DEBUG + LIB_STROKE_EXPORT + FEdge * GetSelectedFEdgeCF(); + +} // end of namespace ContextFunctions + +#endif // CONTEXT_FUNCTIONS_HPP + diff --git a/source/blender/freestyle/intern/stroke/Curve.cpp b/source/blender/freestyle/intern/stroke/Curve.cpp new file mode 100755 index 00000000000..f7b255c3ef4 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Curve.cpp @@ -0,0 +1,818 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "Curve.h" +#include "CurveIterators.h" +#include "CurveAdvancedIterators.h" + + /**********************************/ + /* */ + /* */ + /* CurvePoint */ + /* */ + /* */ + /**********************************/ + +CurvePoint::CurvePoint() +{ + __A=0; + __B=0; + _t2d=0; +} + +CurvePoint::CurvePoint(SVertex *iA, SVertex *iB, float t) +{ + __A=iA; + __B=iB; + _t2d=t; + if((iA == 0) && (t == 1.f)) + { + _Point2d=__B->point2d(); + _Point3d=__B->point3d(); + } + else if((iB == 0) && (t == 0.f)) + { + _Point2d=__A->point2d(); + _Point3d=__A->point3d(); + } + else + { + _Point2d=__A->point2d()+_t2d*(__B->point2d()-__A->point2d()); + _Point3d=__A->point3d()+_t2d*(__B->point3d()-__A->point3d()); + } +} + +CurvePoint::CurvePoint(CurvePoint *iA, CurvePoint *iB, float t3) +{ + float t1=iA->t2d(); + float t2=iB->t2d(); + if((iA->A() == iB->A()) && (iA->B() == iB->B()) && (iA->A() != 0) && (iA->B() != 0) && (iB->A() != 0) && (iB->B() != 0)) + { + __A=iA->A(); + __B=iB->B(); + _t2d=t1+t2*t3-t1*t3; + } + else if((iA->B() == 0) && (iB->B() == 0)) + { + __A = iA->A(); + __B = iB->A(); + _t2d = t3; + } + else if((iA->t2d() == 0) && (iB->t2d() == 0)) + { + __A = iA->A(); + __B = iB->A(); + _t2d = t3; + } + else if(iA->A() == iB->A()){ + if(iA->t2d() == 0){ + __A = iB->A(); + __B = iB->B(); + _t2d = t3; + }else if(iB->t2d() == 0){ + __A = iA->A(); + __B = iA->B(); + _t2d = t3; + } + }else if(iA->B() == iB->B()){ + if(iA->t2d() == 1){ + __A = iB->A(); + __B = iB->B(); + _t2d = t3; + }else if(iB->t2d() == 1){ + __A = iA->A(); + __B = iA->B(); + _t2d = t3; + } + } + else if(iA->B() == iB->A()) + { + if((iA->t2d() != 1.f) && (iB->t2d() == 0.f)) + { + __A = iA->A(); + __B = iA->B(); + _t2d=t1+t3-t1*t3; + //_t2d = t3; + } + else if((iA->t2d() == 1.f) && (iB->t2d() != 0.f)) + { + __A = iB->A(); + __B = iB->B(); + //_t2d = t3; + _t2d=t2*t3; + } + + } + //_Point2d=__A->point2d()+_t2d*(__B->point2d()-__A->point2d()); + //_Point3d=__A->point3d()+_t2d*(__B->point3d()-__A->point3d()); + + _Point2d= iA->point2d()+t3*(iB->point2d()-iA->point2d()); + _Point3d=__A->point3d()+_t2d*(__B->point3d()-__A->point3d()); +} + +CurvePoint::CurvePoint(const CurvePoint& iBrother) +{ + __A=iBrother.__A; + __B=iBrother.__B; + _t2d=iBrother._t2d; + _Point2d=iBrother._Point2d; + _Point3d=iBrother._Point3d; +} + +CurvePoint& CurvePoint::operator=(const CurvePoint& iBrother) +{ + __A=iBrother.__A; + __B=iBrother.__B; + _t2d=iBrother._t2d; + _Point2d=iBrother._Point2d; + _Point3d=iBrother._Point3d; + return *this; +} + + +FEdge *CurvePoint::fedge() +{ + if(getNature() & Nature::T_VERTEX) + return 0; + return __A->fedge(); +} + + +FEdge* CurvePoint::getFEdge(Interface0D& inter) +{ + CurvePoint* iVertexB = dynamic_cast<CurvePoint*>(&inter); + if (!iVertexB) + return 0; + if(((__A == iVertexB->__A) && (__B == iVertexB->__B)) + || + ((__A == iVertexB->__B) && (__B == iVertexB->__A))) + return __A->getFEdge(*__B); + else if(__B == 0) + { + if(iVertexB->__B == 0) + return __A->getFEdge(*(iVertexB->__A)); + else if(iVertexB->__A == __A) + return __A->getFEdge(*(iVertexB->__B)); + else if(iVertexB->__B == __A) + return __A->getFEdge(*(iVertexB->__A)); + } + else if(iVertexB->__B == 0) + { + if(iVertexB->__A == __A) + return __B->getFEdge(*(iVertexB->__A)); + else if(iVertexB->__A == __B) + return __A->getFEdge(*(iVertexB->__A)); + } + else if(__B == iVertexB->__A) + { + if((_t2d != 1) && (iVertexB->_t2d == 0)) + return __A->getFEdge(*__B); + if((_t2d == 1) && (iVertexB->_t2d != 0)) + return iVertexB->__A->getFEdge(*(iVertexB->__B)); + } + else if(__B == iVertexB->__B) + { + if((_t2d != 1) && (iVertexB->_t2d == 1)) + return __A->getFEdge(*__B); + if((_t2d == 1) && (iVertexB->_t2d != 1)) + return iVertexB->__A->getFEdge(*(iVertexB->__B)); + } + else if(__A == iVertexB->__A) + { + if((_t2d == 0) && (iVertexB->_t2d != 0)) + return iVertexB->__A->getFEdge(*(iVertexB->__B)); + if((_t2d != 0) && (iVertexB->_t2d == 0)) + return __A->getFEdge(*__B); + } + else if(__A == iVertexB->__B) + { + if((_t2d == 0) && (iVertexB->_t2d != 1)) + return iVertexB->__A->getFEdge(*(iVertexB->__B)); + if((_t2d != 0) && (iVertexB->_t2d == 1)) + return __A->getFEdge(*__B); + } + + cerr << "Warning: you should not be there..." << endl; + + return 0; +} + + + Vec3r CurvePoint::normal() const +{ + if(__B == 0) + return __A->normal(); + if(__A == 0) + return __B->normal(); + Vec3r Na = __A->normal(); + if(Exception::getException()) + Na = Vec3r(0,0,0); + Vec3r Nb = __B->normal(); + if(Exception::getException()) + Nb = Vec3r(0,0,0); + // compute t3d: + real t3d = SilhouetteGeomEngine::ImageToWorldParameter(__A->getFEdge(*__B),_t2d); + return ((1-t3d)*Na+t3d*Nb); +} + + + // Material CurvePoint::material() const + //{ + // if(__A == 0) + // return __B->material(); + // return __A->material(); + //} + + +// Id CurvePoint::shape_id() const +// { +// if(__A == 0) +// return __B->shape_id(); +// return __A->shape_id(); +// } + + + const SShape * CurvePoint::shape() const +{ + if(__A == 0) + return __B->shape(); + return __A->shape(); +} + + + +// float CurvePoint::shape_importance() const +// { + +// if(__A == 0) + +// return __B->shape_importance(); +// return __A->shape_importance(); +// } + + + // const unsigned CurvePoint::qi() const + //{ + // if(__A == 0) + // return __B->qi(); + // if(__B == 0) + // return __A->qi(); + // return __A->getFEdge(*__B)->qi(); + //} + + + occluder_container::const_iterator CurvePoint::occluders_begin() const +{ + if(__A == 0) + return __B->occluders_begin(); + if(__B == 0) + return __A->occluders_begin(); + return __A->getFEdge(*__B)->occluders_begin(); +} + + occluder_container::const_iterator CurvePoint::occluders_end() const +{ + if(__A == 0) + return __B->occluders_end(); + if(__B == 0) + return __A->occluders_end(); + return __A->getFEdge(*__B)->occluders_end(); +} + + bool CurvePoint::occluders_empty() const +{ + if(__A == 0) + return __B->occluders_empty(); + if(__B == 0) + return __A->occluders_empty(); + return __A->getFEdge(*__B)->occluders_empty(); +} + + int CurvePoint::occluders_size() const +{ + if(__A == 0) + return __B->occluders_size(); + if(__B == 0) + return __A->occluders_size(); + return __A->getFEdge(*__B)->occluders_size(); +} + + const SShape * CurvePoint::occluded_shape() const +{ + if(__A == 0) + return __B->occluded_shape(); + if(__B == 0) + return __A->occluded_shape(); + return __A->getFEdge(*__B)->occluded_shape(); +} + + const Polygon3r& CurvePoint::occludee() const +{ + if(__A == 0) + return __B->occludee(); + if(__B == 0) + return __A->occludee(); + return __A->getFEdge(*__B)->occludee(); +} + + const bool CurvePoint::occludee_empty() const +{ + if(__A == 0) + return __B->occludee_empty(); + if(__B == 0) + return __A->occludee_empty(); + return __A->getFEdge(*__B)->occludee_empty(); +} + + real CurvePoint::z_discontinuity() const +{ + if(__A == 0) + return __B->z_discontinuity(); + if(__B == 0) + return __A->z_discontinuity(); + if(__A->getFEdge(*__B) == 0) + return 0.0; + + return __A->getFEdge(*__B)->z_discontinuity(); +} +// +// float CurvePoint::local_average_depth() const +//{ +// return local_average_depth_function<CurvePoint >(this); +//} +// +// float CurvePoint::local_depth_variance() const +//{ +// return local_depth_variance_function<CurvePoint >(this); +//} +// +// real CurvePoint::local_average_density(float sigma) const +//{ +// //return local_average_density<CurvePoint >(this); +// +// return density_function<CurvePoint >(this); +//} +// Vec3r shaded_color() const ; +// +// Vec3r CurvePoint::orientation2d() const +// { +// if(__A == 0) +// return __B->orientation2d(); +// if(__B == 0) +// return __A->orientation2d(); +// return __B->point2d()-__A->point2d(); +// } +// +// Vec3r CurvePoint::orientation3d() const +// { +// if(__A == 0) +// return __B->orientation3d(); +// if(__B == 0) +// return __A->orientation3d(); +// return __B->point3d()-__A->point3d(); +// } + +// real curvature2d() const {return viewedge()->curvature2d((_VertexA->point2d()+_VertexB->point2d())/2.0);} +// +// Vec3r CurvePoint::curvature2d_as_vector() const +//{ +// // Vec3r edgeA = (_FEdges[0])->orientation2d().normalize(); +// // Vec3r edgeB = (_FEdges[1])->orientation2d().normalize(); +// // return edgeA+edgeB; +// // +// if(__A == 0) +// return __B->curvature2d_as_vector(); +// if(__B == 0) +// return __A->curvature2d_as_vector(); +// return ((1-_t2d)*__A->curvature2d_as_vector()+_t2d*__B->curvature2d_as_vector()); +//} +// +// real CurvePoint::curvature2d_as_angle() const +//{ +// // Vec3r edgeA = (_FEdges[0])->orientation2d(); +// // Vec3r edgeB = (_FEdges[1])->orientation2d(); +// // Vec2d N1(-edgeA.y(), edgeA.x());N1.normalize(); +// // Vec2d N2(-edgeB.y(), edgeB.x());N2.normalize(); +// // return acos((N1*N2)); +// +// if(__A == 0) +// return __B->curvature2d_as_angle(); +// if(__B == 0) +// return __A->curvature2d_as_angle(); +// return ((1-_t2d)*__A->curvature2d_as_angle()+_t2d*__B->curvature2d_as_angle()); +//} + + +real CurvePoint::curvatureFredo() const +{ + if(__A == 0) + return __B->curvatureFredo(); + if(__B == 0) + return __A->curvatureFredo(); + return ((1-_t2d)*__A->curvatureFredo()+_t2d*__B->curvatureFredo()); +} + +Vec2d CurvePoint::directionFredo () const +{ + if(__A == 0) + return __B->directionFredo(); + if(__B == 0) + return __A->directionFredo(); + return ((1-_t2d)*__A->directionFredo()+_t2d*__B->directionFredo()); +} + + /**********************************/ + /* */ + /* */ + /* Curve */ + /* */ + /* */ + /**********************************/ + +/* for functions */ + + +Curve::~Curve() +{ + if(!_Vertices.empty()) + { + for(vertex_container::iterator it=_Vertices.begin(), itend =_Vertices.end(); + it!=itend; + ++it) + { + delete (*it); + } + _Vertices.clear(); + } +} + +/*! iterators access */ +Curve::point_iterator Curve::points_begin(float step) +{ + vertex_container::iterator second = _Vertices.begin();++second; + return point_iterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), _nSegments, step, 0.f, 0.f); + //return point_iterator(_Vertices.begin(), second, _nSegments, step, 0.f, 0.f); +} +Curve::const_point_iterator Curve::points_begin(float step) const +{ + vertex_container::const_iterator second = _Vertices.begin();++second; + return const_point_iterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), _nSegments, step, 0.f, 0.f); + //return const_point_iterator(_Vertices.begin(), second, _nSegments, step, 0.f, 0.f); +} +Curve::point_iterator Curve::points_end(float step) +{ + return point_iterator(_Vertices.end(), _Vertices.end(), _Vertices.begin(), _Vertices.end(), _nSegments, step, 1.f, _Length); + //return point_iterator(_Vertices.end(), _Vertices.end(), _nSegments, step, 1.f, _Length); +} +Curve::const_point_iterator Curve::points_end(float step) const +{ + return const_point_iterator(_Vertices.end(), _Vertices.end(), _Vertices.begin(), _Vertices.end(), _nSegments, step, 1.f, _Length); + //return const_point_iterator(_Vertices.end(), _Vertices.end(), _nSegments, step, 1.f, _Length); +} + +// Adavnced Iterators access +Curve::point_iterator Curve::vertices_begin(){return points_begin(0);} +Curve::const_point_iterator Curve::vertices_begin() const {return points_begin(0);} +Curve::point_iterator Curve::vertices_end(){return points_end(0);} +Curve::const_point_iterator Curve::vertices_end() const {return points_end(0);} + +// specialized iterators access +CurveInternal::CurvePointIterator Curve::curvePointsBegin(float t){ + vertex_container::iterator second = _Vertices.begin();++second; + return CurveInternal::CurvePointIterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), 0, _nSegments, _Length, t, 0.f, 0.f); +} + +CurveInternal::CurvePointIterator Curve::curvePointsEnd(float t){ + vertex_container::iterator last = _Vertices.end();--last; + return CurveInternal::CurvePointIterator(last, _Vertices.end(), _Vertices.begin(), _Vertices.end(), _nSegments, _nSegments, _Length, t, 0.f, _Length); +} + +CurveInternal::CurvePointIterator Curve::curveVerticesBegin(){ + return curvePointsBegin(0); +} + +CurveInternal::CurvePointIterator Curve::curveVerticesEnd(){ + return curvePointsEnd(0); +} + +Interface0DIterator Curve::pointsBegin(float t){ + vertex_container::iterator second = _Vertices.begin();++second; + Interface0DIterator ret(new CurveInternal::CurvePointIterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), 0, _nSegments, _Length, t, 0.f, 0.f)); + return ret; +} + +Interface0DIterator Curve::pointsEnd(float t){ + vertex_container::iterator last = _Vertices.end();--last; + Interface0DIterator ret(new CurveInternal::CurvePointIterator(last, _Vertices.end(), _Vertices.begin(), _Vertices.end(), _nSegments, _nSegments, _Length, t, 0.f, _Length)); + return ret; +} + +Interface0DIterator Curve::verticesBegin(){ + return pointsBegin(0); +} + +Interface0DIterator Curve::verticesEnd(){ + return pointsEnd(0); +} + + +// Vec3r shaded_color(int iCombination = 0) const ; +// +// Vec3r Curve::orientation2d(point_iterator it) const +//{ +// return (*it)->orientation2d(); +//} +/* template <class BaseVertex> */ +/* Vec3r Curve::orientation2d(int iCombination) const */ +/* { */ +/* return edge_orientation2d_function<Curve >(this, iCombination); */ +/* } */ +// +// Vec3r Curve::orientation3d(point_iterator it) const +//{ +// return (*it)->orientation3d(); +//} +/* */ +/* Vec3r Curve::orientation3d(int iCombination) const */ +/* { */ +/* return edge_orientation3d_function<Curve >(this, iCombination); */ +/* } */ +// real curvature2d(point_iterator it) const {return (*it)->curvature2d();} +// real curvature2d(int iCombination = 0) const ; + +// Material Curve::material() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// const Material& mat = (*v)->material(); +// for(;v!=vend;++v) +// { +// if((*v)->material() != mat) +// Exception::raiseException(); +// } +// return mat; +//} + +// int Curve::qi() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// int qi_= (*v)->qi(); +// for(;v!=vend;++v) +// { +// if((*v)->qi() != qi_) +// Exception::raiseException(); +// } +// return qi_; +//} +// occluder_container::const_iterator occluders_begin() const {return _FEdgeA->occluders().begin();} +// occluder_container::const_iterator occluders_end() const {return _FEdgeA->occluders().end();} + +//int Curve::occluders_size() const +//{ +// return qi(); +//} + +// bool Curve::occluders_empty() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// bool empty = (*v)->occluders_empty(); +// for(;v!=vend;++v) +// { +// if((*v)->occluders_empty() != empty) +// Exception::raiseException(); +// } +// return empty; +//} +// const Polygon3r& occludee() const {return *(_FEdgeA->aFace());} + +// const SShape * Curve::occluded_shape() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// const SShape *sshape = (*v)->occluded_shape(); +// for(;v!=vend;++v) +// { +// if((*v)->occluded_shape() != sshape) +// Exception::raiseException(); +// } +// return sshape; +//} + + +// const bool Curve::occludee_empty() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// bool empty = (*v)->occludee_empty(); +// for(;v!=vend;++v) +// { +// if((*v)->occludee_empty() != empty) +// Exception::raiseException(); +// } +// return empty; +//} +/* */ +/* real Curve::z_discontinuity(int iCombination) const */ +/* { */ +/* return z_discontinuity_edge_function<Curve >(this, iCombination); */ +/* } */ + +// int Curve::shape_id() const +// { +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// Id id = (*v)->shape_id(); +// for(;v!=vend;++v) +// { +// if((*v)->shape_id() != id) +// Exception::raiseException(); +// } +// return id.first; +// } + + +// const SShape * Curve::shape() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// const SShape *sshape = (*v)->shape(); +// for(;v!=vend;++v) +// { +// if((*v)->shape() != sshape) +// Exception::raiseException(); +// } +// return sshape; +//} + + +// occluder_container::const_iterator Curve::occluders_begin() const +//{ +// const_vertex_iterator v=vertices_begin(); +// return (*v)->occluders_begin(); +//} +// +// +// occluder_container::const_iterator Curve::occluders_end() const +//{ +// const_vertex_iterator v=vertices_end(); +// return (*v)->occluders_end(); +//} + +/* */ +/* Vec3r Curve::curvature2d_as_vector(int iCombination) const */ +/* { */ +/* return curvature2d_as_vector_edge_function<Curve >(this, iCombination); */ +/* } */ +/* */ +/* real Curve::curvature2d_as_angle(int iCombination) const */ +/* { */ +/* return curvature2d_as_angle_edge_function<Curve >(this, iCombination); */ +/* } */ + +/* */ +/* float Curve::shape_importance(int iCombination) const */ +/* { */ +/* return shape_importance_edge_function<Curve >(this, iCombination); */ +/* } */ + +/* */ +/* float Curve::local_average_depth(int iCombination) const */ +/* { */ +/* return local_average_depth_edge_function<Curve >(this, iCombination); */ +/* } */ +/* */ +/* float Curve::local_depth_variance(int iCombination ) const */ +/* { */ +/* return local_depth_variance_edge_function<Curve >(this, iCombination); */ +/* // local_depth_variance_functor<Point> functor; */ +/* // float result; */ +/* // Evaluate<float, local_depth_variance_functor<Point> >(&functor, iCombination, result); */ +/* // return result; */ +/* } */ + +/* */ +/* real Curve::local_average_density(float sigma, int iCombination ) const */ +/* { */ +/* return density_edge_function<Curve >(this, iCombination); */ +/* // density_functor<Point> functor; */ +/* // real result; */ +/* // Evaluate<real, density_functor<Point> >(&functor, iCombination, result); */ +/* // return result; */ +/* } */ + +#define EPS_CURVA_DIR 0.01 + + +void Curve::computeCurvatureAndOrientation () +{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(), v2, prevV, v0; +// Vec2d p0, p1, p2; +// Vec3r p; + +// p=(*v)->point2d(); +// p0=Vec2d(p[0], p[1]); +// prevV=v; ++v; +// p=(*v)->point2d(); +// p1=Vec2d(p[0], p[1]); +// Vec2d prevDir(p1-p0); + +// for(;v!=vend;++v) +// { +// v2=v; ++v2; +// if (v2==vend) break; +// Vec3r p2=(*v2)->point2d(); + +// Vec2d BA=p0-p1; +// Vec2d BC=p2-p1; +// real lba=BA.norm(), lbc=BC.norm(); +// BA.normalizeSafe(); +// BC.normalizeSafe(); +// Vec2d normalCurvature=BA+BC; +// Vec2d dir=Vec2d(BC-BA); +// Vec2d normal=Vec2d(-dir[1], dir[0]); + +// normal.normalizeSafe(); +// real curvature=normalCurvature*normal; +// if (lba+lbc > MY_EPSILON) +// curvature/=(0.5*lba+lbc); +// if (dir.norm() < MY_EPSILON) +// dir=0.1*prevDir; +// (*v)->setCurvatureFredo(curvature); +// (*v)->setDirectionFredo(dir); + +// prevV=v; p0=p1; p1=p2; prevDir=dir; prevDir.normalize(); +// } +// (*v)->setCurvatureFredo((*prevV)->curvatureFredo()); +// (*v)->setDirectionFredo((*v)->point2d()-(*prevV)->point2d()); +// v0=vertices_begin(); v2=v0; ++v2; +// (*v0)->setCurvatureFredo((*v2)->curvatureFredo()); +// (*v0)->setDirectionFredo((*v2)->point2d()-(*v0)->point2d()); + +// //closed curve case one day... + +// // +// return; + +// //numerical degeneracy verification.. we'll see later +// const_vertex_iterator vLastReliable=vertices_begin(); + +// v=vertices_begin(); +// p=(*v)->point2d(); +// p0=Vec2d(p[0], p[1]); +// prevV=v; ++v; +// p=(*v)->point2d(); +// p1=Vec2d(p[0], p[1]); +// bool isReliable=false; +// if ((p1-p0).norm>EPS_CURVA) +// { +// vLastReliable=v; +// isReliable=true; +// } + +// for(;v!=vend;++v) +// { +// v2=v; ++v2; +// if (v2==vend) break; +// Vec3r p2=(*v2)->point2d(); + +// Vec2d BA=p0-p1; +// Vec2d BC=p2-p1; +// real lba=BA.norm(), lbc=BC.norm(); + +// if ((lba+lbc)<EPS_CURVA) +// { +// isReliable=false; +// cerr<<"/"; +// } +// else +// { +// if (!isReliable)//previous points were not reliable +// { +// const_vertex_iterator vfix=vLastReliable; +// vfix++; +// for (; vfix!=v; ++vfix) +// { +// (*vfix)->setCurvatureFredo((*v)->curvatureFredo()); +// (*vfix)->setDirectionFredo((*v)->directionFredo()); +// } +// } +// isReliable=true; +// vLastReliable=v; +// } +// prevV=v; p0=p1; p1=p2; +// } + +} diff --git a/source/blender/freestyle/intern/stroke/Curve.h b/source/blender/freestyle/intern/stroke/Curve.h new file mode 100755 index 00000000000..52a0dda1f17 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Curve.h @@ -0,0 +1,467 @@ +// +// Filename : Curve.h +// Author(s) : Stephane Grabli +// Purpose : Class to define a container for curves +// Date of creation : 11/01/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CURVE_H +# define CURVE_H + +# include <deque> +# include "../system/BaseIterator.h" +# include "../geometry/Geom.h" +//# include "../scene_graph/FrsMaterial.h" +# include "../view_map/Silhouette.h" +# include "../view_map/SilhouetteGeomEngine.h" +# include "../view_map/Interface0D.h" +# include "../view_map/Interface1D.h" + +using namespace std; +using namespace Geometry; + + /**********************************/ + /* */ + /* */ + /* CurvePoint */ + /* */ + /* */ + /**********************************/ + +/*! Class to represent a point of a curve. + * A CurvePoint can be any point of a 1D curve + * (it doesn't have to be a vertex of the curve). + * Any Interface1D is built upon ViewEdges, themselves + * built upon FEdges. Therefore, a curve is basically + * a polyline made of a list SVertex. + * Thus, a CurvePoint is built by lineraly interpolating + * two SVertex. + * CurvePoint can be used as virtual points while + * querying 0D information along a curve at a given resolution. + */ +class LIB_STROKE_EXPORT CurvePoint : public Interface0D +{ +public: // Implementation of Interface0D + /*! Returns the string "CurvePoint"*/ + virtual string getExactTypeName() const { + return "CurvePoint"; + } + + // Data access methods + /*! Returns the 3D X coordinate of the point */ + virtual real getX() const { + return _Point3d.x(); + } + /*! Returns the 3D Y coordinate of the point */ + virtual real getY() const { + return _Point3d.y(); + } + /*! Returns the 3D Z coordinate of the point */ + virtual real getZ() const { + return _Point3d.z(); + } + /*! Returns the 3D point. */ + virtual Vec3f getPoint3D() const { + return _Point3d; + } + /*! Returns the projected 3D X coordinate of the point */ + virtual real getProjectedX() const { + return _Point2d.x(); + } + /*! Returns the projected 3D Y coordinate of the point */ + virtual real getProjectedY() const { + return _Point2d.y(); + } + /*! Returns the projected 3D Z coordinate of the point */ + virtual real getProjectedZ() const { + return _Point2d.z(); + } + /*! Returns the 2D point. */ + virtual Vec2f getPoint2D() const { + return Vec2f((float)_Point2d.x(),(float)_Point2d.y()); + } + + virtual FEdge* getFEdge(Interface0D& inter); + /*! Returns the CurvePoint's Id */ + virtual Id getId() const { + Id id; + if(_t2d == 0) + return __A->getId(); + else if(_t2d == 1) + return __B->getId(); + return id; + } + /*! Returns the CurvePoint's Nature */ + virtual Nature::VertexNature getNature() const { + Nature::VertexNature nature = Nature::POINT; + if(_t2d == 0) + nature |= __A->getNature(); + else if(_t2d == 1) + nature |= __B->getNature(); + return nature; + } + + /*! Cast the Interface0D in SVertex if it can be. */ + virtual SVertex * castToSVertex(){ + if(_t2d == 0) + return __A; + else if(_t2d == 1) + return __B; + return Interface0D::castToSVertex(); + } + + /*! Cast the Interface0D in ViewVertex if it can be. */ + virtual ViewVertex * castToViewVertex(){ + if(_t2d == 0) + return __A->castToViewVertex(); + else if(_t2d == 1) + return __B->castToViewVertex(); + return Interface0D::castToViewVertex(); + } + + /*! Cast the Interface0D in NonTVertex if it can be. */ + virtual NonTVertex * castToNonTVertex(){ + if(_t2d == 0) + return __A->castToNonTVertex(); + else if(_t2d == 1) + return __B->castToNonTVertex(); + return Interface0D::castToNonTVertex(); + } + + /*! Cast the Interface0D in TVertex if it can be. */ + virtual TVertex * castToTVertex(){ + if(_t2d == 0) + return __A->castToTVertex(); + else if(_t2d == 1) + return __B->castToTVertex(); + return Interface0D::castToTVertex(); + } +public: + typedef SVertex vertex_type; +protected: + SVertex *__A; + SVertex *__B; + float _t2d; + //float _t3d; + Vec3r _Point2d; + Vec3r _Point3d; +public: + /*! Defult Constructor. */ + CurvePoint(); + /*! Builds a CurvePoint from two SVertex and an interpolation + * parameter. + * \param iA + * The first SVertex + * \param iB + * The second SVertex + * \param t2d + * A 2D interpolation parameter + * used to linearly interpolate \a iA and \a iB + */ + CurvePoint(SVertex *iA, SVertex *iB, float t2d) ; + /*! Builds a CurvePoint from two CurvePoint and an interpolation parameter. + * \param iA + * The first CurvePoint + * \param iB + * The second CurvePoint + * \param t2d + * The 2D interpolation parameter used + * to linearly interpolate \a iA and \a iB. + */ + CurvePoint(CurvePoint *iA, CurvePoint *iB, float t2d) ; + // CurvePoint(SVertex *iA, SVertex *iB, float t2d, float t3d) ; + /*! Copy Constructor. */ + CurvePoint(const CurvePoint& iBrother) ; + /*! Operator = */ + CurvePoint& operator=(const CurvePoint& iBrother) ; + /*! Destructor */ + virtual ~CurvePoint() {} + /*! Operator == */ + bool operator==(const CurvePoint& b){ + return ((__A==b.__A) && (__B==b.__B) && (_t2d==b._t2d)); + } + + /* accessors */ + /*! Returns the first SVertex upon which + * the CurvePoint is built. */ + inline SVertex * A() {return __A;} + /*! Returns the second SVertex upon which + * the CurvePoint is built. */ + inline SVertex * B() {return __B;} + /*! Returns the interpolation parameter. */ + inline float t2d() const {return _t2d;} + //inline const float t3d() const {return _t3d;} + + /* modifiers */ + /*! Sets the first SVertex upon which to build + * the CurvePoint. + */ + inline void setA(SVertex *iA) {__A = iA;} + /*! Sets the second SVertex upon which to build + * the CurvePoint. + */ + inline void setB(SVertex *iB) {__B = iB;} + /*! Sets the 2D interpolation parameter to use. + */ + inline void setT2d(float t) {_t2d = t;} + //inline void SetT3d(float t) {_t3d = t;} + + /* Information access interface */ + + FEdge *fedge() ; + inline const Vec3r& point2d() const {return _Point2d;} + inline const Vec3r& point3d() const {return _Point3d;} + Vec3r normal() const ; + //FrsMaterial material() const ; + // Id shape_id() const ; + const SShape * shape() const ; + // float shape_importance() const ; + + //const unsigned qi() const ; + occluder_container::const_iterator occluders_begin() const ; + occluder_container::const_iterator occluders_end() const ; + bool occluders_empty() const ; + int occluders_size() const ; + const Polygon3r& occludee() const ; + const SShape * occluded_shape() const ; + const bool occludee_empty() const ; + real z_discontinuity() const ; + // float local_average_depth() const ; + // float local_depth_variance() const ; + // real local_average_density(float sigma = 2.3f) const ; + // Vec3r shaded_color() const ; +// Vec3r orientation2d() const ; +// Vec3r orientation3d() const ; + // // real curvature2d() const {return viewedge()->curvature2d((_VertexA->point2d()+_VertexB->point2d())/2.0);} + // Vec3r curvature2d_as_vector() const ; + // /*! angle in radians */ + // real curvature2d_as_angle() const ; + + real curvatureFredo () const; + Vec2d directionFredo () const; +}; + + + /**********************************/ + /* */ + /* */ + /* Curve */ + /* */ + /* */ + /**********************************/ + +namespace CurveInternal { + class CurvePoint_const_traits; + class CurvePoint_nonconst_traits; + template<class Traits> class __point_iterator; + class CurvePointIterator; +} // end of namespace CurveInternal + +/*! Base class for curves made of CurvePoints. + * SVertex is the type of the initial curve vertices. + * A Chain is a specialization of a Curve. + */ +class LIB_STROKE_EXPORT Curve : public Interface1D +{ +public: + typedef CurvePoint Vertex; + typedef CurvePoint Point; + typedef Point point_type; + typedef Vertex vertex_type; + typedef deque<Vertex*> vertex_container; + + /* Iterator to iterate over a vertex edges */ + + typedef CurveInternal::__point_iterator<CurveInternal::CurvePoint_nonconst_traits > point_iterator; + typedef CurveInternal::__point_iterator<CurveInternal::CurvePoint_const_traits > const_point_iterator; + typedef point_iterator vertex_iterator ; + typedef const_point_iterator const_vertex_iterator ; + +protected: + vertex_container _Vertices; + double _Length; + Id _Id; + unsigned _nSegments; // number of segments + +public: + /*! Default Constructor. */ + Curve() {_Length = 0;_Id = 0;_nSegments=0;} + /*! Builds a Curve from its id */ + Curve(const Id& id) {_Length = 0;_Id = id;_nSegments=0;} + /*! Copy Constructor. */ + Curve(const Curve& iBrother) {_Length = iBrother._Length;_Vertices = iBrother._Vertices;_Id=iBrother._Id;_nSegments=0;} + /*! Destructor. */ + virtual ~Curve() ; + /*! Returns the string "Curve" */ + virtual string getExactTypeName() const { + return "Curve"; + } + + /* + fredo's curvature storage + */ + void computeCurvatureAndOrientation (); + + /*! Adds a single vertex (CurvePoint) at the end of the Curve */ + inline void push_vertex_back(Vertex *iVertex) + { + if(!_Vertices.empty()) + { + Vec3r vec_tmp(iVertex->point2d() - _Vertices.back()->point2d()); + _Length += vec_tmp.norm(); + ++_nSegments; + } + Vertex * new_vertex = new Vertex(*iVertex); + _Vertices.push_back(new_vertex); + } + /*! Adds a single vertex (SVertex) at the end of the Curve */ + inline void push_vertex_back(SVertex *iVertex) + { + if(!_Vertices.empty()) + { + Vec3r vec_tmp(iVertex->point2d() - _Vertices.back()->point2d()); + _Length += vec_tmp.norm(); + ++_nSegments; + } + Vertex *new_vertex = new Vertex(iVertex, 0,0); + _Vertices.push_back(new_vertex); + } + /*! Adds a single vertex (CurvePoint) at the front of the Curve */ + inline void push_vertex_front(Vertex *iVertex) + { + if(!_Vertices.empty()) + { + Vec3r vec_tmp(iVertex->point2d() - _Vertices.front()->point2d()); + _Length += vec_tmp.norm(); + ++_nSegments; + } + Vertex * new_vertex = new Vertex(*iVertex); + _Vertices.push_front(new_vertex); + } + /*! Adds a single vertex (SVertex) at the front of the Curve */ + inline void push_vertex_front(SVertex *iVertex) + { + if(!_Vertices.empty()) + { + Vec3r vec_tmp(iVertex->point2d() - _Vertices.front()->point2d()); + _Length += vec_tmp.norm(); + ++_nSegments; + } + Vertex *new_vertex = new Vertex(iVertex, 0,0); + _Vertices.push_front(new_vertex); + } + /*! Returns true is the Curve doesn't have any Vertex yet. */ + inline bool empty() const {return _Vertices.empty();} + /*! Returns the 2D length of the Curve.*/ + inline real getLength2D() const {return _Length;} + /*! Returns the Id of the 1D element .*/ + virtual Id getId() const { + return _Id; + } + /*! Returns the number of segments in the + * oplyline constituing the Curve. + */ + inline unsigned int nSegments() const {return _nSegments;} + + inline void setId(const Id& id){_Id = id;} + /* Information access interface */ + + + //inline Vec3r shaded_color(int iCombination = 0) const ; + // inline Vec3r orientation2d(point_iterator it) const ; + //Vec3r orientation2d(int iCombination = 0) const ; + // Vec3r orientation3d(point_iterator it) const ; + //Vec3r orientation3d(int iCombination = 0) const ; + // real curvature2d(point_iterator it) const {return (*it)->curvature2d();} + // real curvature2d(int iCombination = 0) const ; + //FrsMaterial material() const ; + //int qi() const ; + // occluder_container::const_iterator occluders_begin() const ; + // occluder_container::const_iterator occluders_end() const ; + //int occluders_size() const; + //bool occluders_empty() const ; + // const Polygon3r& occludee() const {return *(_FEdgeA->aFace());} + //const SShape * occluded_shape() const; + //const bool occludee_empty() const ; + //real z_discontinuity(int iCombination = 0) const ; + // int shape_id() const ; + //const SShape * shape() const ; + //float shape_importance(int iCombination=0) const ; + //float local_average_depth(int iCombination = 0) const; + //float local_depth_variance(int iCombination = 0) const ; + //real local_average_density(float sigma = 2.3f, int iCombination = 0) const ; + //Vec3r curvature2d_as_vector(int iCombination=0) const ; + /*! angle in radians */ + //real curvature2d_as_angle(int iCombination=0) const ; + + /* advanced iterators access */ + point_iterator points_begin(float step = 0); + const_point_iterator points_begin(float step = 0) const; + point_iterator points_end(float step = 0); + const_point_iterator points_end(float step = 0) const; + + // methods given for convenience */ + point_iterator vertices_begin(); + const_point_iterator vertices_begin() const; + point_iterator vertices_end(); + const_point_iterator vertices_end() const; + + // specialized iterators access + CurveInternal::CurvePointIterator curvePointsBegin(float t=0.f); + CurveInternal::CurvePointIterator curvePointsEnd(float t=0.f); + + CurveInternal::CurvePointIterator curveVerticesBegin(); + CurveInternal::CurvePointIterator curveVerticesEnd(); + + // Iterators access + /*! Returns an Interface0DIterator pointing onto + * the first vertex of the Curve and that can iterate + * over the \a vertices of the Curve. + */ + virtual Interface0DIterator verticesBegin(); + /*! Returns an Interface0DIterator pointing after + * the last vertex of the Curve and that can iterate + * over the \a vertices of the Curve. + */ + virtual Interface0DIterator verticesEnd(); + /*! Returns an Interface0DIterator pointing onto + * the first point of the Curve and that can iterate + * over the \a points of the Curve at any resolution. + * At each iteration a virtual temporary CurvePoint + * is created. + */ + virtual Interface0DIterator pointsBegin(float t=0.f); + /*! Returns an Interface0DIterator pointing after + * the last point of the Curve and that can iterate + * over the \a points of the Curve at any resolution. + * At each iteration a virtual temporary CurvePoint + * is created. + */ + virtual Interface0DIterator pointsEnd(float t=0.f); +}; + + + +#endif diff --git a/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h b/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h new file mode 100755 index 00000000000..dfc9f2719f8 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h @@ -0,0 +1,378 @@ +// +// Filename : CurveAdvancedIterators.h +// Author(s) : Stephane Grabli +// Purpose : Iterators used to iterate over the elements of the Curve +// Can't be used in python +// Date of creation : 01/08/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef ADVANCEDCURVEITERATORS_H +# define ADVANCEDCURVEITERATORS_H + +# include "Stroke.h" + +namespace CurveInternal { + + class CurvePoint_const_traits : public Const_traits<CurvePoint*> { + public: + typedef deque<CurvePoint*> vertex_container; + typedef vertex_container::const_iterator vertex_container_iterator; + typedef SVertex vertex_type; + }; + + class CurvePoint_nonconst_traits : public Nonconst_traits<CurvePoint*> { + public: + typedef deque<CurvePoint*> vertex_container; + typedef vertex_container::iterator vertex_container_iterator ; + typedef SVertex vertex_type; + }; + + /**********************************/ + /* */ + /* */ + /* CurvePoint Iterator */ + /* */ + /* */ + /**********************************/ + + + /*! iterator on a curve. Allows an iterating outside + * initial vertices. A CurvePoint is instanciated an returned + * when the iterator is dereferenced. + */ + + template<class Traits> + class __point_iterator : public IteratorBase<Traits, BidirectionalIteratorTag_Traits> + { + public: + typedef __point_iterator <Traits> Self; + typedef typename Traits::vertex_container_iterator vertex_container_iterator; + typedef typename Traits::vertex_type vertex_type; + typedef CurvePoint Point; + typedef Point point_type; + + typedef __point_iterator<CurvePoint_nonconst_traits > iterator; + typedef __point_iterator<CurvePoint_const_traits > const_iterator; + + // public: + // typedef Vertex vertex_type ; + // typedef vertex_container_iterator vertex_iterator_type; + // typedef CurvePoint<Vertex> Point; + // typedef Point point_type; + typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class; + //# if defined(__GNUC__) && (__GNUC__ < 3) + // typedef bidirectional_iterator<CurvePoint<Vertex>,ptrdiff_t> bidirectional_point_iterator; + //# else + // typedef iterator<bidirectional_iterator_tag, CurvePoint<Vertex>,ptrdiff_t> bidirectional_point_iterator; + //# endif + friend class Curve; + //friend class Curve::vertex_iterator; + //friend class __point_iterator<CurvePoint_nonconst_traits >; + //friend class iterator; + //protected: + public: + float _CurvilinearLength; + float _step; + vertex_container_iterator __A; + vertex_container_iterator __B; + vertex_container_iterator _begin; + vertex_container_iterator _end; + int _n; + int _currentn; + float _t; + mutable Point *_Point; + + public: + + public: + inline __point_iterator(float step = 0.f) + : parent_class() + { + _step = step; + _CurvilinearLength = 0.f; + _t = 0.f; + _Point = 0; + _n = 0; + _currentn = 0; + } + + inline __point_iterator(const iterator& iBrother) + : parent_class() + { + __A = iBrother.__A; + __B = iBrother.__B; + _begin = iBrother._begin; + _end = iBrother._end; + _CurvilinearLength = iBrother._CurvilinearLength; + _step = iBrother._step; + _t = iBrother._t; + if(iBrother._Point == 0) + _Point = 0; + else + _Point = new Point(*(iBrother._Point)); + _n = iBrother._n; + _currentn = iBrother._currentn; + } + inline __point_iterator(const const_iterator& iBrother) + : parent_class() + { + __A = iBrother.__A; + __B = iBrother.__B; + _begin = iBrother._begin; + _end = iBrother._end; + _CurvilinearLength = iBrother._CurvilinearLength; + _step = iBrother._step; + _t = iBrother._t; + if(iBrother._Point == 0) + _Point = 0; + else + _Point = new Point(*(iBrother._Point)); + _n = iBrother._n; + _currentn = iBrother._currentn; + } + inline Self& operator=(const Self& iBrother) + { + //((bidirectional_point_iterator*)this)->operator=(iBrother); + __A = iBrother.__A; + __B = iBrother.__B; + _begin = iBrother._begin; + _end = iBrother._end; + _CurvilinearLength = iBrother._CurvilinearLength; + _step = iBrother._step; + _t = iBrother._t; + if(iBrother._Point == 0) + _Point = 0; + else + _Point = new Point(*(iBrother._Point)); + _n = iBrother._n; + _currentn = iBrother._currentn; + return *this; + } + virtual ~__point_iterator() + { + if(_Point != 0) + delete _Point; + } + //protected://FIXME + public: + inline __point_iterator(vertex_container_iterator iA, + vertex_container_iterator iB, + vertex_container_iterator ibegin, + vertex_container_iterator iend, + int currentn, + int n, + float step, float t=0.f, float iCurvilinearLength = 0.f) + : parent_class() + { + __A = iA; + __B = iB; + _begin = ibegin; + _end = iend; + _CurvilinearLength = iCurvilinearLength; + _step = step; + _t = t; + _Point = 0; + _n = n; + _currentn = currentn; + } + + public: + + // operators + inline Self& operator++() // operator corresponding to ++i + { + increment(); + return *this; + } + inline Self operator++(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + increment(); // dans un temporaire. + return tmp; + } + inline Self& operator--() // operator corresponding to ++i + { + decrement(); + return *this; + } + inline Self operator--(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + decrement(); // dans un temporaire. + return tmp; + } + + // comparibility + virtual bool operator!=(const Self& b) const + { + return ((__A!=b.__A) || (__B!=b.__B) || (_t != b._t)); + } + virtual bool operator==(const Self& b) const + { + return !(*this != b); + } + + // dereferencing + virtual typename Traits::reference operator*() const + { + if(_Point != 0) + { + delete _Point; + _Point = 0; + } + if((_currentn < 0) || (_currentn >= _n)) + return _Point; // 0 in this case + return (_Point = new Point(*__A,*__B,_t)); + } + virtual typename Traits::pointer operator->() const { return &(operator*());} + + public: + virtual bool begin() const + { + if((__A == _begin) && (_t < (float)M_EPSILON)) + return true; + return false; + } + virtual bool end() const + { + if((__B == _end)) + return true; + return false; + } + protected: + virtual void increment() + { + if(_Point != 0) + { + delete _Point; + _Point = 0; + } + if((_currentn == _n-1) && (_t == 1.f)) + { + // we're setting the iterator to end + ++__A; + ++__B; + ++_currentn; + _t = 0.f; + return; + } + + if(0 == _step) // means we iterate over initial vertices + { + Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); + _CurvilinearLength += vec_tmp.norm(); + if(_currentn == _n-1) + { + _t = 1.f; + return; + } + ++__B; + ++__A; + ++_currentn; + return; + } + + // compute the new position: + Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); + float normAB = vec_tmp2.norm(); + + if(normAB > M_EPSILON) + { + _CurvilinearLength += _step; + _t = _t + _step/normAB; + } + else + _t = 1.f; // AB is a null segment, we're directly at its end + //if normAB ~= 0, we don't change these values + if(_t >= 1) + { + _CurvilinearLength -= normAB*(_t-1); + if(_currentn == _n-1) + _t=1.f; + else + { + _t = 0.f; + ++_currentn; + ++__A;++__B; + } + } + } + virtual void decrement() + { + if(_Point != 0) + { + delete _Point; + _Point = 0; + } + + if(_t == 0.f) //we're at the beginning of the edge + { + _t = 1.f; + --_currentn; + --__A; --__B; + if(_currentn == _n-1) + return; + } + + if(0 == _step) // means we iterate over initial vertices + { + Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); + _CurvilinearLength -= vec_tmp.norm(); + _t = 0; + return; + } + + // compute the new position: + Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); + float normAB = vec_tmp2.norm(); + + if(normAB >M_EPSILON) + { + _CurvilinearLength -= _step; + _t = _t - _step/normAB; + } + else + _t = -1.f; // We just need a negative value here + + // round value + if(fabs(_t) < (float)M_EPSILON) + _t = 0.0; + if(_t < 0) + { + if(_currentn == 0) + _CurvilinearLength = 0.f; + else + _CurvilinearLength += normAB*(-_t); + _t = 0.f; + } + } + }; + + + +} // end of namespace StrokeInternal + + +#endif // ADVANCEDCURVEITERATORS_H diff --git a/source/blender/freestyle/intern/stroke/CurveIterators.h b/source/blender/freestyle/intern/stroke/CurveIterators.h new file mode 100755 index 00000000000..a45ef4bfdaf --- /dev/null +++ b/source/blender/freestyle/intern/stroke/CurveIterators.h @@ -0,0 +1,299 @@ +// +// Filename : CurveIterators.h +// Author(s) : Stephane Grabli +// Purpose : Iterators used to iterate over the elements of the Curve +// Date of creation : 01/08/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CURVEITERATORS_H +# define CURVEITERATORS_H + +#include "Stroke.h" +#include "Curve.h" + +namespace CurveInternal { + + /*! iterator on a curve. Allows an iterating outside + * initial vertices. A CurvePoint is instanciated an returned + * when the iterator is dereferenced. + */ + + class CurvePointIterator : public Interface0DIteratorNested + { + public: + friend class ::Curve; + public: + float _CurvilinearLength; + float _step; + ::Curve::vertex_container::iterator __A; + ::Curve::vertex_container::iterator __B; + ::Curve::vertex_container::iterator _begin; + ::Curve::vertex_container::iterator _end; + int _n; + int _currentn; + float _t; + mutable CurvePoint _Point; + float _CurveLength; + + public: + + public: + inline CurvePointIterator(float step = 0.f) + : Interface0DIteratorNested() + { + _step = step; + _CurvilinearLength = 0.f; + _t = 0.f; + //_Point = 0; + _n = 0; + _currentn = 0; + _CurveLength=0; + } + + inline CurvePointIterator(const CurvePointIterator& iBrother) + : Interface0DIteratorNested() + { + __A = iBrother.__A; + __B = iBrother.__B; + _begin = iBrother._begin; + _end = iBrother._end; + _CurvilinearLength = iBrother._CurvilinearLength; + _step = iBrother._step; + _t = iBrother._t; + _Point = iBrother._Point; + _n = iBrother._n; + _currentn = iBrother._currentn; + _CurveLength = iBrother._CurveLength; + } + inline CurvePointIterator& operator=(const CurvePointIterator& iBrother) + { + __A = iBrother.__A; + __B = iBrother.__B; + _begin = iBrother._begin; + _end = iBrother._end; + _CurvilinearLength = iBrother._CurvilinearLength; + _step = iBrother._step; + _t = iBrother._t; + _Point = iBrother._Point; + _n = iBrother._n; + _currentn = iBrother._currentn; + _CurveLength = iBrother._CurveLength; + return *this; + } + virtual ~CurvePointIterator() + { + } + protected: + inline CurvePointIterator(::Curve::vertex_container::iterator iA, + ::Curve::vertex_container::iterator iB, + ::Curve::vertex_container::iterator ibegin, + ::Curve::vertex_container::iterator iend, + int currentn, + int n, + float iCurveLength, + float step, float t=0.f, float iCurvilinearLength = 0.f) + : Interface0DIteratorNested() + { + __A = iA; + __B = iB; + _begin = ibegin; + _end = iend; + _CurvilinearLength = iCurvilinearLength; + _step = step; + _t = t; + _n = n; + _currentn = currentn; + _CurveLength = iCurveLength; + } + + public: + + virtual CurvePointIterator* copy() const { + return new CurvePointIterator(*this); + } + + inline Interface0DIterator castToInterface0DIterator() const{ + Interface0DIterator ret(new CurveInternal::CurvePointIterator(*this)); + return ret; + } + virtual string getExactTypeName() const { + return "CurvePointIterator"; + } + + // operators + inline CurvePointIterator& operator++() // operator corresponding to ++i + { + increment(); + return *this; + } + + inline CurvePointIterator& operator--() // operator corresponding to ++i + { + decrement(); + return *this; + } + + // comparibility + virtual bool operator==(const Interface0DIteratorNested& b) const + { + const CurvePointIterator* it_exact = dynamic_cast<const CurvePointIterator*>(&b); + if (!it_exact) + return false; + return ((__A==it_exact->__A) && (__B==it_exact->__B) && (_t == it_exact->_t)); + } + + // dereferencing + virtual CurvePoint& operator*() + { + return (_Point = CurvePoint(*__A,*__B,_t)); + } + virtual CurvePoint* operator->() { return &(operator*());} + public: + virtual bool isBegin() const + { + if((__A == _begin) && (_t < (float)M_EPSILON)) + return true; + return false; + } + virtual bool isEnd() const + { + if(__B == _end) + return true; + return false; + } + +// protected: + + virtual int increment() + { + if((_currentn == _n-1) && (_t == 1.f)) + { + // we're setting the iterator to end + ++__A; + ++__B; + ++_currentn; + _t = 0.f; + return 0; + } + + if(0 == _step) // means we iterate over initial vertices + { + Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); + _CurvilinearLength += (float)vec_tmp.norm(); + if(_currentn == _n-1) + { + _t = 1.f; + return 0; + } + ++__B; + ++__A; + ++_currentn; + return 0; + } + + // compute the new position: + Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); + float normAB = (float)vec_tmp2.norm(); + + if(normAB > M_EPSILON) + { + _CurvilinearLength += _step; + _t = _t + _step/normAB; + } + else + _t = 1.f; // AB is a null segment, we're directly at its end + //if normAB ~= 0, we don't change these values + if(_t >= 1) + { + _CurvilinearLength -= normAB*(_t-1); + if(_currentn == _n-1) + _t=1.f; + else + { + _t = 0.f; + ++_currentn; + ++__A;++__B; + } + } + return 0; + } + virtual int decrement() + { + if(_t == 0.f) //we're at the beginning of the edge + { + _t = 1.f; + --_currentn; + --__A; --__B; + if(_currentn == _n-1) + return 0; + } + + if(0 == _step) // means we iterate over initial vertices + { + Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); + _CurvilinearLength -= (float)vec_tmp.norm(); + _t = 0; + return 0; + } + + // compute the new position: + Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); + float normAB = (float)vec_tmp2.norm(); + + if(normAB >M_EPSILON) + { + _CurvilinearLength -= _step; + _t = _t - _step/normAB; + } + else + _t = -1.f; // We just need a negative value here + + // round value + if(fabs(_t) < (float)M_EPSILON) + _t = 0.0; + if(_t < 0) + { + if(_currentn == 0) + _CurvilinearLength = 0.f; + else + _CurvilinearLength += normAB*(-_t); + _t = 0.f; + } + return 0; + } + + virtual float t() const{ + return _CurvilinearLength; + } + virtual float u() const{ + return _CurvilinearLength/_CurveLength; + } + }; + + + +} // end of namespace StrokeInternal + +#endif // CURVEITERATORS_H diff --git a/source/blender/freestyle/intern/stroke/Modifiers.h b/source/blender/freestyle/intern/stroke/Modifiers.h new file mode 100755 index 00000000000..21bebebc6f8 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Modifiers.h @@ -0,0 +1,71 @@ +// +// Filename : Modifiers.h +// Author : Stephane Grabli +// Purpose : modifiers... +// Date of creation : 05/01/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef MODIFIERS_H +# define MODIFIERS_H + +# include "TimeStamp.h" + +/* ----------------------------------------- * + * * + * modifiers * + * * + * ----------------------------------------- */ +/*! Base class for modifiers. + * Modifiers are used in the + * Operators in order to "mark" + * the processed Interface1D. + */ +template<class Edge> +struct EdgeModifier : public unary_function<Edge,void> +{ + /*! Default construction */ + EdgeModifier() : unary_function<Edge,void>() {} + /*! the () operator */ + virtual void operator()(Edge& iEdge) {} +}; + +/*! Modifier that sets the time stamp + * of an Interface1D to the time stamp + * of the system. + */ +template<class Edge> +struct TimestampModifier : public EdgeModifier<Edge> +{ + /*! Default constructor */ + TimestampModifier() : EdgeModifier<Edge>() {} + /*! The () operator. */ + virtual void operator()(Edge& iEdge) + { + TimeStamp *timestamp = TimeStamp::instance(); + iEdge.setTimeStamp(timestamp->getTimeStamp()); + } +}; + +#endif // MODIFIERS_H diff --git a/source/blender/freestyle/intern/stroke/Module.h b/source/blender/freestyle/intern/stroke/Module.h new file mode 100755 index 00000000000..591bb157392 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Module.h @@ -0,0 +1,72 @@ +// +// Filename : Module.h +// Author(s) : Emmanuel Turquin +// Purpose : Set the type of the module +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef MODULE_H +# define MODULE_H + +# include "Canvas.h" +# include "StyleModule.h" + +class Module +{ +public: + + static void setAlwaysRefresh(bool b = true) { + getCurrentStyleModule()->setAlwaysRefresh(b); + } + + static void setCausal(bool b = true) { + getCurrentStyleModule()->setCausal(b); + } + + static void setDrawable(bool b = true) { + getCurrentStyleModule()->setDrawable(b); + } + + static bool getAlwaysRefresh() { + return getCurrentStyleModule()->getAlwaysRefresh(); + } + + static bool getCausal() { + return getCurrentStyleModule()->getCausal(); + } + + static bool getDrawable() { + return getCurrentStyleModule()->getDrawable(); + } + +private: + + static StyleModule* getCurrentStyleModule() { + Canvas* canvas = Canvas::getInstance(); + return canvas->getCurrentStyleModule(); + } +}; + +#endif // MODULE_H diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp new file mode 100755 index 00000000000..950c9570f0e --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Operators.cpp @@ -0,0 +1,1024 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <algorithm> +#include <stdexcept> +#include "Operators.h" +#include "Canvas.h" +#include "Stroke.h" + +LIB_STROKE_EXPORT Operators::I1DContainer Operators::_current_view_edges_set; +LIB_STROKE_EXPORT Operators::I1DContainer Operators::_current_chains_set; +LIB_STROKE_EXPORT Operators::I1DContainer* Operators::_current_set = NULL; +LIB_STROKE_EXPORT Operators::StrokesContainer Operators::_current_strokes_set; + +int Operators::select(UnaryPredicate1D& pred) { + if (!_current_set) + return 0; + if(_current_set->empty()) + return 0; + I1DContainer new_set; + I1DContainer rejected; + Functions1D::ChainingTimeStampF1D cts; + Functions1D::TimeStampF1D ts; + I1DContainer::iterator it = _current_set->begin(); + I1DContainer::iterator itbegin = it; + while (it != _current_set->end()) { + Interface1D * i1d = *it; + cts(*i1d); // mark everyone's chaining time stamp anyway + if(pred(*i1d) < 0){ + new_set.clear(); + rejected.clear(); + return -1; + } + if(pred.result){ + new_set.push_back(i1d); + ts(*i1d); + }else{ + rejected.push_back(i1d); + } + ++it; + } + if((*itbegin)->getExactTypeName() != "ViewEdge"){ + for (it = rejected.begin(); + it != rejected.end(); + ++it) + delete *it; + } + rejected.clear(); + _current_set->clear(); + *_current_set = new_set; + return 0; +} + + +int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, + UnaryPredicate1D& pred, + UnaryFunction1D_void& modifier) { + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + ViewEdge* edge; + //soc unused - Chain* new_chain; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) { + if (pred(**it_edge) < 0) + return -1; + if (pred.result) + continue; + + edge = dynamic_cast<ViewEdge*>(*it_edge); + it.setBegin(edge); + it.setCurrentEdge(edge); + + Chain* new_chain = new Chain(id);++id; + for (;;) { + new_chain->push_viewedge_back(*it, it.getOrientation()); + if (modifier(**it) < 0) { + delete new_chain; + return -1; + } + ++it; + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + return -1; + } + if (pred.result) + break; + } + + _current_chains_set.push_back(new_chain); + } + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; +} + + +int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, + UnaryPredicate1D& pred) { + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp()+1); + + ViewEdge* edge; + //soc Chain* new_chain; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) { + if (pred(**it_edge) < 0) + return -1; + if (pred.result) + continue; + if (pred_ts(**it_edge) < 0) + return -1; + if (pred_ts.result) + continue; + + edge = dynamic_cast<ViewEdge*>(*it_edge); + it.setBegin(edge); + it.setCurrentEdge(edge); + + Chain* new_chain = new Chain(id);++id; + for (;;) { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + ++it; + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + return -1; + } + if (pred.result) + break; + if (pred_ts(**it) < 0) { + delete new_chain; + return -1; + } + if (pred_ts.result) + break; + } + + _current_chains_set.push_back(new_chain); + } + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; +} + + +//void Operators::bidirectionalChain(ViewEdgeIterator& it, +// UnaryPredicate1D& pred, +// UnaryFunction1D_void& modifier) { +// if (_current_view_edges_set.empty()) +// return; +// +// unsigned id = 0; +// ViewEdge* edge; +// Chain* new_chain; +// +// for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); +// it_edge != _current_view_edges_set.end(); +// ++it_edge) { +// if (pred(**it_edge)) +// continue; +// +// edge = dynamic_cast<ViewEdge*>(*it_edge); +// it.setBegin(edge); +// it.setCurrentEdge(edge); +// +// Chain* new_chain = new Chain(id);++id; +// //ViewEdgeIterator it_back(it);--it_back; // FIXME +// do { +// new_chain->push_viewedge_back(*it, it.getOrientation()); +// modifier(**it); +// ++it; +// } while (!it.isEnd() && !pred(**it)); +// it.setBegin(edge); +// it.setCurrentEdge(edge); +// --it; +// while (!it.isEnd() && !pred(**it)) { +// new_chain->push_viewedge_front(*it, it.getOrientation()); +// modifier(**it); +// --it; +// } +// +// _current_chains_set.push_back(new_chain); +// } +// +// if (!_current_chains_set.empty()) +// _current_set = &_current_chains_set; +//} +// +//void Operators::bidirectionalChain(ViewEdgeIterator& it, +// UnaryPredicate1D& pred) { +// if (_current_view_edges_set.empty()) +// return; +// +// unsigned id = 0; +// Functions1D::IncrementChainingTimeStampF1D ts; +// Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp()+1); +// +// ViewEdge* edge; +// Chain* new_chain; +// +// for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); +// it_edge != _current_view_edges_set.end(); +// ++it_edge) { +// if (pred(**it_edge) || pred_ts(**it_edge)) +// continue; +// +// edge = dynamic_cast<ViewEdge*>(*it_edge); +// it.setBegin(edge); +// it.setCurrentEdge(edge); + // + // Chain* new_chain = new Chain(id);++id; + // //ViewEdgeIterator it_back(it);--it_back;//FIXME + // do { + // new_chain->push_viewedge_back(*it, it.getOrientation()); + // ts(**it); + // ++it; + // } while (!it.isEnd() && !pred(**it) && !pred_ts(**it)); + // it.setBegin(edge); + // it.setCurrentEdge(edge); + // --it; + // while (!it.isEnd() && !pred(**it) && !pred_ts(**it)) { + // new_chain->push_viewedge_front(*it, it.getOrientation()); + // ts(**it); + // --it; + // } + // + // _current_chains_set.push_back(new_chain); + // } + // + // if (!_current_chains_set.empty()) + // _current_set = &_current_chains_set; + //} + +int Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred) { + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp()+1); + + ViewEdge* edge; + //soc unused - Chain* new_chain; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) { + if (pred(**it_edge) < 0) + return -1; + if (pred.result) + continue; + if (pred_ts(**it_edge) < 0) + return -1; + if (pred_ts.result) + continue; + + edge = dynamic_cast<ViewEdge*>(*it_edge); + // re-init iterator + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.init() < 0) + return -1; + + Chain* new_chain = new Chain(id);++id; + //ViewEdgeIterator it_back(it);--it_back;//FIXME + for (;;) { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + if (it.increment() < 0) { // FIXME + delete new_chain; + return -1; + } + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + return -1; + } + if (pred.result) + break; + } + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.decrement() < 0) { // FIXME + delete new_chain; + return -1; + } + while (!it.isEnd()) { + if (pred(**it) < 0) { + delete new_chain; + return -1; + } + if (pred.result) + break; + new_chain->push_viewedge_front(*it, it.getOrientation()); + ts(**it); + if (it.decrement() < 0) { // FIXME + delete new_chain; + return -1; + } + } + _current_chains_set.push_back(new_chain); + } + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; +} + +int Operators::bidirectionalChain(ChainingIterator& it) { + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp()+1); + + ViewEdge* edge; + //soc unused - Chain* new_chain; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) { + if (pred_ts(**it_edge) < 0) + return -1; + if (pred_ts.result) + continue; + + edge = dynamic_cast<ViewEdge*>(*it_edge); + // re-init iterator + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.init() < 0) + return -1; + + Chain* new_chain = new Chain(id);++id; + //ViewEdgeIterator it_back(it);--it_back;//FIXME + do { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + if (it.increment() < 0) { // FIXME + delete new_chain; + return -1; + } + } while (!it.isEnd()); + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.decrement() < 0) { // FIXME + delete new_chain; + return -1; + } + while (!it.isEnd()) { + new_chain->push_viewedge_front(*it, it.getOrientation()); + ts(**it); + if (it.decrement() < 0) { // FIXME + delete new_chain; + return -1; + } + } + _current_chains_set.push_back(new_chain); + } + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; +} + +int Operators::sequentialSplit(UnaryPredicate0D& pred, + float sampling) +{ + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + CurvePoint *point; + Chain * new_curve; + I1DContainer splitted_chains; + Interface0DIterator first; + Interface0DIterator end; + Interface0DIterator last; + Interface0DIterator it; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; + cit != citend; + ++cit) { + + Id currentId = (*cit)->getId(); + new_curve = new Chain(currentId); + first = (*cit)->pointsBegin(sampling); + end = (*cit)->pointsEnd(sampling); + last = end;--last; + it = first; + + point = dynamic_cast<CurvePoint*>(&(*it)); + new_curve->push_vertex_back(point);++it; + for(; it!= end; ++it) + { + point = dynamic_cast<CurvePoint*>(&(*it)); + new_curve->push_vertex_back(point); + if(pred(it) < 0) + { + delete new_curve; + goto error; + } + if(pred.result && (it!=last)) + { + splitted_chains.push_back(new_curve); + currentId.setSecond(currentId.getSecond()+1); + new_curve = new Chain(currentId); + new_curve->push_vertex_back(point); + } + } + if(new_curve->nSegments() == 0){ + delete new_curve; + return 0; + } + + splitted_chains.push_back(new_curve); + } + + // Update the current set of chains: + cit = _current_chains_set.begin(); + for(; + cit != citend; + ++cit){ + delete (*cit); + } + _current_chains_set.clear(); + _current_chains_set = splitted_chains; + splitted_chains.clear(); + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; + +error: + cit = splitted_chains.begin(); + citend = splitted_chains.end(); + for(; + cit != citend; + ++cit){ + delete (*cit); + } + splitted_chains.clear(); + return -1; +} + +int Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, + float sampling) +{ + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + CurvePoint *point; + Chain * new_curve; + I1DContainer splitted_chains; + Interface0DIterator first; + Interface0DIterator end; + Interface0DIterator last; + Interface0DIterator itStart; + Interface0DIterator itStop; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; + cit != citend; + ++cit) { + Id currentId = (*cit)->getId(); + first = (*cit)->pointsBegin(sampling); + end = (*cit)->pointsEnd(sampling); + last = end;--last; + itStart = first; + do{ + itStop = itStart;++itStop; + + new_curve = new Chain(currentId); + currentId.setSecond(currentId.getSecond()+1); + + point = dynamic_cast<CurvePoint*>(&(*itStart)); + new_curve->push_vertex_back(point); + do{ + point = dynamic_cast<CurvePoint*>(&(*itStop)); + new_curve->push_vertex_back(point); + ++itStop; + if(itStop == end) + break; + if(stoppingPred(itStop) < 0){ + delete new_curve; + goto error; + } + }while(!stoppingPred.result); + if(itStop!=end){ + point = dynamic_cast<CurvePoint*>(&(*itStop)); + new_curve->push_vertex_back(point); + } + if(new_curve->nSegments() == 0){ + delete new_curve; + }else{ + splitted_chains.push_back(new_curve); + } + // find next start + do{ + ++itStart; + if(itStart == end) + break; + if(startingPred(itStart) < 0) + goto error; + }while(!startingPred.result); + }while((itStart!=end) && (itStart!=last)); + } + + // Update the current set of chains: + cit = _current_chains_set.begin(); + for(; + cit != citend; + ++cit){ + delete (*cit); + } + _current_chains_set.clear(); + _current_chains_set = splitted_chains; + splitted_chains.clear(); + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; + +error: + cit = splitted_chains.begin(); + citend = splitted_chains.end(); + for(; + cit != citend; + ++cit){ + delete (*cit); + } + splitted_chains.clear(); + return -1; +} + +#include "CurveIterators.h" + +// Internal function +int __recursiveSplit(Chain *_curve, UnaryFunction0D<double>& func, UnaryPredicate1D& pred, float sampling, + Operators::I1DContainer& newChains, Operators::I1DContainer& splitted_chains) +{ + if(((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)){ + newChains.push_back(_curve); + return 0; + } + + CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); + CurveInternal::CurvePointIterator second = first; ++second; + CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling); + CurveInternal::CurvePointIterator it = second; + CurveInternal::CurvePointIterator split = second; + Interface0DIterator it0d = it.castToInterface0DIterator(); + real _min = FLT_MAX;++it;//func(it0d);++it; + CurveInternal::CurvePointIterator next = it;++next; + + bool bsplit = false; + for(; ((it != end) && (next != end)); ++it,++next){ + it0d = it.castToInterface0DIterator(); + if (func(it0d) < 0) + return -1; + if(func.result < _min){ + _min = func.result; + split = it; + bsplit = true; + } + } + + if(!bsplit){ // we didn't find any minimum + newChains.push_back(_curve); + return 0; + } + + // retrieves the current splitting id + Id * newId = _curve->getSplittingId(); + if(newId == 0){ + newId = new Id(_curve->getId()); + _curve->setSplittingId(newId); + } + + Chain *new_curve_a = new Chain(*newId); + newId->setSecond(newId->getSecond()+1); + new_curve_a->setSplittingId(newId); + Chain *new_curve_b = new Chain(*newId); + newId->setSecond(newId->getSecond()+1); + new_curve_b->setSplittingId(newId); + + CurveInternal::CurvePointIterator vit = _curve->curveVerticesBegin(), vitend=_curve->curveVerticesEnd(); + CurveInternal::CurvePointIterator vnext = vit; ++vnext; + + + for(; (vit!=vitend)&&(vnext!=vitend)&&(split._CurvilinearLength-vit._CurvilinearLength> 0.001); ++vit,++vnext){ + new_curve_a->push_vertex_back(&(*vit)); + } + if((vit==vitend) || (vnext == vitend)){ + cout << "The split takes place in bad location" << endl; + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + + // build the two resulting chains + if(fabs(vit._CurvilinearLength-split._CurvilinearLength) > 0.001){ + new_curve_a->push_vertex_back(&(*split)); + new_curve_b->push_vertex_back(&(*split)); + } + else{ + new_curve_a->push_vertex_back(&(*vit)); + } + + for(;vit!=vitend;++vit) + new_curve_b->push_vertex_back(&(*vit)); + + // let's check whether one or two of the two new curves + // satisfy the stopping condition or not. + // (if one of them satisfies it, we don't split) + if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) { + delete new_curve_a; + delete new_curve_b; + return -1; + } + if(pred.result){ + // we don't actually create these two chains + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + // here we know we'll split _curve: + splitted_chains.push_back(_curve); + + __recursiveSplit(new_curve_a, func, pred, sampling, newChains, splitted_chains); + __recursiveSplit(new_curve_b, func, pred, sampling, newChains, splitted_chains); + return 0; +} + +int Operators::recursiveSplit(UnaryFunction0D<double>& func, UnaryPredicate1D& pred, float sampling) +{ + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + + Chain *currentChain = 0; + I1DContainer splitted_chains; + I1DContainer newChains; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; + cit != citend; + ++cit) { + currentChain = dynamic_cast<Chain*>(*cit); + if(!currentChain) + continue; + // let's check the first one: + if (pred(*currentChain) < 0) + return -1; + if(!pred.result){ + __recursiveSplit(currentChain, func, pred, sampling, newChains, splitted_chains); + }else{ + newChains.push_back(currentChain); + } + } + // Update the current set of chains: + if(!splitted_chains.empty()){ + for(cit = splitted_chains.begin(), citend = splitted_chains.end(); + cit != citend; + ++cit){ + delete (*cit); + } + splitted_chains.clear(); + } + + _current_chains_set.clear(); + _current_chains_set = newChains; + newChains.clear(); + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; +} + + +// recursive split with pred 0D +int __recursiveSplit(Chain *_curve, UnaryFunction0D<double>& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling, + Operators::I1DContainer& newChains, Operators::I1DContainer& splitted_chains) +{ + if(((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)){ + newChains.push_back(_curve); + return 0; + } + + CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); + CurveInternal::CurvePointIterator second = first; ++second; + CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling); + CurveInternal::CurvePointIterator it = second; + CurveInternal::CurvePointIterator split = second; + Interface0DIterator it0d = it.castToInterface0DIterator(); + //real _min = func(it0d);++it; + real _min = FLT_MAX;++it; + real mean = 0.f; + //soc unused - real variance = 0.f; + unsigned count = 0; + CurveInternal::CurvePointIterator next = it;++next; + + bool bsplit = false; + for(; ((it != end) && (next != end)); ++it,++next){ + ++count; + it0d = it.castToInterface0DIterator(); + if(pred0d(it0d) < 0) + return -1; + if(!pred0d.result) + continue; + if(func(it0d) < 0) + return -1; + mean += func.result; + if(func.result < _min){ + _min = func.result; + split = it; + bsplit = true; + } + } + mean /= (float)count; + + //if((!bsplit) || (mean-_min>mean)){ // we didn't find any minimum + if(!bsplit){ // we didn't find any minimum + newChains.push_back(_curve); + return 0; + } + + // retrieves the current splitting id + Id * newId = _curve->getSplittingId(); + if(newId == 0){ + newId = new Id(_curve->getId()); + _curve->setSplittingId(newId); + } + + Chain *new_curve_a = new Chain(*newId); + newId->setSecond(newId->getSecond()+1); + new_curve_a->setSplittingId(newId); + Chain *new_curve_b = new Chain(*newId); + newId->setSecond(newId->getSecond()+1); + new_curve_b->setSplittingId(newId); + + CurveInternal::CurvePointIterator vit = _curve->curveVerticesBegin(), vitend=_curve->curveVerticesEnd(); + CurveInternal::CurvePointIterator vnext = vit; ++vnext; + + + for(; (vit!=vitend)&&(vnext!=vitend)&&(split._CurvilinearLength-vit._CurvilinearLength> 0.001); ++vit,++vnext){ + new_curve_a->push_vertex_back(&(*vit)); + } + if((vit==vitend) || (vnext == vitend)){ + cout << "The split takes place in bad location" << endl; + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + + // build the two resulting chains + if(fabs(vit._CurvilinearLength-split._CurvilinearLength) > 0.001){ + new_curve_a->push_vertex_back(&(*split)); + new_curve_b->push_vertex_back(&(*split)); + } + else{ + new_curve_a->push_vertex_back(&(*vit)); + } + + for(;vit!=vitend;++vit) + new_curve_b->push_vertex_back(&(*vit)); + + // let's check whether one or two of the two new curves + // satisfy the stopping condition or not. + // (if one of them satisfies it, we don't split) + if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) { + delete new_curve_a; + delete new_curve_b; + return -1; + } + if(pred.result){ + // we don't actually create these two chains + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + // here we know we'll split _curve: + splitted_chains.push_back(_curve); + + __recursiveSplit(new_curve_a, func, pred0d, pred, sampling, newChains, splitted_chains); + __recursiveSplit(new_curve_b, func, pred0d, pred, sampling, newChains, splitted_chains); + return 0; +} + +int Operators::recursiveSplit(UnaryFunction0D<double>& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling) +{ + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + + Chain *currentChain = 0; + I1DContainer splitted_chains; + I1DContainer newChains; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; + cit != citend; + ++cit) { + currentChain = dynamic_cast<Chain*>(*cit); + if(!currentChain) + continue; + // let's check the first one: + if(pred(*currentChain) < 0) + return -1; + if(!pred.result){ + __recursiveSplit(currentChain, func, pred0d, pred, sampling, newChains, splitted_chains); + }else{ + newChains.push_back(currentChain); + } + } + // Update the current set of chains: + if(!splitted_chains.empty()){ + for(cit = splitted_chains.begin(), citend = splitted_chains.end(); + cit != citend; + ++cit){ + delete (*cit); + } + splitted_chains.clear(); + } + + _current_chains_set.clear(); + _current_chains_set = newChains; + newChains.clear(); + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; +} +// Internal class +class PredicateWrapper +{ +public: + + inline PredicateWrapper(BinaryPredicate1D& pred) { + _pred = &pred; + } + + inline bool operator()(Interface1D* i1, Interface1D* i2) { + if ((*_pred)(*i1, *i2) < 0) + throw std::runtime_error("comparison failed"); + return _pred->result; + } + +private: + + BinaryPredicate1D* _pred; +}; + +int Operators::sort(BinaryPredicate1D& pred) { + if (!_current_set) + return 0; + PredicateWrapper wrapper(pred); + try { + std::sort(_current_set->begin(), _current_set->end(), wrapper); + } + catch (std::runtime_error &e) { + cerr << "Warning: Operator.sort(): " << e.what() << endl; + return -1; + } + return 0; +} + +Stroke* createStroke(Interface1D& inter) { + Stroke* stroke = new Stroke; + stroke->setId(inter.getId()); + + float currentCurvilignAbscissa = 0.f; + + Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); + Interface0DIterator itfirst = it; + + Vec3r current(it->getProjectedX(), it->getProjectedY(), it->getProjectedZ()); + Vec3r previous = current; + SVertex* sv; + CurvePoint* cp; + StrokeVertex* stroke_vertex = NULL; + + do { + cp = dynamic_cast<CurvePoint*>(&(*it)); + if (!cp) { + sv = dynamic_cast<SVertex*>(&(*it)); + if (!sv) { + cerr << "Warning: unexpected Vertex type" << endl; + continue; + } + stroke_vertex = new StrokeVertex(sv); + } + else + stroke_vertex = new StrokeVertex(cp); + current = stroke_vertex->point2d(); + Vec3r vec_tmp(current - previous); + currentCurvilignAbscissa += vec_tmp.norm(); + stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa); + stroke->push_back(stroke_vertex); + previous = current; + ++it; + } while((it != itend) && (it != itfirst)); + + if (it == itfirst) { + // Add last vertex: + cp = dynamic_cast<CurvePoint*>(&(*it)); + if (!cp) { + sv = dynamic_cast<SVertex*>(&(*it)); + if (!sv) + cerr << "Warning: unexpected Vertex type" << endl; + else + stroke_vertex = new StrokeVertex(sv); + } + else + stroke_vertex = new StrokeVertex(cp); + current = stroke_vertex->point2d(); + Vec3r vec_tmp(current - previous); + currentCurvilignAbscissa += vec_tmp.norm(); + stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa); + stroke->push_back(stroke_vertex); + } + stroke->setLength(currentCurvilignAbscissa); + return stroke; +} + + +inline int applyShading(Stroke& stroke, vector<StrokeShader*>& shaders) { + for (vector<StrokeShader*>::iterator it = shaders.begin(); it != shaders.end(); ++it) { + if ((*it)->shade(stroke) < 0) { + return -1; + } + } + return 0; +} + + +int Operators::create(UnaryPredicate1D& pred, vector<StrokeShader*> shaders) { + //Canvas* canvas = Canvas::getInstance(); + if (!_current_set) { + cerr << "Warning: current set empty" << endl; + return 0; + } + for (Operators::I1DContainer::iterator it = _current_set->begin(); + it != _current_set->end(); + ++it) { + if (pred(**it) < 0) + return -1; + if (!pred.result) + continue; + + Stroke* stroke = createStroke(**it); + if (stroke) { + if (applyShading(*stroke, shaders) < 0) + return -1; + //canvas->RenderStroke(stroke); + _current_strokes_set.push_back(stroke); + } + } + return 0; +} + + +void Operators::reset() { + ViewMap* vm = ViewMap::getInstance(); + if (!vm) { + cerr << "Error: no ViewMap computed yet" << endl; + return; + } + _current_view_edges_set.clear(); + for (I1DContainer::iterator it = _current_chains_set.begin(); + it != _current_chains_set.end(); + ++it) + delete *it; + _current_chains_set.clear(); + _current_view_edges_set.insert(_current_view_edges_set.begin(), + vm->ViewEdges().begin(), + vm->ViewEdges().end()); + _current_set = &_current_view_edges_set; + _current_strokes_set.clear(); +} diff --git a/source/blender/freestyle/intern/stroke/Operators.h b/source/blender/freestyle/intern/stroke/Operators.h new file mode 100755 index 00000000000..cff9e120c1a --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Operators.h @@ -0,0 +1,311 @@ +// +// Filename : Operators.h +// Author(s) : Stephane Grabli, Emmanuel Turquin +// Purpose : Class gathering stroke creation algorithms +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef OPERATORS_H +# define OPERATORS_H + +# include <vector> +# include <iostream> +# include "../view_map/Interface1D.h" +# include "Predicates1D.h" +# include "Predicates0D.h" +# include "../view_map/ViewMap.h" +# include "Chain.h" +# include "ChainingIterators.h" +# include "../system/TimeStamp.h" +# include "StrokeShader.h" + +/*! Class defining the operators used in a style module. + * There are 4 classes of operators: Selection, Chaining, + * Splitting and Creating. All these operators are user controlled + * in the scripting language through Functors, Predicates and Shaders + * that are taken as arguments. + */ +class LIB_STROKE_EXPORT Operators { + +public: + + typedef vector<Interface1D*> I1DContainer; + typedef vector<Stroke*> StrokesContainer; + + + // + // Operators + // + //////////////////////////////////////////////// + + /*! Selects the ViewEdges of the ViewMap verifying + * a specified condition. + * \param pred The predicate expressing this condition + */ + static int select(UnaryPredicate1D& pred); + + /*! Builds a set of chains from the current set of ViewEdges. + * Each ViewEdge of the current list starts a new chain. The chaining + * operator then iterates over the ViewEdges of the ViewMap using the + * user specified iterator. + * This operator only iterates using the increment operator and is + * therefore unidirectional. + * \param it + * The iterator on the ViewEdges of the ViewMap. It contains + * the chaining rule. + * \param pred + * The predicate on the ViewEdge that expresses the stopping + * condition. + * \param modifier + * A function that takes a ViewEdge as argument and that + * is used to modify the processed ViewEdge state (the timestamp + * incrementation is a typical illustration of such a modifier) + */ + static int chain(ViewEdgeInternal::ViewEdgeIterator& it, + UnaryPredicate1D& pred, + UnaryFunction1D_void& modifier); + + /*! Builds a set of chains from the current set of ViewEdges. + * Each ViewEdge of the current list starts a new chain. The chaining + * operator then iterates over the ViewEdges of the ViewMap using the + * user specified iterator. + * This operator only iterates using the increment operator and is + * therefore unidirectional. + * This chaining operator is different from the previous one because + * it doesn't take any modifier as argument. Indeed, the time stamp (insuring + * that a ViewEdge is processed one time) is automatically managed in this case. + * \param it + * The iterator on the ViewEdges of the ViewMap. It contains + * the chaining rule. + * \param pred + * The predicate on the ViewEdge that expresses the stopping + * condition. + */ + static int chain(ViewEdgeInternal::ViewEdgeIterator& it, + UnaryPredicate1D& pred); + + /*! Builds a set of chains from the current set of ViewEdges. + * Each ViewEdge of the current list potentially starts a new chain. The chaining + * operator then iterates over the ViewEdges of the ViewMap using the + * user specified iterator. + * This operator iterates both using the increment and decrement operators and is + * therefore bidirectional. + * This operator works with a ChainingIterator which contains the + * chaining rules. It is this last one which can be told + * to chain only edges that belong to the selection or not to + * process twice a ViewEdge during the chaining. + * Each time a ViewEdge is added to a chain, its chaining time stamp + * is incremented. This allows you to keep track of + * the number of chains to which a ViewEdge belongs to. + * \param it + * The ChainingIterator on the ViewEdges of the ViewMap. It contains + * the chaining rule. + * \param pred + * The predicate on the ViewEdge that expresses the stopping + * condition. + */ + static int bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred); + + /*! The only difference with the above bidirectional chaining algorithm is + * that we don't need to pass a stopping criterion. This might be desirable + * when the stopping criterion is already contained in the iterator + * definition. + * Builds a set of chains from the current set of ViewEdges. + * Each ViewEdge of the current list potentially starts a new chain. The chaining + * operator then iterates over the ViewEdges of the ViewMap using the + * user specified iterator. + * This operator iterates both using the increment and decrement operators and is + * therefore bidirectional. + * This operator works with a ChainingIterator which contains the + * chaining rules. It is this last one which can be told + * to chain only edges that belong to the selection or not to + * process twice a ViewEdge during the chaining. + * Each time a ViewEdge is added to a chain, its chaining time stamp + * is incremented. This allows you to keep track of + * the number of chains to which a ViewEdge belongs to. + * \param it + * The ChainingIterator on the ViewEdges of the ViewMap. It contains + * the chaining rule. + */ + static int bidirectionalChain(ChainingIterator& it); + + /*! Splits each chain of the current set of chains in a sequential way. + * The points of each chain are processed (with a specified sampling) sequentially. + * Each time a user specified starting condition is verified, a new chain begins and + * ends as soon as a user-defined stopping predicate is verified. + * This allows chains overlapping rather than chains partitioning. + * The first point of the initial chain is the first point of one of the + * resulting chains. + * The splitting ends when no more chain can start. + * \param startingPred + * The predicate on a point that expresses the starting + * condition + * \param stoppingPred + * The predicate on a point that expresses the stopping + * condition + * \param sampling + * The resolution used to sample the chain for the predicates + * evaluation. (The chain is not actually resampled, a virtual point + * only progresses along the curve using this resolution) + */ + static int sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, + float sampling = 0.f); + + /*! Splits each chain of the current set of chains in a sequential way. + * The points of each chain are processed (with a specified sampling) sequentially + * and each time a user specified condition is verified, the chain is split into two chains. + * The resulting set of chains is a partition of the initial chain + * \param pred + * The predicate on a point that expresses the splitting + * condition + * \param sampling + * The resolution used to sample the chain for the predicate + * evaluation. (The chain is not actually resampled, a virtual point + * only progresses along the curve using this resolution) + */ + static int sequentialSplit(UnaryPredicate0D& pred, + float sampling = 0.f); + + /*! Splits the current set of chains in a recursive way. + * We process the points of each chain (with a specified sampling) to find + * the point minimizing a specified function. The chain is split in two at this + * point and the two new chains are processed in the same way. + * The recursivity level is controlled through a predicate 1D that expresses a stopping condition + * on the chain that is about to be processed. + * \param func + * The Unary Function evaluated at each point of the chain. + * The splitting point is the point minimizing this function + * \param pred + * The Unary Predicate ex pressing the recursivity stopping condition. + * This predicate is evaluated for each curve before it actually gets + * split. If pred(chain) is true, the curve won't be split anymore. + * \param sampling + * The resolution used to sample the chain for the predicates + * evaluation. (The chain is not actually resampled, a virtual point + * only progresses along the curve using this resolution) + */ + static int recursiveSplit(UnaryFunction0D<double>& func, UnaryPredicate1D& pred, float sampling = 0); + + /*! Splits the current set of chains in a recursive way. + * We process the points of each chain (with a specified sampling) to find + * the point minimizing a specified function. The chain is split in two at this + * point and the two new chains are processed in the same way. + * The user can specify a 0D predicate to make a first selection + * on the points that can potentially be split. + * A point that doesn't verify the 0D predicate won't be candidate + * in realizing the min. + * The recursivity level is controlled through a predicate 1D that expresses a stopping condition + * on the chain that is about to be processed. + * \param func + * The Unary Function evaluated at each point of the chain. + * The splitting point is the point minimizing this function + * \param pred0d + * The Unary Predicate 0D used to select the candidate points + * where the split can occur. + * For example, it is very likely that would rather have + * your chain splitting around its middle point than around + * one of its extremities. A 0D predicate working on + * the curvilinear abscissa allows to add this kind of constraints. + * \param pred + * The Unary Predicate ex pressing the recursivity stopping condition. + * This predicate is evaluated for each curve before it actually gets + * split. If pred(chain) is true, the curve won't be split anymore. + * \param sampling + * The resolution used to sample the chain for the predicates + * evaluation. (The chain is not actually resampled, a virtual point + * only progresses along the curve using this resolution) + * + */ + static int recursiveSplit(UnaryFunction0D<double>& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling = 0); + + /*! Sorts the current set of chains (or viewedges) according to the + * comparison predicate given as argument. + * \param pred + * The binary predicate used for the comparison + */ + static int sort(BinaryPredicate1D& pred); + + /*! Creates and shades the strokes from the current set of chains. + * A predicate can be specified to make a selection pass on the + * chains. + * \param pred + * The predicate that a chain must verify in order to + * be transform as a stroke + * \param shaders + * The list of shaders used to shade the strokes + */ + static int create(UnaryPredicate1D& pred, vector<StrokeShader*> shaders); + + // + // Data access + // + //////////////////////////////////////////////// + + static ViewEdge* getViewEdgeFromIndex(unsigned i) { + return dynamic_cast<ViewEdge*>(_current_view_edges_set[i]); + } + + static Chain* getChainFromIndex(unsigned i) { + return dynamic_cast<Chain*>(_current_chains_set[i]); + } + + static Stroke* getStrokeFromIndex(unsigned i) { + return _current_strokes_set[i]; + } + + static unsigned getViewEdgesSize() { + return _current_view_edges_set.size(); + } + + static unsigned getChainsSize() { + return _current_chains_set.size(); + } + + static unsigned getStrokesSize() { + return _current_strokes_set.size(); + } + + // + // Not exported in Python + // + ////////////////////////////////////////////////// + + static StrokesContainer* getStrokesSet() { + return &_current_strokes_set; + } + + static void reset(); + +private: + + Operators() {} + + static I1DContainer _current_view_edges_set; + static I1DContainer _current_chains_set; + static I1DContainer* _current_set; + static StrokesContainer _current_strokes_set; +}; + +#endif // OPERATORS_H diff --git a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp new file mode 100755 index 00000000000..dc9c94e0e11 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp @@ -0,0 +1,89 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +# include "PSStrokeRenderer.h" +# include "Canvas.h" + +PSStrokeRenderer::PSStrokeRenderer(const char* iFileName) +:StrokeRenderer(){ + if(!iFileName) + iFileName = "freestyle.ps"; + // open the stream: + _ofstream.open(iFileName, ios::out); + if(!_ofstream.is_open()){ + cerr << "couldn't open the output file " << iFileName << endl; + } + _ofstream << "%!PS-Adobe-2.0 EPSF-2.0" << endl; + _ofstream << "%%Creator: Freestyle (http://artis.imag.fr/Software/Freestyle)" << endl; + _ofstream << "%%BoundingBox: " << 0 << " "<< 0 << " " << Canvas::getInstance()->width() << " " << Canvas::getInstance()->height() << endl; + _ofstream << "%%EndComments" << endl; +} + +PSStrokeRenderer::~PSStrokeRenderer(){ + Close(); +} + +void PSStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const{ + RenderStrokeRepBasic(iStrokeRep); +} + +void PSStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const{ + vector<Strip*>& strips = iStrokeRep->getStrips(); + Strip::vertex_container::iterator v[3]; + StrokeVertexRep *svRep[3]; + Vec3r color[3]; + for(vector<Strip*>::iterator s=strips.begin(), send=strips.end(); + s!=send; + ++s){ + Strip::vertex_container& vertices = (*s)->vertices(); + v[0] = vertices.begin(); + v[1] = v[0];++(v[1]); + v[2] = v[1]; ++(v[2]); + + while(v[2]!=vertices.end()){ + svRep[0] = *(v[0]); + svRep[1] = *(v[1]); + svRep[2] = *(v[2]); + + color[0] = svRep[0]->color(); + //color[1] = svRep[1]->color(); + //color[2] = svRep[2]->color(); + + _ofstream << "newpath" << endl; + _ofstream << (color[0])[0] << " " << (color[0])[1] << " " << (color[0])[2] << " setrgbcolor" <<endl; + _ofstream << svRep[0]->point2d()[0] << " " <<svRep[0]->point2d()[1] << " moveto" << endl; + _ofstream << svRep[1]->point2d()[0] << " " <<svRep[1]->point2d()[1] << " lineto" << endl; + _ofstream << svRep[2]->point2d()[0] << " " <<svRep[2]->point2d()[1] << " lineto" << endl; + _ofstream << "closepath" << endl; + _ofstream << "fill" << endl; + + ++v[0]; + ++v[1]; + ++v[2]; + } + } +} + +void PSStrokeRenderer::Close(){ + if(_ofstream.is_open()) + _ofstream.close(); +} + diff --git a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h new file mode 100755 index 00000000000..821c016ab91 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h @@ -0,0 +1,63 @@ +// +// Filename : PSStrokeRenderer.h +// Author(s) : Stephane Grabli +// Purpose : Class to define the Postscript rendering of a stroke +// Date of creation : 10/26/2004 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef PSSTROKERENDERER_H +# define PSSTROKERENDERER_H + +# include "../system/FreestyleConfig.h" +# include "StrokeRenderer.h" +# include <fstream> + +/**********************************/ +/* */ +/* */ +/* PSStrokeRenderer */ +/* */ +/* */ +/**********************************/ + +class LIB_STROKE_EXPORT PSStrokeRenderer : public StrokeRenderer +{ +public: + PSStrokeRenderer(const char * iFileName = 0); + virtual ~PSStrokeRenderer(); + + /*! Renders a stroke rep */ + virtual void RenderStrokeRep(StrokeRep *iStrokeRep) const; + virtual void RenderStrokeRepBasic(StrokeRep *iStrokeRep) const; + + /*! Closes the output PS file */ + void Close(); + +protected: + mutable ofstream _ofstream; +}; + +#endif // PSSTROKERENDERER_H + diff --git a/source/blender/freestyle/intern/stroke/Predicates0D.h b/source/blender/freestyle/intern/stroke/Predicates0D.h new file mode 100755 index 00000000000..2f5d9551b3a --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Predicates0D.h @@ -0,0 +1,172 @@ +// +// Filename : Predicates0D.h +// Author(s) : Stephane Grabli, Emmanuel Turquin +// Purpose : Class gathering stroke creation algorithms +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef PREDICATES0D_H +# define PREDICATES0D_H + +# include "../view_map/Functions0D.h" + +# include "../python/Director.h" + +// +// UnaryPredicate0D (base class for predicates in 0D) +// +/////////////////////////////////////////////////////////// +/*! Base class for Unary Predicates that work + * on Interface0DIterator. + * A UnaryPredicate0D is a functor that evaluates + * a condition on a Interface0DIterator and returns + * true or false depending on whether this condition is + * satisfied or not. + * The UnaryPredicate0D is used by calling its () operator. + * Any inherited class must overload the () operator. + */ +class UnaryPredicate0D +{ +public: + + bool result; + PyObject *py_up0D; + + /*! Default constructor. */ + UnaryPredicate0D() { py_up0D = 0; } + /*! Destructor. */ + virtual ~UnaryPredicate0D() {} + /*! Returns the string of the name + * of the UnaryPredicate0D. + */ + virtual string getName() const { + return "UnaryPredicate0D"; + } + /*! The () operator. Must be overload + * by inherited classes. + * \param it + * The Interface0DIterator pointing onto the + * Interface0D at which we wish to evaluate + * the predicate. + * \return true if the condition is satisfied, + * false otherwise. + */ + virtual int operator()(Interface0DIterator& it) { + return Director_BPy_UnaryPredicate0D___call__(this, it); + } + +}; + + +// +// BinaryPredicate0D (base class for predicates in 0D) +// +/////////////////////////////////////////////////////////// +/*! Base class for Binary Predicates working on Interface0D. + * A BinaryPredicate0D is typically an ordering relation + * between two Interface0D. + * It evaluates a relation between 2 Interface0D and + * returns true or false. + * It is used by calling the () operator. + */ +class BinaryPredicate0D +{ +public: + + bool result; + PyObject *py_bp0D; + + /*! Default constructor. */ + BinaryPredicate0D() { py_bp0D = 0; } + /*! Destructor. */ + virtual ~BinaryPredicate0D() {} + /*! Returns the string of the name of the + * binary predicate. + */ + virtual string getName() const { + return "BinaryPredicate0D"; + } + + /*! The () operator. Must be overload by inherited classes. + * It evaluates a relation between 2 Interface0D. + * \param inter1 + * The first Interface0D. + * \param inter2 + * The second Interface0D. + * \return true or false. + */ + virtual int operator()(Interface0D& inter1, Interface0D& inter2) { + return Director_BPy_BinaryPredicate0D___call__(this, inter1, inter2); + } + +}; + + +// +// Predicates definitions +// +/////////////////////////////////////////////////////////// + +namespace Predicates0D { + + // TrueUP0D + /*! Returns true any time */ + class TrueUP0D : public UnaryPredicate0D + { + public: + /*! Default constructor. */ + TrueUP0D() {} + /*! Returns the string "TrueUP0D"*/ + string getName() const { + return "TrueUP0D"; + } + /*! The () operator. */ + int operator()(Interface0DIterator&) { + result = true; + return 0; + } + }; + + // FalseUP0D + /*! Returns false any time */ + class FalseUP0D : public UnaryPredicate0D + { + public: + /*! Default constructor. */ + FalseUP0D() {} + /*! Returns the string "FalseUP0D"*/ + string getName() const { + return "FalseUP0D"; + } + /*! The () operator. */ + int operator()(Interface0DIterator&) { + result = false; + return 0; + } + }; + +} // end of namespace Predicates0D + +#endif // PREDICATES0D_H diff --git a/source/blender/freestyle/intern/stroke/Predicates1D.h b/source/blender/freestyle/intern/stroke/Predicates1D.h new file mode 100755 index 00000000000..6461f6428ab --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Predicates1D.h @@ -0,0 +1,483 @@ +// +// Filename : Predicates1D.h +// Author(s) : Stephane Grabli, Emmanuel Turquin +// Purpose : Class gathering stroke creation algorithms +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef PREDICATES1D_H +# define PREDICATES1D_H + +# include <string> +# include "../system/TimeStamp.h" +# include "../view_map/Interface1D.h" +# include "../view_map/Functions1D.h" +# include "AdvancedFunctions1D.h" + +# include "../python/Director.h" + +// +// UnaryPredicate1D (base class for predicates in 1D) +// +/////////////////////////////////////////////////////////// +/*! Base class for Unary Predicates that work + * on Interface1D. + * A UnaryPredicate1D is a functor that evaluates + * a condition on a Interface1D and returns + * true or false depending on whether this condition is + * satisfied or not. + * The UnaryPredicate1D is used by calling its () operator. + * Any inherited class must overload the () operator. + */ +class UnaryPredicate1D +{ +public: + + bool result; + PyObject *py_up1D; + + /*! Default constructor. */ + UnaryPredicate1D() { py_up1D = 0; } + /*! Destructor. */ + virtual ~UnaryPredicate1D() {} + /*! Returns the string of the name + * of the UnaryPredicate1D. + */ + virtual string getName() const { + return "UnaryPredicate1D"; + } + /*! The () operator. Must be overload + * by inherited classes. + * \param inter + * The Interface1D on which we wish to evaluate + * the predicate. + * \return true if the condition is satisfied, + * false otherwise. + */ + virtual int operator()(Interface1D& inter) { + return Director_BPy_UnaryPredicate1D___call__(this, inter); + } + +}; + + +// +// BinaryPredicate1D (base class for predicates in 1D) +// +/////////////////////////////////////////////////////////// +/*! Base class for Binary Predicates working on Interface1D. + * A BinaryPredicate1D is typically an ordering relation + * between two Interface1D. + * It evaluates a relation between 2 Interface1D and + * returns true or false. + * It is used by calling the () operator. + */ +class BinaryPredicate1D +{ +public: + + bool result; + PyObject *py_bp1D; + + /*! Default constructor. */ + BinaryPredicate1D() { py_bp1D = 0; } + /*! Destructor. */ + virtual ~BinaryPredicate1D() {} + /*! Returns the string of the name of the + * binary predicate. + */ + virtual string getName() const { + return "BinaryPredicate1D"; + } + /*! The () operator. Must be overload by inherited classes. + * It evaluates a relation between 2 Interface1D. + * \param inter1 + * The first Interface1D. + * \param inter2 + * The second Interface1D. + * \return true or false. + */ + virtual int operator()(Interface1D& inter1, Interface1D& inter2) { + return Director_BPy_BinaryPredicate1D___call__(this, inter1, inter2); + } + +}; + + +// +// Predicates definitions +// +/////////////////////////////////////////////////////////// + +namespace Predicates1D { + + // TrueUP1D + /*! Returns true */ + class TrueUP1D : public UnaryPredicate1D + { + public: + /*! Constructor */ + TrueUP1D() {} + /*! Returns the string "TrueUP1D"*/ + string getName() const { + return "TrueUP1D"; + } + /*! the () operator */ + int operator()(Interface1D&) { + result = true; + return 0; + } + }; + + // FalseUP1D + /*! Returns false */ + class FalseUP1D : public UnaryPredicate1D + { + public: + /*! Constructor */ + FalseUP1D() {} + /*! Returns the string "FalseUP1D"*/ + string getName() const { + return "FalseUP1D"; + } + /*! the () operator */ + int operator()(Interface1D&) { + result = false; + return 0; + } + }; + + // QuantitativeInvisibilityUP1D + /*! Returns true if the Quantitative Invisibility evaluated + * at an Interface1D, using the QuantitativeInvisibilityF1D + * functor, equals a certain user-defined value. + */ + class QuantitativeInvisibilityUP1D : public UnaryPredicate1D + { + public: + /*! Builds the Predicate. + * \param qi + * The Quantitative Invisibility you want + * the Interface1D to have + */ + QuantitativeInvisibilityUP1D(unsigned qi = 0) : _qi(qi) {} + /*! Returns the string "QuantitativeInvisibilityUP1D"*/ + string getName() const { + return "QuantitativeInvisibilityUP1D"; + } + /*! the () operator */ + int operator()(Interface1D& inter) { + Functions1D::QuantitativeInvisibilityF1D func; + if (func(inter) < 0) + return -1; + result = (func.result == _qi); + return 0; + } + private: + unsigned _qi; + }; + + // ContourUP1D + /*! Returns true if the Interface1D is a contour. + * An Interface1D is a contour if it is borded + * by a different shape on each of its sides. + */ + class ContourUP1D : public UnaryPredicate1D + { + private: + Functions1D::CurveNatureF1D _getNature; + public: + /*! Returns the string "ContourUP1D"*/ + string getName() const { + return "ContourUP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& inter) { + if (_getNature(inter) < 0) + return -1; + if((_getNature.result & Nature::SILHOUETTE) || (_getNature.result & Nature::BORDER)){ + Interface0DIterator it=inter.verticesBegin(); + for(; !it.isEnd(); ++it){ + if(Functions0D::getOccludeeF0D(it) != Functions0D::getShapeF0D(it)) { + result = true; + return 0; + } + } + } + result = false; + return 0; + } + }; + + // ExternalContourUP1D + /*! Returns true if the Interface1D is an external contour. + * An Interface1D is an external contour if it is borded + * by no shape on one of its sides. + */ + class ExternalContourUP1D : public UnaryPredicate1D + { + private: + Functions1D::CurveNatureF1D _getNature; + public: + /*! Returns the string "ExternalContourUP1D"*/ + string getName() const { + return "ExternalContourUP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& inter) { + if (_getNature(inter) < 0) + return -1; + if((_getNature.result & Nature::SILHOUETTE) || (_getNature.result & Nature::BORDER)){ + set<ViewShape*> occluded; + Functions1D::getOccludeeF1D(inter, occluded); + for(set<ViewShape*>::iterator os=occluded.begin(), osend=occluded.end(); + os!=osend; + ++os){ + if((*os) == 0) { + result = true; + return 0; + } + } + } + result = false; + return 0; + } + }; + + // EqualToTimeStampUP1D + /*! Returns true if the Interface1D's time stamp + * is equal to a certain user-defined value. + */ + class EqualToTimeStampUP1D : public UnaryPredicate1D + { + protected: + unsigned _timeStamp; + public: + EqualToTimeStampUP1D(unsigned ts) : UnaryPredicate1D(){ + _timeStamp = ts; + } + /*! Returns the string "EqualToTimeStampUP1D"*/ + string getName() const { + return "EqualToTimeStampUP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& inter) { + result = (inter.getTimeStamp() == _timeStamp); + return 0; + } + }; + + // EqualToChainingTimeStampUP1D + /*! Returns true if the Interface1D's time stamp + * is equal to a certain user-defined value. + */ + class EqualToChainingTimeStampUP1D : public UnaryPredicate1D + { + protected: + unsigned _timeStamp; + public: + EqualToChainingTimeStampUP1D(unsigned ts) : UnaryPredicate1D(){ + _timeStamp = ts; + } + /*! Returns the string "EqualToChainingTimeStampUP1D"*/ + string getName() const { + return "EqualToChainingTimeStampUP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& inter) { + ViewEdge* edge = dynamic_cast<ViewEdge*>(&inter); + if (!edge) { + result = false; + return 0; + } + result = (edge->getChainingTimeStamp() >= _timeStamp); + return 0; + } + }; + + // ShapeUP1D + /*! Returns true if the shape to which the Interface1D + * belongs to has the same Id as the one specified by the + * user. + */ + class ShapeUP1D: public UnaryPredicate1D + { + private: + Id _id; + public: + /*! Builds the Predicate. + * \param idFirst + * The first Id component. + * \param idSecond + * The second Id component. + */ + ShapeUP1D(unsigned idFirst, unsigned idSecond=0) + : UnaryPredicate1D(){ + _id = Id(idFirst, idSecond); + } + /*! Returns the string "ShapeUP1D"*/ + string getName() const { + return "ShapeUP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& inter) { + set<ViewShape*> shapes; + Functions1D::getShapeF1D(inter, shapes); + for(set<ViewShape*>::iterator s=shapes.begin(), send=shapes.end(); + s!=send; + ++s){ + if((*s)->getId() == _id) { + result = true; + return 0; + } + } + result = false; + return 0; + } + }; + + // + // Binary Predicates definitions + // + /////////////////////////////////////////////////////////// + + // TrueBP1D + /*! Returns true. */ + class TrueBP1D : public BinaryPredicate1D + { + public: + /*! Returns the string "TrueBP1D"*/ + string getName() const { + return "TrueBP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& i1, Interface1D& i2) { + result = true; + return 0; + } + }; + + // FalseBP1D + /*! Returns false. */ + class FalseBP1D : public BinaryPredicate1D + { + public: + /*! Returns the string "FalseBP1D"*/ + string getName() const { + return "FalseBP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& i1, Interface1D& i2) { + result = false; + return 0; + } + }; + + // Length2DBP1D + /*! Returns true if the 2D length of the Interface1D i1 + * is less than the 2D length of the Interface1D i2. + */ + class Length2DBP1D : public BinaryPredicate1D + { + public: + /*! Returns the string "Length2DBP1D"*/ + string getName() const { + return "Length2DBP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& i1, Interface1D& i2) { + result = (i1.getLength2D() > i2.getLength2D()); + return 0; + } + }; + + // SameShapeIdBP1D + /*! Returns true if the Interface1D i1 and i2 belong + * to the same shape. + */ + class SameShapeIdBP1D : public BinaryPredicate1D + { + public: + /*! Returns the string "SameShapeIdBP1D"*/ + string getName() const { + return "SameShapeIdBP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& i1, Interface1D& i2) { + set<ViewShape*> shapes1; + Functions1D::getShapeF1D(i1, shapes1); + set<ViewShape*> shapes2; + Functions1D::getShapeF1D(i2, shapes2); + // FIXME:// n2 algo, can do better... + for(set<ViewShape*>::iterator s=shapes1.begin(), send=shapes1.end(); + s!=send; + ++s){ + Id current = (*s)->getId(); + for(set<ViewShape*>::iterator s2=shapes2.begin(), s2end=shapes2.end(); + s2!=s2end; + ++s2){ + if((*s2)->getId() == current) { + result = true; + return 0; + } + } + } + result = false; + return 0; + } + }; + + // ViewMapGradientNormBP1D + /*! Returns true if the evaluation of the + * Gradient norm Function is higher for Interface1D i1 + * than for i2. + */ + class ViewMapGradientNormBP1D : public BinaryPredicate1D + { + private: + Functions1D::GetViewMapGradientNormF1D _func; + public: + ViewMapGradientNormBP1D(int level, IntegrationType iType=MEAN, float sampling=2.0) + : BinaryPredicate1D(), _func(level, iType, sampling) { + } + /*! Returns the string "ViewMapGradientNormBP1D"*/ + string getName() const { + return "ViewMapGradientNormBP1D"; + } + /*! The () operator. */ + int operator()(Interface1D& i1, Interface1D& i2) { + if (_func(i1) < 0) + return -1; + real n1 = _func.result; + if (_func(i2) < 0) + return -1; + real n2 = _func.result; + result = (n1 > n2); + return 0; + } + }; +} // end of namespace Predicates1D + +#endif // PREDICATES1D_H diff --git a/source/blender/freestyle/intern/stroke/QInformationMap.h b/source/blender/freestyle/intern/stroke/QInformationMap.h new file mode 100755 index 00000000000..ef068f15061 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/QInformationMap.h @@ -0,0 +1,58 @@ +// +// Filename : QInformationMap.h +// Author : Stephane Grabli +// Purpose : Class defining an information map using a QImage +// Date of creation : 04/01/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef QINFORMATIONMAP_H +# define QINFORMATIONMAP_H + +# include <qimage.h> +# include "InformationMap.h" + +class QInformationMap : public InformationMap +{ +private: + QImage _map; // the image or a piece of image + +public: + QInformationMap(); + QInformationMap(const QImage&); + QInformationMap(const QInformationMap&); + QInformationMap& operator=(const QInformationMap&); + + //float getSmoothedPixel(int x, int y, float sigma = 0.2f) + virtual float getMean(int x, int y) ; + virtual void retrieveMeanAndVariance(int x, int y, float &oMean, float &oVariance) ; + + inline const QImage& map() const {return _map;} + inline void setMap(const QImage& iMap, float iw, float ih) {_map = iMap.copy();_w=iw;_h=ih;} + +protected: + virtual float computeGaussian(int x, int y); +}; + +#endif // QINFORMATIONMAP_H diff --git a/source/blender/freestyle/intern/stroke/Stroke.cpp b/source/blender/freestyle/intern/stroke/Stroke.cpp new file mode 100755 index 00000000000..f6cefdfee34 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Stroke.cpp @@ -0,0 +1,953 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "Stroke.h" +#include "StrokeRenderer.h" +#include "StrokeIterators.h" +#include "StrokeAdvancedIterators.h" + + /**********************************/ + /* */ + /* */ + /* StrokeAttribute */ + /* */ + /* */ + /**********************************/ + +StrokeAttribute::StrokeAttribute() +{ + int i; + _alpha = 1.f; + _thickness[0] = 1.f; + _thickness[1] = 1.f; + for(i=0; i<3; ++i) + _color[i] = 0.2f; + _color[0]=0.8; + _userAttributesReal = 0; + _userAttributesVec2f = 0; + _userAttributesVec3f = 0; + _visible = true; +} +StrokeAttribute::StrokeAttribute(const StrokeAttribute& iBrother) +{ + _alpha = iBrother._alpha; + _thickness[0] = iBrother._thickness[0]; + _thickness[1] = iBrother._thickness[1]; + for(int i=0; i<3; ++i) + _color[i] = iBrother._color[i]; + _visible = iBrother._visible; + if(iBrother._userAttributesReal) + _userAttributesReal = new realMap(*iBrother._userAttributesReal); + else + _userAttributesReal = 0; + if(iBrother._userAttributesVec2f) + _userAttributesVec2f = new Vec2fMap(*iBrother._userAttributesVec2f); + else + _userAttributesVec2f = 0; + if(iBrother._userAttributesVec3f) + _userAttributesVec3f = new Vec3fMap(*iBrother._userAttributesVec3f); + else + _userAttributesVec3f = 0; +} +StrokeAttribute::StrokeAttribute( float iRColor, float iGColor, float iBColor, + float iAlpha, + float iRThickness, float iLThickness) +{ + _color[0] = iRColor; + _color[1] = iGColor; + _color[2] = iBColor; + + _alpha = iAlpha; + + _thickness[0] = iRThickness; + _thickness[1] = iLThickness; + + _visible = true; + + _userAttributesReal = 0; + _userAttributesVec2f = 0; + _userAttributesVec3f = 0; +} +StrokeAttribute::StrokeAttribute(const StrokeAttribute& a1, const StrokeAttribute& a2, float t) + +{ + + _alpha = (1-t)*a1._alpha + t*a2._alpha; + _thickness[0] = (1-t)*a1._thickness[0] + t*a2._thickness[0]; + _thickness[1] = (1-t)*a1._thickness[1] + t*a2._thickness[1]; + for(int i=0; i<3; ++i) + _color[i] = (1-t)*a1._color[i] + t*a2._color[i]; + + _visible = true; + + // FIXME: a verifier (et a ameliorer) + if((a1._userAttributesReal) && (a2._userAttributesReal)){ + if(a1._userAttributesReal->size() == a2._userAttributesReal->size()){ + _userAttributesReal = new realMap; + realMap::iterator it1=a1._userAttributesReal->begin(), it1end=a1._userAttributesReal->end(); + realMap::iterator it2=a2._userAttributesReal->begin(), it2end=a2._userAttributesReal->end(); + for(; (it1!=it1end); ++it1){ + (*_userAttributesReal)[(*it1).first] = ((1-t)*(*it1).second+t*(*it2).second); + } + } + }else{ + _userAttributesReal = 0; + } + if((a1._userAttributesVec2f) && (a2._userAttributesVec2f)){ + if(a1._userAttributesVec2f->size() == a2._userAttributesVec2f->size()){ + _userAttributesVec2f = new Vec2fMap; + Vec2fMap::iterator it1=a1._userAttributesVec2f->begin(), it1end=a1._userAttributesVec2f->end(); + Vec2fMap::iterator it2=a2._userAttributesVec2f->begin(), it2end=a2._userAttributesVec2f->end(); + for(; (it1!=it1end); ++it1){ + (*_userAttributesVec2f)[(*it1).first] = ((1-t)*(*it1).second+t*(*it2).second); + } + } + }else{ + _userAttributesVec2f = 0; + } + if((a1._userAttributesVec3f) && (a2._userAttributesVec3f)){ + if(a1._userAttributesVec3f->size() == a2._userAttributesVec3f->size()){ + _userAttributesVec3f = new Vec3fMap; + Vec3fMap::iterator it1=a1._userAttributesVec3f->begin(), it1end=a1._userAttributesVec3f->end(); + Vec3fMap::iterator it2=a2._userAttributesVec3f->begin(), it2end=a2._userAttributesVec3f->end(); + for(; (it1!=it1end); ++it1){ + (*_userAttributesVec3f)[(*it1).first] = ((1-t)*(*it1).second+t*(*it2).second); + } + } + }else{ + _userAttributesVec3f = 0; + } +} + +StrokeAttribute::~StrokeAttribute() +{ + if(_userAttributesReal){ + _userAttributesReal->clear(); + delete _userAttributesReal; + } + if(_userAttributesVec2f){ + _userAttributesVec2f->clear(); + delete _userAttributesVec2f; + } + if(_userAttributesVec3f){ + _userAttributesVec3f->clear(); + delete _userAttributesVec3f; + } +} + +StrokeAttribute& StrokeAttribute::operator=(const StrokeAttribute& iBrother) +{ + int i; + _alpha = iBrother._alpha; + _thickness[0] = iBrother._thickness[0]; + _thickness[1] = iBrother._thickness[1]; + for(i=0; i<3; ++i) + _color[i] = iBrother._color[i]; + _visible = iBrother._visible; + if(iBrother._userAttributesReal){ + if(!_userAttributesReal) + _userAttributesReal = new realMap; + _userAttributesReal = new realMap(*(iBrother._userAttributesReal)); + }else{ + _userAttributesReal = 0; + } + if(iBrother._userAttributesVec2f){ + if(!_userAttributesVec2f) + _userAttributesVec2f = new Vec2fMap; + _userAttributesVec2f = new Vec2fMap(*(iBrother._userAttributesVec2f)); + }else{ + _userAttributesVec2f = 0; + } + if(iBrother._userAttributesVec3f){ + if(!_userAttributesVec3f) + _userAttributesVec3f = new Vec3fMap; + _userAttributesVec3f = new Vec3fMap(*(iBrother._userAttributesVec3f)); + }else{ + _userAttributesVec3f = 0; + } + return *this; +} + +float StrokeAttribute::getAttributeReal(const char *iName) const{ + if(!_userAttributesReal){ + cout << "StrokeAttribute warning: no real attribute was defined"<< endl; + return 0; + } + realMap::iterator a = _userAttributesReal->find(iName); + if(a ==_userAttributesReal->end()){ + cout << "StrokeAttribute warning: no real attribute was added with the name " << iName << endl; + return 0; + } + return (*a).second; +} +Vec2f StrokeAttribute::getAttributeVec2f(const char *iName) const{ + if(!_userAttributesVec2f){ + cout << "StrokeAttribute warning: no Vec2f attribute was defined "<< endl; + return 0; + } + Vec2fMap::iterator a = _userAttributesVec2f->find(iName); + if(a ==_userAttributesVec2f->end()){ + cout << "StrokeAttribute warning: no Vec2f attribute was added with the name " << iName << endl; + return 0; + } + return (*a).second; +} +Vec3f StrokeAttribute::getAttributeVec3f(const char *iName) const{ + if(!_userAttributesVec3f){ + cout << "StrokeAttribute warning: no Vec3f attribute was defined"<< endl; + return 0; + } + Vec3fMap::iterator a = _userAttributesVec3f->find(iName); + if(a ==_userAttributesVec3f->end()){ + cout << "StrokeAttribute warning: no Vec3f attribute was added with the name " << iName << endl; + return 0; + } + return (*a).second; +} +bool StrokeAttribute::isAttributeAvailableReal(const char *iName) const{ + if(!_userAttributesReal){ + return false; + } + realMap::iterator a = _userAttributesReal->find(iName); + if(a ==_userAttributesReal->end()){ + return false; + } + return true; +} +bool StrokeAttribute::isAttributeAvailableVec2f(const char *iName) const{ + if(!_userAttributesVec2f){ + return false; + } + Vec2fMap::iterator a = _userAttributesVec2f->find(iName); + if(a ==_userAttributesVec2f->end()){ + return false; + } + return true; +} +bool StrokeAttribute::isAttributeAvailableVec3f(const char *iName) const{ + if(!_userAttributesVec3f){ + return false; + } + Vec3fMap::iterator a = _userAttributesVec3f->find(iName); + if(a ==_userAttributesVec3f->end()){ + return false; + } + return true; +} +void StrokeAttribute::setAttributeReal(const char *iName, float att){ + if(!_userAttributesReal) + _userAttributesReal = new realMap; + (*_userAttributesReal)[iName] = att; +} +void StrokeAttribute::setAttributeVec2f(const char *iName, const Vec2f& att){ + if(!_userAttributesVec2f) + _userAttributesVec2f = new Vec2fMap; + (*_userAttributesVec2f)[iName] = att; +} +void StrokeAttribute::setAttributeVec3f(const char *iName, const Vec3f& att){ + if(!_userAttributesVec3f) + _userAttributesVec3f = new Vec3fMap; + (*_userAttributesVec3f)[iName] = att; +} + /**********************************/ + /* */ + /* */ + /* StrokeVertex */ + /* */ + /* */ + /**********************************/ + +StrokeVertex::StrokeVertex() + +:CurvePoint() +{ + + _CurvilignAbscissa = 0.f; + + _StrokeLength = 0.f; +} + + + +StrokeVertex::StrokeVertex(const StrokeVertex& iBrother) + +:CurvePoint(iBrother) +{ + _Attribute = iBrother._Attribute; + + _CurvilignAbscissa = 0.f; + + _StrokeLength = 0.f; +} +StrokeVertex::StrokeVertex(SVertex *iSVertex) + +:CurvePoint(iSVertex,0,0.f) + +{ + + _CurvilignAbscissa = 0.f; + + _StrokeLength = 0.f; + +} + + + +StrokeVertex::StrokeVertex(CurvePoint *iPoint) + +:CurvePoint(*iPoint) + +{ + + _CurvilignAbscissa = 0.f; + + _StrokeLength = 0.f; + +} + + + +StrokeVertex::StrokeVertex(StrokeVertex *iA, StrokeVertex *iB, float t3) + +:CurvePoint(iA,iB,t3) + +{ + + // interpolate attributes: + + _Attribute = StrokeAttribute(iA->attribute(), iB->attribute(), t3); + _CurvilignAbscissa = (1-t3)*iA->curvilinearAbscissa()+t3*iB->curvilinearAbscissa(); + _StrokeLength = iA->strokeLength(); + +} + + + +StrokeVertex::StrokeVertex(SVertex *iSVertex, const StrokeAttribute& iAttribute) + +:CurvePoint(iSVertex,0,0.f) + +{ + + _Attribute = iAttribute; + + _CurvilignAbscissa = 0.f; + + _StrokeLength = 0.f; + +} +StrokeVertex::~StrokeVertex() +{ +} + +StrokeVertex& StrokeVertex::operator=(const StrokeVertex& iBrother) +{ + ((CurvePoint*)this)->operator=(iBrother); + _Attribute = iBrother._Attribute; + + _CurvilignAbscissa = 0.f; + + _StrokeLength = 0.f; + return *this; +} + + /**********************************/ + /* */ + /* */ + /* Stroke */ + /* */ + /* */ + /**********************************/ + +Stroke::Stroke() +{ + _Length = 0; + _id = 0; + _sampling = FLT_MAX; + //_mediumType = DEFAULT_STROKE; + _mediumType = OPAQUE_MEDIUM; + _textureId = 0; + _tips = false; + _rep = 0; +} + +Stroke::Stroke(const Stroke& iBrother) +{ + for(vertex_container::const_iterator v=iBrother._Vertices.begin(), vend=iBrother._Vertices.end(); + v!=vend; + v++) + { + _Vertices.push_back(*v); + } + _Length = 0; + _id = iBrother._id; + _ViewEdges = iBrother._ViewEdges; + _sampling = iBrother._sampling; + _mediumType = iBrother._mediumType; + _textureId = iBrother._textureId; + _tips = iBrother._tips; + if(iBrother._rep) + _rep = new StrokeRep(*(iBrother._rep)); + else + _rep = 0; + +} + +Stroke::~Stroke() +{ + if(!_Vertices.empty()) + { + for(vertex_container::iterator v=_Vertices.begin(), vend=_Vertices.end(); + v!=vend; + v++) + { + delete (*v); + } + _Vertices.clear(); + } + + _ViewEdges.clear(); + if(_rep != 0) + { + delete _rep; + _rep = 0; + } +} + +Stroke& Stroke::operator=(const Stroke& iBrother) +{ + if(!_Vertices.empty()) + _Vertices.clear(); + + for(vertex_container::const_iterator v=iBrother._Vertices.begin(), vend=iBrother._Vertices.end(); + v!=vend; + v++) + { + _Vertices.push_back(*v); + } + _Length = iBrother._Length; + _id = iBrother._id; + _ViewEdges = iBrother._ViewEdges; + _sampling = iBrother._sampling; + if(_rep) delete _rep; + if(iBrother._rep) + _rep = new StrokeRep(*(iBrother._rep)); + return *this; +} + + +void Stroke::setLength(float iLength) +{ + _Length = iLength; + for(vertex_container::iterator v=_Vertices.begin(), vend=_Vertices.end(); + v!=vend; + ++v) + { + (*v)->setStrokeLength(iLength); + } +} + +float Stroke::ComputeSampling(int iNVertices) +{ + if(iNVertices <= (int)_Vertices.size()) //soc + return _sampling; + + float sampling = _Length/(float)(iNVertices-_Vertices.size()+1); + return sampling; +} + +class StrokeSegment +{ +public: + StrokeInternal::StrokeVertexIterator _begin; + StrokeInternal::StrokeVertexIterator _end; + float _length; + int _n; + float _sampling; + bool _resampled; + + StrokeSegment(StrokeInternal::StrokeVertexIterator ibegin, + StrokeInternal::StrokeVertexIterator iend, + float ilength, + int in, + float isampling) + { + _begin=ibegin; + _end=iend; + _length=ilength; + _n=in; + _sampling = isampling; + _resampled = false; + } +}; + +void Stroke::Resample(int iNPoints) +{ + int vertsize = strokeVerticesSize(); + if(iNPoints <= vertsize) + return; + + StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator next = it;++next; + StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd(); + + vertex_container newVertices; + real t=0.f; + StrokeVertex * newVertex = 0; + vector<StrokeSegment> strokeSegments; + int N=0; + float meanlength = 0; + int nsegments = 0; + while(((it!=itend)&&(next!=itend))) + { + Vec3r a((it)->point2d()); + Vec3r b((next)->point2d()); + Vec3r vec_tmp(b - a); + real norm_var = vec_tmp.norm(); + int numberOfPointsToAdd = (int)floor((iNPoints-strokeVerticesSize())*norm_var/_Length); + float csampling = norm_var/(float)(numberOfPointsToAdd+1); + strokeSegments.push_back(StrokeSegment(it,next,norm_var,numberOfPointsToAdd, csampling)); + N+=numberOfPointsToAdd; + meanlength += norm_var; + ++nsegments; + ++it; ++next; + } + meanlength /= (float)nsegments; + + // if we don't have enough points let's resample + // finer some segments + int NPointsToAdd = iNPoints-vertsize; + bool checkEveryone = false; + while(N < NPointsToAdd) + { + for(vector<StrokeSegment>::iterator s=strokeSegments.begin(), send=strokeSegments.end(); + s!=send; + ++s) + { + if(s->_sampling == 0.f) + continue; + + if(s->_resampled == false) + { + if((!checkEveryone) && (s->_length < meanlength)) + continue; + //resample + s->_n = s->_n+1; + s->_sampling = s->_length/(float)(s->_n+1); + s->_resampled = true; + N++; + if(N == NPointsToAdd) + break; + } + } + checkEveryone = true; + } + //actually resample: + for(vector<StrokeSegment>::iterator s=strokeSegments.begin(), send=strokeSegments.end(); + s!=send; + ++s) + { + newVertices.push_back(&(*(s->_begin))); + if(s->_sampling < _sampling) + _sampling = s->_sampling; + + t = s->_sampling/s->_length; + for(int i=0; i<s->_n; ++i) + { + newVertex = new StrokeVertex(&(*(s->_begin)),&(*(s->_end)),t); + newVertices.push_back(newVertex); + t += s->_sampling/s->_length; + } + it=s->_begin; + next=s->_end; + } + + // add last: + ++it;++next; + if((it != itend) && (next == itend))// && (t == 0.f)) + newVertices.push_back(&(*it)); + + int newsize = newVertices.size(); + if(newsize != iNPoints) + cerr << "Warning: incorrect points number" << endl; + + _Vertices.clear(); + _Vertices = newVertices; + newVertices.clear(); + + if(_rep) + { + delete _rep; + _rep = new StrokeRep(this); + } +} + + +void Stroke::Resample(float iSampling) +{ + // cerr<<"old size :"<<strokeVerticesSize()<<endl; + if(iSampling == 0) + + return; + if(iSampling >= _sampling) + return ; + + _sampling = iSampling; + // Resample... + //real curvilinearLength = 0.f; + vertex_container newVertices; + real t=0.f; + StrokeVertex * newVertex = 0; + StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator next = it;++next; + StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd(); + while(((it!=itend)&&(next!=itend))) + { + newVertices.push_back(&(*it)); + Vec3r a((it)->point2d()); + Vec3r b((next)->point2d()); + Vec3r vec_tmp(b - a); + real norm_var = vec_tmp.norm(); + if(norm_var <= _sampling) + { + //curvilinearLength += norm_var; + ++it; ++next; + continue; + } + + //curvilinearLength += _sampling; + t = _sampling/norm_var; + float limit = 0.99f; + while(t<limit) + { + newVertex = new StrokeVertex(&(*it),&(*next),t); + //newVertex->setCurvilinearAbscissa(curvilinearLength); + newVertices.push_back(newVertex); + t = t + _sampling/norm_var; + } + ++it; ++next; + } + // add last: + if((it != itend) && (next == itend))// && (t == 0.f)) + newVertices.push_back(&(*it)); + + _Vertices.clear(); + _Vertices = newVertices; + newVertices.clear(); + + if(_rep) + { + delete _rep; + _rep = new StrokeRep(this); + } +} + +void Stroke::RemoveVertex(StrokeVertex *iVertex) +{ + vertex_container::iterator it=_Vertices.begin(), itend=_Vertices.end(); + for(; + it!=itend; + ++it) + { + if((*it) == iVertex) + { + delete iVertex; + it = _Vertices.erase(it); // it is now the element just after the erased element + break; + } + } + // recompute various values (length, curvilign abscissa) + float curvabsc = 0.f; + it=_Vertices.begin(); + itend=_Vertices.end(); + vertex_container::iterator previous=it; + for(; + (it!=itend); + ++it) + { + if(it != previous) + curvabsc += ((*it)->point2d()-(*previous)->point2d()).norm(); + (*it)->setCurvilinearAbscissa(curvabsc); + previous = it; + } + _Length = curvabsc; + it=_Vertices.begin(); + for(; + (it!=itend); + ++it) + { + (*it)->setStrokeLength(_Length); + } +} + +void Stroke::InsertVertex(StrokeVertex *iVertex, StrokeInternal::StrokeVertexIterator next) +{ + vertex_container::iterator it=_Vertices.begin(), itend=_Vertices.end(); + + vertex_container::iterator itnext = next.getIt(); + _Vertices.insert(itnext, iVertex); + // recompute various values (length, curvilign abscissa) + float curvabsc = 0.f; + it=_Vertices.begin(); + itend=_Vertices.end(); + vertex_container::iterator previous=it; + for(; + (it!=itend); + ++it) + { + curvabsc += ((*it)->point2d()-(*previous)->point2d()).norm(); + (*it)->setCurvilinearAbscissa(curvabsc); + previous = it; + } + _Length = curvabsc; + for(; + (it!=itend); + ++it) + { + (*it)->setStrokeLength(_Length); + } +} + +//! embedding vertex iterator +Stroke::const_vertex_iterator Stroke::vertices_begin() const { return const_vertex_iterator(_Vertices.begin(),_Vertices.begin(), _Vertices.end()); } +Stroke::const_vertex_iterator Stroke::vertices_end() const { return const_vertex_iterator(_Vertices.end(),_Vertices.begin(), _Vertices.end()); } +Stroke::vertex_iterator Stroke::vertices_end() { return vertex_iterator(_Vertices.end(),_Vertices.begin(), _Vertices.end()); } + +StrokeInternal::StrokeVertexIterator Stroke::strokeVerticesBegin(float t) { + if((t!=0) && (t < _sampling)) + Resample(t); + return StrokeInternal::StrokeVertexIterator(this->_Vertices.begin(), this->_Vertices.begin(), this->_Vertices.end()); +} + +StrokeInternal::StrokeVertexIterator Stroke::strokeVerticesEnd() { + return StrokeInternal::StrokeVertexIterator(this->_Vertices.end(), this->_Vertices.begin(), this->_Vertices.end()); +} + +Interface0DIterator Stroke::verticesBegin() { + Interface0DIterator ret(new StrokeInternal::StrokeVertexIterator(this->_Vertices.begin(), + this->_Vertices.begin(), + this->_Vertices.end())); + return ret; +} + +Interface0DIterator Stroke::verticesEnd() { + Interface0DIterator ret(new StrokeInternal::StrokeVertexIterator(this->_Vertices.end(), + this->_Vertices.begin(), + this->_Vertices.end())); + return ret; +} + +Interface0DIterator Stroke::pointsBegin(float t) { + return verticesBegin(); // FIXME +} + +Interface0DIterator Stroke::pointsEnd(float t) { + return verticesEnd(); +} + +void Stroke::Render(const StrokeRenderer *iRenderer) +{ + if(!_rep) + _rep = new StrokeRep(this); + iRenderer->RenderStrokeRep(_rep); +} + +void Stroke::RenderBasic(const StrokeRenderer *iRenderer) +{ + if(!_rep) + _rep = new StrokeRep(this); + iRenderer->RenderStrokeRepBasic(_rep); +} + +Stroke::vertex_iterator Stroke::vertices_begin(float sampling) +{ + // Resample if necessary + if((sampling != 0) && (sampling < _sampling)) + Resample(sampling); + return vertex_iterator(_Vertices.begin(),_Vertices.begin(),_Vertices.end()); + //return _Vertices.begin(); +} +// +//Stroke::vertex_iterator Stroke::vertices_last() +//{ +// vertex_iterator res = vertices_begin(); +// vertex_iterator next = res;++next; +// while(!next.end()) +// { +// ++next; +// ++res; +// } +// return res; +//} +// +//Stroke::const_vertex_iterator Stroke::vertices_last() const +//{ +// const_vertex_iterator res = vertices_begin(); +// const_vertex_iterator next = res;++next; +// while(!next.end()) +// { +// ++next; +// ++res; +// } +// return res; +//} + +//Stroke::vertex_container::reverse_iterator Stroke::vertices_last(float sampling) +//{ +// // Resample if necessary +// if(sampling < _sampling) +// Resample(sampling); +// return _Vertices.rbegin(); +//} + + +//inline Vec3r shaded_color(int iCombination = 0) const ; +//inline Vec<3,real> Stroke::orientation2d(const_vertex_iterator it) const +//{ +// return iterator_edge_orientation2d_function<Stroke, const_vertex_iterator>(this, it); +//} +// Vec3r Stroke::orientation2d(int iCombination) const +// { +// return edge_orientation2d_function<Stroke>(*this, iCombination); +// } +//inline Vec3r Stroke::orientation3d(const_vertex_iterator it) const +//{ +// return iterator_edge_orientation3d_function<Stroke, const_vertex_iterator>(*this, it); +//} +// Vec3r Stroke::orientation3d(int iCombination) const +// { +// return edge_orientation3d_function<Stroke>(*this, iCombination); +// } + +//Material Stroke::material() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=strokeVerticesEnd(); +// Material mat = (*v)->material(); +// for(;v!=vend;++v) +// { +// if(mat != (*v)->material()) +// Exception::raiseException(); +// } +// return mat; +//} + +//int Stroke::qi() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// int qi_= (*v)->qi(); +// for(;v!=vend;++v) +// { +// if((*v)->qi() != qi_) +// Exception::raiseException(); +// } +// return qi_; +//} +//inline occluder_container::const_iterator occluders_begin() const {return _FEdgeA->occluders().begin();} +//inline occluder_container::const_iterator occluders_end() const {return _FEdgeA->occluders().end();} + +//int Stroke::occluders_size() const +//{ +// return qi(); +//} +// +//bool Stroke::occluders_empty() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// bool empty = (*v)->occluders_empty(); +// for(;v!=vend;++v) +// { +// if((*v)->occluders_empty() != empty) +// Exception::raiseException(); +// } +// return empty; +//} +////inline const polygon3d& occludee() const {return *(_FEdgeA->aFace());} +//const SShape * Stroke::occluded_shape() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// const SShape *sshape = (*v)->occluded_shape(); +// for(;v!=vend;++v) +// { +// if((*v)->occluded_shape() != sshape) +// Exception::raiseException(); +// } +// return sshape; +//} +// +//const bool Stroke::occludee_empty() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// bool empty = (*v)->occludee_empty(); +// for(;v!=vend;++v) +// { +// if((*v)->occludee_empty() != empty) +// Exception::raiseException(); +// } +// return empty; +//} + +//const SShape * Stroke::shape() const +//{ +// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); +// const SShape *sshape = (*v)->shape(); +// for(;v!=vend;++v) +// { +// if((*v)->shape() != sshape) +// Exception::raiseException(); +// } +// return sshape; +//} + +// real Stroke::z_discontinuity(int iCombination) const +// { +// return z_discontinuity_edge_function<Stroke>(*this, iCombination); +// } + +// Vec3r Stroke::curvature2d_as_vector(int iCombination) const +// { +// return curvature2d_as_vector_edge_function<Stroke>(*this, iCombination); +// } + +// real Stroke::curvature2d_as_angle(int iCombination) const +// { +// return curvature2d_as_angle_edge_function<Stroke>(*this, iCombination); +// } + +// float Stroke::shape_importance(int iCombination) const +// { +// return shape_importance_edge_function<Stroke>(*this, iCombination); +// } + + +// float Stroke::local_average_depth(int iCombination ) const +// { +// return local_average_depth_edge_function<Stroke >(*this, iCombination); +// } + +// float Stroke::local_depth_variance(int iCombination) const +// { +// return local_depth_variance_edge_function<Stroke>(*this, iCombination); +// } + +// real Stroke::local_average_density(float sigma , int iCombination ) const +// { +// return density_edge_function<Stroke>(*this, iCombination); +// } diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h new file mode 100755 index 00000000000..796b5dc9e2d --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Stroke.h @@ -0,0 +1,588 @@ +// +// Filename : Stroke.h +// Author(s) : Stephane Grabli +// Purpose : Classes to define a stroke +// Date of creation : 09/09/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef STROKE_H +# define STROKE_H + +# include <vector> +# include <map> +# include "../system/FreestyleConfig.h" +# include "../view_map/Silhouette.h" +# include "Curve.h" +# include "../view_map/Interface1D.h" +# include "../system/StringUtils.h" + + +// +// StrokeAttribute +// +//////////////////////////////////////////////////////// + +/*! Class to define an attribute associated to a Stroke Vertex. + * This attribute stores the color, alpha and thickness values + * for a Stroke Vertex. + */ +class LIB_STROKE_EXPORT StrokeAttribute +{ +public: + + /*! default constructor */ + StrokeAttribute(); + /*! Copy constructor */ + StrokeAttribute(const StrokeAttribute& iBrother); + /*! Builds a stroke vertex attribute from + * a set of parameters. + * \param iRColor + * The Red Component value. + * \param iGColor + * The Green Component value. + * \param iBColor + * The Blue Component value. + * \param iAlpha + * The transparency value + * \param iRThickness + * The thickness of the stroke on the right + * \param iLThickness + * The Thickness of the stroke on the left + */ + StrokeAttribute(float iRColor, float iGColor, float iBColor, + float iAlpha, + float iRThickness, float iLThickness); + + /*! Interpolation constructor. + * Builds a StrokeAttribute from two + * StrokeAttributes and an interpolation parameter. + * \param a1 + * The first Attribute. + * \param a2 + * The second parameter. + * \param t + * The interpolation parameter. + */ + StrokeAttribute(const StrokeAttribute& a1, const StrokeAttribute& a2, float t); + + /*! destructor */ + virtual ~StrokeAttribute(); + + /* operators */ + /*! operator = */ + StrokeAttribute& operator=(const StrokeAttribute& iBrother); + + /* accessors */ + /*! Returns the attribute's color. + * \return The array of 3 floats containing the R,G,B values + * of the attribute's color. + */ + inline const float* getColor() const { return _color; } + /*! Returns the R color component. */ + inline const float getColorR() const { return _color[0]; } + /*! Returns the G color component. */ + inline const float getColorG() const { return _color[1]; } + /*! Returns the B color component. */ + inline const float getColorB() const { return _color[2]; } + /*! Returns the RGB color components. */ + inline Vec3f getColorRGB() const { return Vec3f(_color[0], _color[1], _color[2]); } + /*! Returns the alpha color component. */ + inline float getAlpha() const { return _alpha; } + /*! Returns the attribute's thickness. + * \return an array of 2 floats. the first value is + * the thickness on the right of the vertex when following + * the stroke, the second one is the thickness on the left. + */ + inline const float* getThickness() const { return _thickness; } + /*! Returns the thickness on the right of the vertex when following the + * stroke. */ + inline const float getThicknessR() const { return _thickness[0]; } + /*! Returns the thickness on the left of the vertex when following the + * stroke. */ + inline const float getThicknessL() const { return _thickness[1]; } + /*! Returns the thickness on the right and on the left of the vertex when following the + * stroke. */ + inline Vec2f getThicknessRL() const { return Vec2f(_thickness[0], _thickness[1]); } + + /*! Returns true if the strokevertex is visible, false otherwise */ + inline bool isVisible() const {return _visible;} + + /*! Returns an attribute of type real + * \param iName + * The name of the attribute + */ + float getAttributeReal(const char *iName) const; + /*! Returns an attribute of type Vec2f + * \param iName + * The name of the attribute + */ + Vec2f getAttributeVec2f(const char *iName) const; + /*! Returns an attribute of type Vec3f + * \param iName + * The name of the attribute + */ + Vec3f getAttributeVec3f(const char *iName) const; + + /*! Checks whether the attribute iName is availbale */ + bool isAttributeAvailableReal(const char *iName) const ; + /*! Checks whether the attribute iName is availbale */ + bool isAttributeAvailableVec2f(const char *iName) const ; + /*! Checks whether the attribute iName is availbale */ + bool isAttributeAvailableVec3f(const char *iName) const ; + + /* modifiers */ + /*! sets the attribute's color. + * \param r + * The new R value. + * \param g + * The new G value. + * \param b + * The new B value. + */ + inline void setColor(float r, float g, float b) { _color[0]=r; _color[1]=g; _color[2]=b; } + /*! sets the attribute's color. + * \param iRGB + * The new RGB values. + */ + inline void setColor(const Vec3f& iRGB) { _color[0]=iRGB[0]; _color[1]=iRGB[1]; _color[2]=iRGB[2]; } + /*! sets the attribute's alpha value. + * \param alpha + * The new alpha value. + */ + inline void setAlpha(float alpha) { _alpha = alpha; } + /*! sets the attribute's thickness. + * \param tr + * The thickness on the right of the vertex when following the stroke. + * \param tl + * The thickness on the left of the vertex when following the stroke. + */ + inline void setThickness(float tr, float tl) { _thickness[0]=tr; _thickness[1]=tl; } + /*! sets the attribute's thickness. + * \param tRL + * The thickness on the right and on the left of the vertex when following the stroke. + */ + inline void setThickness(const Vec2f& tRL) { _thickness[0]=tRL[0]; _thickness[1]=tRL[1]; } + + /*! sets the visible flag. True means visible. */ + inline void setVisible(bool iVisible){ _visible = iVisible; } + + /*! Adds a user defined attribute of type real + * If there is no attribute of name iName, it is added. + * Otherwise, the new value replaces the old one. + * \param iName + * The name of the attribute + * \param att + * The attribute's value + */ + void setAttributeReal(const char *iName, float att); + /*! Adds a user defined attribute of type Vec2f + * If there is no attribute of name iName, it is added. + * Otherwise, the new value replaces the old one. + * \param iName + * The name of the attribute + * \param att + * The attribute's value + */ + void setAttributeVec2f(const char *iName, const Vec2f& att); + /*! Adds a user defined attribute of type Vec3f + * If there is no attribute of name iName, it is added. + * Otherwise, the new value replaces the old one. + * \param iName + * The name of the attribute + * \param att + * The attribute's value + */ + void setAttributeVec3f(const char *iName, const Vec3f& att); + +private: + + typedef std::map<const char*, float, StringUtils::ltstr> realMap ; + typedef std::map<const char*, Vec2f, StringUtils::ltstr> Vec2fMap ; + typedef std::map<const char*, Vec3f, StringUtils::ltstr> Vec3fMap ; + + float _color[3]; //! the color + float _alpha; //! alpha + float _thickness[2]; //! the thickness on the right and on the left of the backbone vertex (the stroke is oriented) + bool _visible; + realMap *_userAttributesReal; + Vec2fMap *_userAttributesVec2f; + Vec3fMap *_userAttributesVec3f; +}; + + +// +// StrokeVertex +// +//////////////////////////////////////////////////////// + +/*! Class to define a stroke vertex. + */ +class LIB_STROKE_EXPORT StrokeVertex : public CurvePoint +{ +public: // Implementation of Interface0D + + /*! Returns the string "StrokeVertex"*/ + virtual string getExactTypeName() const { + return "StrokeVertex"; + } + +private: + + StrokeAttribute _Attribute; //! The attribute associated to the vertex + float _CurvilignAbscissa; //! the curvilign abscissa + float _StrokeLength; // stroke length + +public: + + /*! default constructor */ + StrokeVertex(); + /*! Copy constructor */ + StrokeVertex(const StrokeVertex& iBrother); + /*! Builds a stroke vertex from a SVertex */ + StrokeVertex(SVertex *iSVertex); + /*! Builds a stroke vertex from a CurvePoint */ + StrokeVertex(CurvePoint *iPoint); + /*! Builds Stroke Vertex from 2 stroke vertices and an interpolation parameter*/ + StrokeVertex(StrokeVertex *iA, StrokeVertex *iB, float t3); + /*! Builds a stroke from a view vertex and an attribute */ + StrokeVertex(SVertex *iSVertex, const StrokeAttribute& iAttribute); + /*! destructor */ + virtual ~StrokeVertex(); + + /* operators */ + /*! operator = */ + StrokeVertex& operator=(const StrokeVertex& iBrother); + + /* accessors */ + /*! Returns the 2D point x coordinate */ + inline real x() const { return _Point2d[0]; } + /*! Returns the 2D point y coordinate */ + inline real y() const { return _Point2d[1]; } + /*! Returns the 2D point coordinates as a Vec2d */ + Vec2f getPoint () {return Vec2f((float)point2d()[0], (float)point2d()[1]);} + /*! Returns the ith 2D point coordinate (i=0 or 1)*/ + inline real operator[](const int i) const { return _Point2d[i]; } + /*! Returns the StrokeAttribute for this StrokeVertex */ + inline const StrokeAttribute& attribute() const { return _Attribute; } + /*! Returns a non-const reference to the StrokeAttribute of this StrokeVertex */ + inline StrokeAttribute& attribute() {return _Attribute;} + /*! Returns the curvilinear abscissa */ + inline float curvilinearAbscissa() const {return _CurvilignAbscissa;} + /*! Returns the length of the Stroke to which this StrokeVertex belongs */ + inline float strokeLength() const {return _StrokeLength;} + /*! Returns the curvilinear abscissa of this StrokeVertex in the Stroke */ + inline float u() const {return _CurvilignAbscissa/_StrokeLength;} + + /* modifiers */ + /*! sets the 2D x value */ + inline void setX(real x) { _Point2d[0]=x; } + /*! sets the 2D y value */ + inline void setY(real y) { _Point2d[1]=y; } + /*! sets the 2D x and y values */ + inline void setPoint(real x, real y) { _Point2d[0]=x; _Point2d[1]=y;} + /*! sets the 2D x and y values */ + inline void setPoint(const Vec2f& p) { _Point2d[0] = p[0];_Point2d[1] = p[1];} + /*! Returns a reference to the ith 2D point coordinate (i=0 or 1) */ + inline real& operator[](const int i) { return _Point2d[i]; } + /*! sets the attribute. */ + inline void setAttribute(const StrokeAttribute& iAttribute) { _Attribute = iAttribute; } + /*! sets the curvilinear abscissa of this StrokeVertex in the Stroke */ + inline void setCurvilinearAbscissa(float iAbscissa) {_CurvilignAbscissa = iAbscissa;} + /*! sets the Stroke's length (it's only a value stored by the Stroke Vertex, it won't + * change the real Stroke's length.) + */ + inline void setStrokeLength(float iLength) {_StrokeLength = iLength;} + + /* interface definition */ + /* inherited */ + +}; + + +// +// Stroke +// +//////////////////////////////////////////////////////// + +class StrokeRenderer; +class StrokeRep; + +namespace StrokeInternal { + class vertex_const_traits ; + class vertex_nonconst_traits ; + template<class Traits> class vertex_iterator_base; + class StrokeVertexIterator; +} // end of namespace StrokeInternal + +/*! Class to define a stroke. + * A stroke is made of a set of 2D vertices (StrokeVertex), regularly spaced out. + * This set of vertices defines the stroke's backbone geometry. + * Each of these stroke vertices defines the stroke's shape and appearance + * at this vertex position. + */ +class LIB_STROKE_EXPORT Stroke : public Interface1D +{ +public: // Implementation of Interface1D + + /*! Returns the string "Stroke" */ + virtual string getExactTypeName() const { + return "Stroke"; + } + + // Data access methods + + /*! Returns the Id of the Stroke */ + virtual Id getId() const { + return _id; + } + /*! The different blending modes + * available to similate the interaction + * media-medium. + */ + typedef enum{ + DRY_MEDIUM,/*!< To simulate a dry medium such as Pencil or Charcoal.*/ + HUMID_MEDIUM,/*!< To simulate ink painting (color substraction blending).*/ + OPAQUE_MEDIUM, /*!< To simulate an opaque medium (oil, spray...).*/ + } MediumType; + + +public: + typedef std::deque<StrokeVertex*> vertex_container; // the vertices container + typedef std::vector<ViewEdge*> viewedge_container; // the viewedges container + typedef StrokeInternal::vertex_iterator_base<StrokeInternal::vertex_nonconst_traits > vertex_iterator; + typedef StrokeInternal::vertex_iterator_base<StrokeInternal::vertex_const_traits> const_vertex_iterator; + +public: + //typedef StrokeVertex vertex_type; +private: + vertex_container _Vertices; //! The stroke's backbone vertices + Id _id; + float _Length; // The stroke length + viewedge_container _ViewEdges; + float _sampling; + StrokeRenderer *_renderer; // mark implementation OpenGL renderer + MediumType _mediumType; + unsigned int _textureId; + bool _tips; + Vec2r _extremityOrientations[2]; // the orientations of the first and last extermity + StrokeRep *_rep; + +public: + /*! default constructor */ + Stroke(); + /*! copy constructor */ + Stroke(const Stroke& iBrother); + /*! Builds a stroke from a set of StrokeVertex. + * This constructor is templated by an iterator type. + * This iterator type must allow the vertices parsing + * using the ++ operator. + * \param iBegin + * The iterator pointing to the first vertex. + * \param iEnd + * The iterator pointing to the end of the vertex list. + */ + template<class InputVertexIterator> + Stroke(InputVertexIterator iBegin, InputVertexIterator iEnd); + + /*! Destructor */ + virtual ~Stroke(); + + /* operators */ + /*! operator = */ + Stroke& operator=(const Stroke& iBrother); + + /*! Compute the sampling needed to get iNVertices + * vertices. + * If the specified number of vertices is less than the + * actual number of vertices, the actual sampling value is returned. + * (To remove Vertices, use the RemoveVertex() method of this class). + * \param iNVertices + * The number of StrokeVertices we eventually want + * in our Stroke. + * \return the sampling that must be used in the Resample(float) method. + * @see Resample(int) + * @see Resample(float) + */ + float ComputeSampling(int iNVertices); + + /*! Resampling method. + * Resamples the curve so that it eventually + * has iNPoints. That means it is going + * to add iNPoints-vertices_size, if vertices_size + * is the number of points we already have. + * Is vertices_size >= iNPoints, no resampling is done. + * \param iNPoints + * The number of vertices we eventually want in our stroke. + */ + void Resample(int iNPoints); + + /*! Resampling method. + * Resamples the curve with a given sampling. + * If this sampling is < to the actual sampling + * value, no resampling is done. + * \param iSampling + * The new sampling value. + */ + void Resample(float iSampling); + + /*! Removes the stroke vertex iVertex + * from the stroke. + * The length and curvilinear abscissa are updated + * consequently. + */ + void RemoveVertex(StrokeVertex *iVertex); + + /*! Inserts the stroke vertex iVertex + * in the stroke before next. + * The length, curvilinear abscissa are updated + * consequently. + * \param iVertex + * The StrokeVertex to insert in the Stroke. + * \param next + * A StrokeVertexIterator pointing to the StrokeVeretx before + * which iVertex must be inserted. + */ + void InsertVertex(StrokeVertex *iVertex, StrokeInternal::StrokeVertexIterator next); + + /* Render method */ + void Render(const StrokeRenderer *iRenderer ); + void RenderBasic(const StrokeRenderer *iRenderer ); + + /* Iterator definition */ + + /* accessors */ + /*! Returns the 2D length of the Stroke */ + inline real getLength2D() const {return _Length;} + /*! Returns a reference to the time stamp value of the stroke. */ + /*! Returns the MediumType used for this Stroke. */ + inline MediumType getMediumType() const {return _mediumType;} + /*! Returns the id of the texture used to simulate th marks system + * for this Stroke + */ + inline unsigned int getTextureId() {return _textureId;} + /*! Returns true if this Stroke uses a texture with tips, false + * otherwise. + */ + inline bool hasTips() const {return _tips;} + /* these advanced iterators are used only in C++ */ + inline int vertices_size() const {return _Vertices.size();} + inline viewedge_container::const_iterator viewedges_begin() const {return _ViewEdges.begin();} + inline viewedge_container::iterator viewedges_begin() {return _ViewEdges.begin();} + inline viewedge_container::const_iterator viewedges_end() const {return _ViewEdges.end();} + inline viewedge_container::iterator viewedges_end() {return _ViewEdges.end();} + inline int viewedges_size() const {return _ViewEdges.size();} + + inline Vec2r getBeginningOrientation() const {return _extremityOrientations[0];} + inline real getBeginningOrientationX() const {return _extremityOrientations[0].x();} + inline real getBeginningOrientationY() const {return _extremityOrientations[0].y();} + inline Vec2r getEndingOrientation() const {return _extremityOrientations[1];} + inline real getEndingOrientationX() const {return _extremityOrientations[1].x();} + inline real getEndingOrientationY() const {return _extremityOrientations[1].y();} + + + /* modifiers */ + /*! sets the Id of the Stroke. */ + inline void setId(const Id& id) {_id = id;} + /*! sets the 2D length of the Stroke. */ + void setLength(float iLength); + /*! sets the medium type that must be used for this Stroke. */ + inline void setMediumType(MediumType iType) {_mediumType = iType;} + /*! sets the texture id to be used to simulate the marks system for this Stroke. */ + inline void setTextureId(unsigned int id) {_textureId = id;} + /*! sets the flag telling whether this stroke is using a texture with + * tips or not. + */ + inline void setTips(bool iTips) {_tips = iTips;} + + inline void push_back(StrokeVertex* iVertex) { _Vertices.push_back(iVertex); } + inline void push_front(StrokeVertex* iVertex) { _Vertices.push_front(iVertex); } + inline void AddViewEdge(ViewEdge *iViewEdge) {_ViewEdges.push_back(iViewEdge);} + inline void setBeginningOrientation(const Vec2r& iOrientation) {_extremityOrientations[0] = iOrientation;} + inline void setBeginningOrientation(real x, real y) {_extremityOrientations[0] = Vec2r(x,y);} + inline void setEndingOrientation(const Vec2r& iOrientation) {_extremityOrientations[1] = iOrientation;} + inline void setEndingOrientation(real x, real y) {_extremityOrientations[1] = Vec2r(x,y);} + + /* Information access interface */ + + // embedding vertex iterator + const_vertex_iterator vertices_begin() const; + vertex_iterator vertices_begin(float t=0.f); + const_vertex_iterator vertices_end() const; + vertex_iterator vertices_end(); + + /*! Returns a StrokeVertexIterator pointing on the first StrokeVertex of the + * Stroke. One can specifly a sampling value to resample the Stroke + * on the fly if needed. + * \param t + * The resampling value with which we want our Stroke to be resampled. + * If 0 is specified, no resampling is done. + */ + StrokeInternal::StrokeVertexIterator strokeVerticesBegin(float t=0.f); + /*! Returns a StrokeVertexIterator pointing after the last StrokeVertex of the + * Stroke. + */ + StrokeInternal::StrokeVertexIterator strokeVerticesEnd(); + /*! Returns the number of StrokeVertex constituing the Stroke. */ + inline unsigned int strokeVerticesSize() const {return _Vertices.size();} + + /*! Returns the i-th StrokeVertex constituting the Stroke. */ + inline StrokeVertex& strokeVerticeAt(unsigned int i) {return *(_Vertices.at(i));} + + // Iterator access (Interface1D) + /*! Returns an Interface0DIterator pointing on the first StrokeVertex of the + * Stroke. + */ + virtual Interface0DIterator verticesBegin(); + /*! Returns an Interface0DIterator pointing after the last StrokeVertex of the + * Stroke. + */ + virtual Interface0DIterator verticesEnd(); + + virtual Interface0DIterator pointsBegin(float t=0.f); + virtual Interface0DIterator pointsEnd(float t=0.f); +}; + + + +// +// Implementation +// +//////////////////////////////////////////////////////// + + +template<class InputVertexIterator> +Stroke::Stroke(InputVertexIterator iBegin, InputVertexIterator iEnd) +{ + for(InputVertexIterator v=iBegin, vend=iEnd; + v!=vend; + v++) + { + _Vertices.push_back(*v); + } + _Length = 0; + _id = 0; +} + +#endif // STROKE_H diff --git a/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h b/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h new file mode 100755 index 00000000000..279a0b12089 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h @@ -0,0 +1,142 @@ +// +// Filename : StrokeAdvancedIterators.h +// Author(s) : Stephane Grabli +// Purpose : Iterators used to iterate over the elements of the Stroke +// Can't be used in python +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef STROKEADVANCEDITERATORS_H +# define STROKEADVANCEDITERATORS_H + +# include "Stroke.h" + +namespace StrokeInternal { + + class vertex_const_traits : public Const_traits<StrokeVertex*> { + public: + typedef std::deque<StrokeVertex*> vertex_container; + typedef vertex_container::const_iterator vertex_container_iterator ; + }; + class vertex_nonconst_traits : public Nonconst_traits<StrokeVertex*> { + public: + typedef std::deque<StrokeVertex*> vertex_container; //! the vertices container + typedef vertex_container::iterator vertex_container_iterator ; + }; + + + template<class Traits> + class vertex_iterator_base : public IteratorBase<Traits,BidirectionalIteratorTag_Traits> + { + public: + typedef vertex_iterator_base<Traits> Self; + protected: + typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class; + typedef typename Traits::vertex_container_iterator vertex_container_iterator; + typedef vertex_iterator_base<vertex_nonconst_traits> iterator; + typedef vertex_iterator_base<vertex_const_traits> const_iterator; + //protected: + public: + vertex_container_iterator _it; + vertex_container_iterator _begin; + vertex_container_iterator _end; + public: + friend class Stroke; + //friend class vertex_iterator; + inline vertex_iterator_base() + : parent_class() + {} + inline vertex_iterator_base(const iterator& iBrother) + : parent_class() + {_it = iBrother._it;_begin = iBrother._begin;_end = iBrother._end;} + inline vertex_iterator_base(const const_iterator& iBrother) + : parent_class() + {_it = iBrother._it;_begin = iBrother._begin;_end = iBrother._end;} + //protected://FIXME + public: + inline vertex_iterator_base(vertex_container_iterator it, vertex_container_iterator begin, vertex_container_iterator end) + : parent_class() + { + _it = it; + _begin = begin; + _end = end; + } + + public: + virtual ~vertex_iterator_base() {} + + virtual bool begin() const {return _it==_begin? true : false;} + virtual bool end() const {return _it==_end ? true : false;} + + // operators + inline Self& operator++() // operator corresponding to ++i + { + ++_it; + return *(this); + } + inline Self operator++(int) // opérateur correspondant à i++ + { + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + ++_it; // dans un temporaire. + return tmp; + } + inline Self& operator--() // operator corresponding to ++i + { + --_it; + return *(this); + } + inline Self operator--(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + --_it; // dans un temporaire. + return tmp; + } + + // comparibility + virtual bool operator!=(const Self& b) const + { + return (_it != b._it); + } + virtual bool operator==(const Self& b) const + { + return !(*this != b); + } + + // dereferencing + virtual typename Traits::reference operator*() const {return *(_it);} + virtual typename Traits::pointer operator->() const { return &(operator*());} + + /*! accessors */ + inline vertex_container_iterator it() const {return _it;} + inline vertex_container_iterator getBegin() const {return _begin;} + inline vertex_container_iterator getEnd() const {return _end;} + }; + +} // end of namespace StrokeInternal + + +#endif // STROKEADVANCEDITERATORS_H + + diff --git a/source/blender/freestyle/intern/stroke/StrokeIO.cpp b/source/blender/freestyle/intern/stroke/StrokeIO.cpp new file mode 100755 index 00000000000..903a198adc2 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeIO.cpp @@ -0,0 +1,55 @@ +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "StrokeIO.h" +#include "StrokeAdvancedIterators.h" + + +ostream& operator<<(ostream& out, const StrokeAttribute& iStrokeAttribute){ + out << " StrokeAttribute" << endl; + out << " color : (" << iStrokeAttribute.getColorR() << "," << iStrokeAttribute.getColorG() << "," << iStrokeAttribute.getColorB() << ")" << endl; + out << " alpha : " << iStrokeAttribute.getAlpha() << endl; + out << " thickness : " << iStrokeAttribute.getThicknessR() << ", " << iStrokeAttribute.getThicknessL() << endl; + out << " visible : " << iStrokeAttribute.isVisible() << endl; + return out; +} + +ostream& operator<<(ostream& out, const StrokeVertex& iStrokeVertex){ + out << " StrokeVertex" << endl; + out << " id : " << iStrokeVertex.getId() << endl; + out << " curvilinear length : " << iStrokeVertex.curvilinearAbscissa() << endl; + out << " 2d coordinates : (" << iStrokeVertex.getProjectedX() << "," << iStrokeVertex.getProjectedY() << "," << iStrokeVertex.getProjectedZ() << ")" << endl; + out << " 3d coordinates : (" << iStrokeVertex.getX() << "," << iStrokeVertex.getY() << "," << iStrokeVertex.getZ() << ")"<< endl; + out << iStrokeVertex.attribute() << endl; + return out; +} + +ostream& operator<<(ostream& out, const Stroke& iStroke){ + out << "Stroke" << endl; + out << " id : " << iStroke.getId() << endl; + out << " length : " << iStroke.getLength2D() << endl; + out << " medium type : " << iStroke.getMediumType() << endl; + for(Stroke::const_vertex_iterator v=iStroke.vertices_begin(), vend=iStroke.vertices_end(); + v!=vend; + ++v){ + out << *(*v) << endl; + } + return out; +} diff --git a/source/blender/freestyle/intern/stroke/StrokeIO.h b/source/blender/freestyle/intern/stroke/StrokeIO.h new file mode 100755 index 00000000000..c99704c3b37 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeIO.h @@ -0,0 +1,47 @@ +// +// Filename : StrokeIO.h +// Author(s) : Stephane Grabli +// Purpose : Functions to manage I/O for the stroke +// Date of creation : 03/02/2004 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef STROKEIO_H +# define STROKEIO_H + +# include <iostream> +# include "../system/FreestyleConfig.h" +# include "Stroke.h" + +LIB_STROKE_EXPORT +ostream& operator<<(ostream& out, const StrokeAttribute& iStrokeAttribute); + +LIB_STROKE_EXPORT +ostream& operator<<(ostream& out, const StrokeVertex& iStrokeVertex); + +LIB_STROKE_EXPORT +ostream& operator<<(ostream& out, const Stroke& iStroke); + + +#endif // STROKEIO_H diff --git a/source/blender/freestyle/intern/stroke/StrokeIterators.h b/source/blender/freestyle/intern/stroke/StrokeIterators.h new file mode 100755 index 00000000000..b51189f3990 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeIterators.h @@ -0,0 +1,229 @@ +// +// Filename : StrokeIterators.h +// Author(s) : Stephane Grabli +// Purpose : Iterators used to iterate over the elements of the Stroke +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef STROKEITERATORS_H +# define STROKEITERATORS_H + +# include "Stroke.h" + +namespace StrokeInternal { + + // + // StrokeVertexIterator + // + ///////////////////////////////////////////////// + + /*! Class defining an iterator designed to iterate over + * the StrokeVertex of a Stroke. + * An instance of a StrokeVertexIterator can only be obtained + * from a Stroke by calling strokeVerticesBegin() or strokeVerticesEnd(). + * It is iterating over the same vertices as an Interface0DIterator. + * The difference resides in the object access. Indeed, an Interface0DIterator + * allows only an access to an Interface0D whereas we could need + * to access the specialized StrokeVertex type. In this case, one + * should use a StrokeVertexIterator. + * The castToInterface0DIterator() method is useful to get an Interface0DIterator + * from a StrokeVertexIterator in order to call any functions of the + * type UnaryFunction0D. + * \attention In the scripting language, you must call + * \code it2 = StrokeVertexIterator(it1) \endcode instead of + * \code it2 = it1 \endcode + * where \a it1 and \a it2 are 2 StrokeVertexIterator. + * Otherwise, incrementing \a it1 will also increment \a it2. + */ + class StrokeVertexIterator : public Interface0DIteratorNested + { + public: + + /*! Default constructor. */ + StrokeVertexIterator() {} + + /*! Copy constructor. */ + StrokeVertexIterator(const StrokeVertexIterator& vi) { + _it = vi._it; + _begin = vi._begin; + _end = vi._end; + } + + StrokeVertexIterator(const ::Stroke::vertex_container::iterator& it, + const ::Stroke::vertex_container::iterator& begin, + const ::Stroke::vertex_container::iterator& end) { + _it = it; + _begin = begin; + _end = end; + } + + virtual ~StrokeVertexIterator() {} + + /*! Casts this StrokeVertexIterator into an Interface0DIterator. + * Useful for any call to a function of the type UnaryFunction0D. + */ + inline Interface0DIterator castToInterface0DIterator() const { + Interface0DIterator ret(new StrokeVertexIterator(*this)); + return ret; + } + /*! operator= + * \attention In the scripting language, you must call + * \code it2 = StrokeVertexIterator(it1) \endcode instead of + * \code it2 = it1 \endcode + * where \a it1 and \a it2 are 2 StrokeVertexIterator. + * Otherwise, incrementing \a it1 will also increment \a it2. + * + */ + StrokeVertexIterator& operator=(const StrokeVertexIterator& vi) { + _it = vi._it; + _begin = vi._begin; + _end = vi._end; + return *this; + } + + /*! Returns the string "StrokeVertexIterator". */ + virtual string getExactTypeName() const { + return "StrokeVertexIterator"; + } + + /*! Returns a reference to the pointed StrokeVertex. + * In the scripting language, you must call + * "getObject()"instead. + */ + virtual StrokeVertex& operator*() { + return **_it; + } + + /*! Returns a pointer to the pointed StrokeVertex. + * Can't be called in the scripting language. + */ + virtual StrokeVertex* operator->() { + return &(operator*()); + } + + /*! Increments. In the scripting language, call + * "increment()". + */ + virtual StrokeVertexIterator& operator++() { + increment(); + return *this; + } + + /*! Increments. In the scripting language, call + * "increment()". + */ + virtual StrokeVertexIterator operator++(int) { + StrokeVertexIterator ret(*this); + increment(); + return ret; + } + + /*! Decrements. In the scripting language, call + * "decrement()". + */ + virtual StrokeVertexIterator& operator--() { + decrement(); + return *this; + } + + /*! Decrements. In the scripting language, call + * "decrement()". + */ + virtual StrokeVertexIterator operator--(int) { + StrokeVertexIterator ret(*this); + decrement(); + return ret; + } + + /*! Increments. */ + virtual int increment() { + ++_it; + return 0; + } + + /*! Decrements. */ + virtual int decrement() { + --_it; + return 0; + } + + /*! Returns true if the pointed StrokeVertex is the + * first of the Stroke. + */ + bool isBegin() const { + return _it == _begin; + } + + /*! Returns true if the pointed StrokeVertex is after the + * last StrokeVertex of the Stroke. + */ + bool isEnd() const { + return _it == _end; + } + + /*! operator == */ + virtual bool operator==(const Interface0DIteratorNested& it) const { + const StrokeVertexIterator* it_exact = dynamic_cast<const StrokeVertexIterator*>(&it); + if (!it_exact) + return false; + return (_it == it_exact->_it); + } + + /*! Returns the curvilinear abscissa of the current point */ + virtual float t() const{ + return (*_it)->curvilinearAbscissa(); + } + /*! Returns the point's parameter in the stroke */ + virtual float u() const{ + return (*_it)->u(); + } + + /*! Cloning method */ + virtual StrokeVertexIterator* copy() const { + return new StrokeVertexIterator(*this); + } + + // + // Not exported in Python + // + ////////////////////////////////////////////////// + + const ::Stroke::vertex_container::iterator& getIt() { + return _it; + } + + private: + + ::Stroke::vertex_container::iterator _it; + ::Stroke::vertex_container::iterator _begin; + ::Stroke::vertex_container::iterator _end; + }; + +} // end of namespace StrokeInternal + + +#endif // STROKEITERATORS_H + + diff --git a/source/blender/freestyle/intern/stroke/StrokeLayer.cpp b/source/blender/freestyle/intern/stroke/StrokeLayer.cpp new file mode 100755 index 00000000000..8b469399ca8 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeLayer.cpp @@ -0,0 +1,55 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "StrokeLayer.h" +#include "Stroke.h" +#include "Canvas.h" + +StrokeLayer::~StrokeLayer() +{ + clear(); +} + +void StrokeLayer::Render(const StrokeRenderer *iRenderer ) +{ + for(StrokeLayer::stroke_container::iterator s=_strokes.begin(), send=_strokes.end(); + s!=send; + ++s){ + (*s)->Render(iRenderer); + } +} + +void StrokeLayer::RenderBasic(const StrokeRenderer *iRenderer ) +{ + for(StrokeLayer::stroke_container::iterator s=_strokes.begin(), send=_strokes.end(); + s!=send; + ++s){ + (*s)->RenderBasic(iRenderer); + } +} +void StrokeLayer::clear() +{ + for(stroke_container::iterator s=_strokes.begin(), send=_strokes.end(); + s!=send; + ++s) + delete *s; + _strokes.clear(); +} diff --git a/source/blender/freestyle/intern/stroke/StrokeLayer.h b/source/blender/freestyle/intern/stroke/StrokeLayer.h new file mode 100755 index 00000000000..dbe9ea5a75c --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeLayer.h @@ -0,0 +1,75 @@ +// +// Filename : StrokeLayer.h +// Author : Stephane Grabli +// Purpose : Class to define a layer of strokes. +// Date of creation : 18/12/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef STROKELAYER_H +# define STROKELAYER_H + +# include <deque> + +class Stroke; +class StrokeRenderer; +class StrokeLayer +{ +public: + typedef std::deque<Stroke*> stroke_container; + +protected: + stroke_container _strokes; +public: + StrokeLayer() {} + StrokeLayer(const stroke_container& iStrokes) + { + _strokes = iStrokes; + } + StrokeLayer(const StrokeLayer& iBrother) + { + _strokes = iBrother._strokes; + } + virtual ~StrokeLayer() ; + + /*! Render method */ + void Render(const StrokeRenderer *iRenderer ); + void RenderBasic(const StrokeRenderer *iRenderer ); + + /*! clears the layer */ + void clear() ; + + /*! accessors */ + inline stroke_container::iterator strokes_begin() {return _strokes.begin();} + inline stroke_container::iterator strokes_end() {return _strokes.end();} + inline int strokes_size() const {return _strokes.size();} + inline bool empty() const {return _strokes.empty();} + + /*! modifiers */ + inline void setStrokes(stroke_container& iStrokes) {_strokes = iStrokes;} + inline void AddStroke(Stroke *iStroke) {_strokes.push_back(iStroke);} + +}; + +#endif // STROKELAYER_H diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp new file mode 100755 index 00000000000..19e5ba35fed --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp @@ -0,0 +1,121 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "StrokeRenderer.h" +#include "../geometry/GeomUtils.h" +using namespace std; + +/**********************************/ +/* */ +/* */ +/* StrokeRenderer */ +/* */ +/* */ +/**********************************/ + +LIB_STROKE_EXPORT +TextureManager *StrokeRenderer::_textureManager = 0; + +StrokeRenderer::StrokeRenderer () +{ +} + +StrokeRenderer::~StrokeRenderer () +{ +} + +bool StrokeRenderer::loadTextures() +{ + _textureManager->load(); + return true; +} + + +/**********************************/ +/* */ +/* */ +/* TextureManager */ +/* */ +/* */ +/**********************************/ + + +LIB_STROKE_EXPORT +TextureManager* TextureManager::_pInstance = 0; + +LIB_STROKE_EXPORT +string TextureManager::_patterns_path; + +LIB_STROKE_EXPORT +string TextureManager::_brushes_path; + +TextureManager::TextureManager () +{ + _hasLoadedTextures=false; + _pInstance = this; + _defaultTextureId = 0; +} + +TextureManager::~TextureManager () +{ + if(!_brushesMap.empty()) + _brushesMap.clear(); + _pInstance = 0; +} + +void TextureManager::load() +{ + if(_hasLoadedTextures) + return; + loadStandardBrushes(); + _hasLoadedTextures = true; +} + +unsigned TextureManager::getBrushTextureIndex(string name, Stroke::MediumType loadingMode) +{ + BrushTexture bt(name,loadingMode); + brushesMap::iterator b = _brushesMap.find(bt); + if(b == _brushesMap.end()){ + unsigned texId = loadBrush(name, loadingMode); + _brushesMap[bt] = texId; + return texId; + cout << "brush file " << name << " not found" << endl; + return 0; + }else{ + return _brushesMap[bt]; + } +} + +void TextureManager::Options::setPatternsPath(const string& path) { + _patterns_path = path; +} + +string TextureManager::Options::getPatternsPath() { + return _patterns_path; +} + +void TextureManager::Options::setBrushesPath(const string& path) { + _brushes_path = path; +} + +string TextureManager::Options::getBrushesPath() { + return _brushes_path; +} diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.h b/source/blender/freestyle/intern/stroke/StrokeRenderer.h new file mode 100755 index 00000000000..339e401aa41 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.h @@ -0,0 +1,132 @@ +// +// Filename : StrokeRenderer.h +// Author(s) : Fredo Durand +// Purpose : Classes to render a stroke with OpenGL +// Date of creation : 09/09/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef STROKE_RENDERER_H +# define STROKE_RENDERER_H + +# include <vector> +# include <map> +# include <utility> +# include "../system/FreestyleConfig.h" +# include "Stroke.h" +# include "StrokeRep.h" +# include <string.h> + + +/**********************************/ +/* */ +/* */ +/* TextureManager */ +/* */ +/* */ +/**********************************/ + + +/*! Class to load textures + */ +class LIB_STROKE_EXPORT TextureManager +{ +public: + + TextureManager (); + virtual ~TextureManager (); + static TextureManager * getInstance() {return _pInstance;} + void load () ; + unsigned getBrushTextureIndex(string name, Stroke::MediumType iType = Stroke::OPAQUE_MEDIUM) ; + + inline bool hasLoaded() const {return _hasLoadedTextures;} + inline unsigned int getDefaultTextureId() const {return _defaultTextureId;} + + struct LIB_STROKE_EXPORT Options + { + + static void setPatternsPath(const string& path); + static string getPatternsPath(); + + static void setBrushesPath(const string& path); + static string getBrushesPath(); + }; + + protected: + virtual void loadStandardBrushes() = 0; + virtual unsigned loadBrush(string fileName, Stroke::MediumType = Stroke::OPAQUE_MEDIUM) = 0; + + typedef std::pair<string,Stroke::MediumType> BrushTexture; + struct cmpBrushTexture{ + bool operator()(const BrushTexture& bt1, const BrushTexture& bt2) const{ + int r = strcmp(bt1.first.c_str(), bt2.first.c_str()); + if(r != 0) + return (r<0); + else + return (bt1.second < bt2.second); + } + }; + typedef std::map<BrushTexture, unsigned, cmpBrushTexture> brushesMap; + + static TextureManager * _pInstance; + bool _hasLoadedTextures; + brushesMap _brushesMap; + static string _patterns_path; + static string _brushes_path; + unsigned int _defaultTextureId; +}; + + +/**********************************/ +/* */ +/* */ +/* StrokeRenderer */ +/* */ +/* */ +/**********************************/ + +/*! Class to render a stroke. + Creates a triangle strip and stores it + strip is lazily created at the first rendering +*/ +class LIB_STROKE_EXPORT StrokeRenderer +{ + public: + StrokeRenderer(); + virtual ~StrokeRenderer (); + + /*! Renders a stroke rep */ + virtual void RenderStrokeRep(StrokeRep *iStrokeRep) const = 0; + virtual void RenderStrokeRepBasic(StrokeRep *iStrokeRep) const = 0; + + // initializes the texture manager + // lazy, checks if it has already been done + static bool loadTextures() ; + + //static unsigned int getTextureIndex(unsigned int index) ; + static TextureManager *_textureManager; +}; + + +#endif // STROKE_RENDERER_H diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.cpp b/source/blender/freestyle/intern/stroke/StrokeRep.cpp new file mode 100755 index 00000000000..51a1c8cfd4d --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeRep.cpp @@ -0,0 +1,820 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "StrokeRep.h" +#include "Stroke.h" +#include "StrokeRenderer.h" +#include "StrokeAdvancedIterators.h" +#include "StrokeIterators.h" + +using namespace std; + +// +// STROKE VERTEX REP +///////////////////////////////////// +StrokeVertexRep::StrokeVertexRep(const StrokeVertexRep& iBrother){ + _point2d = iBrother._point2d; + _texCoord = iBrother._texCoord; + _color = iBrother._color; + _alpha = iBrother._alpha; +} + +// +// STRIP +///////////////////////////////////// + +Strip::Strip(const vector<StrokeVertex*>& iStrokeVertices, bool hasTips, bool beginTip, bool endTip){ + createStrip(iStrokeVertices); + if (!hasTips) + computeTexCoord (iStrokeVertices); + else + computeTexCoordWithTips (iStrokeVertices, beginTip, endTip); +} +Strip::Strip(const Strip& iBrother){ + if(!iBrother._vertices.empty()){ + for(vertex_container::const_iterator v=iBrother._vertices.begin(), vend=iBrother._vertices.end(); + v!=vend; + ++v){ + _vertices.push_back(new StrokeVertexRep(**v)); + } + } + _averageThickness = iBrother._averageThickness; +} + +Strip::~Strip(){ + if(!_vertices.empty()){ + for(vertex_container::iterator v=_vertices.begin(), vend=_vertices.end(); + v!=vend; + ++v){ + delete (*v); + } + _vertices.clear(); + } +} + +////////////////////////// +// Strip creation +////////////////////////// +#define EPS_SINGULARITY_RENDERER 0.05 +#define ZERO 0.00001 +#define MAX_RATIO_LENGTH_SINGU 2 +#define HUGE_COORD 1e4 + +bool notValid (Vec2r p) +{ + return (p[0]!=p[0]) || (p[1]!=p[1]) || (fabs(p[0])>HUGE_COORD) || (fabs(p[1])>HUGE_COORD) + || (p[0] <-HUGE_COORD) || (p[1]<-HUGE_COORD); +} + +real crossP(const Vec2r& A, const Vec2r& B){ + return A[0]*B[1] - A[1]*B[0]; +} + +void +Strip::createStrip (const vector<StrokeVertex*>& iStrokeVertices) +{ + //computeParameterization(); + if (iStrokeVertices.size() <2) + { + cerr << "Warning: strip has less than 2 vertices" << endl; + return; + } + _vertices.reserve(2*iStrokeVertices.size()); + if(!_vertices.empty()){ + for(vertex_container::iterator v=_vertices.begin(), vend=_vertices.end(); + v!=vend; + ++v){ + delete (*v); + } + _vertices.clear(); + } + _averageThickness=0.0; + + vector<StrokeVertex*>::const_iterator v ,vend, v2, vPrev; + StrokeVertex *sv, *sv2, *svPrev; + + //special case of first vertex + v=iStrokeVertices.begin(); + sv=*v; + vPrev=v; //in case the stroke has only 2 vertices; + ++v; sv2=*v; + Vec2r dir(sv2->getPoint()-sv->getPoint()); + Vec2r orthDir(-dir[1], dir[0]); + if (orthDir.norm() > ZERO) + orthDir.normalize(); + const float *thickness = sv->attribute().getThickness(); + _vertices.push_back(new StrokeVertexRep(sv->getPoint()+thickness[1]*orthDir)); + _vertices.push_back(new StrokeVertexRep(sv->getPoint()-thickness[0]*orthDir)); + + Vec2r stripDir(orthDir); + // check whether the orientation + // was user defined + if(sv->attribute().isAttributeAvailableVec2f("orientation")){ + Vec2r userDir = sv->attribute().getAttributeVec2f("orientation"); + userDir.normalize(); + Vec2r t(orthDir[1], -orthDir[0]); + real dp1 = userDir*orthDir; + real dp2 = userDir*t; + real h = (thickness[1]+thickness[0])/dp1; + real x = fabs(h*dp2/2.0); + if(dp1>0){ + //i'm in the upper part of the unit circle + if(dp2>0){ + //i'm in the upper-right part of the unit circle + // i must move vertex 1 + _vertices[1]->setPoint2d(_vertices[0]->point2d()-userDir*(h)); + //_vertices[0]->setPoint2d(_vertices[0]->point2d()+t*x); + //_vertices[1]->setPoint2d(_vertices[1]->point2d()-t*x); + }else{ + //i'm in the upper-left part of the unit circle + // i must move vertex 0 + _vertices[0]->setPoint2d(_vertices[1]->point2d()+userDir*(h)); + //_vertices[0]->setPoint2d(_vertices[0]->point2d()-t*x); + //_vertices[1]->setPoint2d(_vertices[1]->point2d()+t*x); + } + }else{ + //i'm in the lower part of the unit circle + if(dp2>0){ + //i'm in the lower-right part of the unit circle + // i must move vertex 0 + //_vertices[0]->setPoint2d(_vertices[1]->point2d()-userDir*(h)); + _vertices[0]->setPoint2d(_vertices[0]->point2d()-t*x); + //_vertices[1]->setPoint2d(_vertices[1]->point2d()+t*x); + }else{ + //i'm in the lower-left part of the unit circle + // i must move vertex 1 + _vertices[1]->setPoint2d(_vertices[0]->point2d()+userDir*(h)); + //_vertices[0]->setPoint2d(_vertices[0]->point2d()-t*x); + //_vertices[1]->setPoint2d(_vertices[1]->point2d()-t*x); + } + } + } + + + // Vec2r userDir = _stroke->getBeginningOrientation(); + // if(userDir != Vec2r(0,0)){ + // userDir.normalize(); + // real o1 = (orthDir*userDir); + // real o2 = crossP(orthDir,userDir); + // real orientation = o1 * o2; + // if(orientation > 0){ + // // then the vertex to move is v0 + // if(o1 > 0) + // _vertex[0]=_vertex[1]+userDir; + // else + // _vertex[0]=_vertex[1]-userDir; + // } + // if(orientation < 0){ + // // then we must move v1 + // if(o1 < 0) + // _vertex[1]=_vertex[0]+userDir; + // else + // _vertex[1]=_vertex[0]-userDir; + // } + // } + + int i=2; //2 because we have already processed the first vertex + + for(vend=iStrokeVertices.end(); + v!=vend; + v++){ + v2=v; ++v2; + if (v2==vend) break; + sv= (*v); sv2 = (*v2); svPrev=(*vPrev); + Vec2r p(sv->getPoint()), p2(sv2->getPoint()), pPrev(svPrev->getPoint()); + + //direction and orthogonal vector to the next segment + Vec2r dir(p2-p); + float dirNorm=dir.norm(); + dir.normalize(); + Vec2r orthDir(-dir[1], dir[0]); + Vec2r stripDir = orthDir; + if(sv->attribute().isAttributeAvailableVec2f("orientation")){ + Vec2r userDir = sv->attribute().getAttributeVec2f("orientation"); + userDir.normalize(); + real dp = userDir*orthDir; + if(dp<0) + userDir = userDir*(-1.f); + stripDir = userDir; + } + + //direction and orthogonal vector to the previous segment + Vec2r dirPrev(p-pPrev); + float dirPrevNorm=dirPrev.norm(); + dirPrev.normalize(); + Vec2r orthDirPrev(-dirPrev[1], dirPrev[0]); + Vec2r stripDirPrev = orthDirPrev; + if(svPrev->attribute().isAttributeAvailableVec2f("orientation")){ + Vec2r userDir = svPrev->attribute().getAttributeVec2f("orientation"); + userDir.normalize(); + real dp = userDir*orthDir; + if(dp<0) + userDir = userDir*(-1.f); + stripDirPrev = userDir; + } + + const float *thickness = sv->attribute().getThickness(); + _averageThickness+=thickness[0]+thickness[1]; + Vec2r pInter; + int interResult; + + interResult=GeomUtils::intersect2dLine2dLine(Vec2r(pPrev+thickness[1]*stripDirPrev), Vec2r(p+thickness[1]*stripDirPrev), + Vec2r(p+thickness[1]*stripDir), Vec2r(p2+thickness[1]*stripDir), + pInter); + + if (interResult==GeomUtils::DO_INTERSECT) + _vertices.push_back(new StrokeVertexRep(pInter)); + else + _vertices.push_back(new StrokeVertexRep(p+thickness[1]*stripDir)); + ++i; + + interResult=GeomUtils::intersect2dLine2dLine(Vec2r(pPrev-thickness[0]*stripDirPrev), Vec2r(p-thickness[0]*stripDirPrev), + Vec2r(p-thickness[0]*stripDir), Vec2r(p2-thickness[0]*stripDir), + pInter); + if (interResult==GeomUtils::DO_INTERSECT) + _vertices.push_back(new StrokeVertexRep(pInter)); + else + _vertices.push_back(new StrokeVertexRep(p-thickness[0]*stripDir)); + ++i; + + // if the angle is obtuse, we simply average the directions to avoid the singularity + stripDir=stripDir+stripDirPrev; + if ((dirNorm<ZERO) || (dirPrevNorm<ZERO) || (stripDir.norm() < ZERO)) { + stripDir[0] = 0; + stripDir[1] = 0; + }else + stripDir.normalize(); + + Vec2r vec_tmp(_vertices[i-2]->point2d()-p); + if ((vec_tmp.norm() > thickness[1]*MAX_RATIO_LENGTH_SINGU) || + (dirNorm<ZERO) || (dirPrevNorm<ZERO) || + notValid(_vertices[i-2]->point2d()) + || (fabs(stripDir * dir) < EPS_SINGULARITY_RENDERER)) + _vertices[i-2]->setPoint2d(p+thickness[1]*stripDir); + + vec_tmp = _vertices[i-1]->point2d()-p; + if ((vec_tmp.norm() > thickness[1]*MAX_RATIO_LENGTH_SINGU) || + (dirNorm<ZERO) || (dirPrevNorm<ZERO) || + notValid(_vertices[i-1]->point2d()) + || (fabs(stripDir * dir)<EPS_SINGULARITY_RENDERER)) + _vertices[i-1]->setPoint2d(p-thickness[0]*stripDir); + + vPrev=v; + } // end of for + + //special case of last vertex + sv=*v; + sv2=*vPrev; + dir=Vec2r (sv->getPoint()-sv2->getPoint()); + orthDir=Vec2r(-dir[1], dir[0]); + if (orthDir.norm() > ZERO) + orthDir.normalize(); + const float *thicknessLast = sv->attribute().getThickness(); + _vertices.push_back(new StrokeVertexRep(sv->getPoint()+thicknessLast[1]*orthDir)); + ++i; + _vertices.push_back(new StrokeVertexRep(sv->getPoint()-thicknessLast[0]*orthDir)); + int n = i; + ++i; + + // check whether the orientation + // was user defined + if(sv->attribute().isAttributeAvailableVec2f("orientation")){ + Vec2r userDir = sv->attribute().getAttributeVec2f("orientation"); + userDir.normalize(); + Vec2r t(orthDir[1], -orthDir[0]); + real dp1 = userDir*orthDir; + real dp2 = userDir*t; + real h = (thicknessLast[1]+thicknessLast[0])/dp1; + //soc unused - real x = fabs(h*dp2/2.0); + if(dp1>0){ + //i'm in the upper part of the unit circle + if(dp2>0){ + //i'm in the upper-right part of the unit circle + // i must move vertex n-1 + _vertices[n-1]->setPoint2d(_vertices[n]->point2d()-userDir*(h)); + //_vertices[n-1]->setPoint2d(_vertices[n-1]->point2d()+t*x); + //_vertices[n]->setPoint2d(_vertices[n]->point2d()-t*x); + }else{ + //i'm in the upper-left part of the unit circle + // i must move vertex n + _vertices[n]->setPoint2d(_vertices[n-1]->point2d()+userDir*(h)); + //_vertices[n-1]->setPoint2d(_vertices[n-1]->point2d()-t*x); + //_vertices[n]->setPoint2d(_vertices[n]->point2d()+t*x); + } + }else{ + //i'm in the lower part of the unit circle + if(dp2>0){ + //i'm in the lower-right part of the unit circle + // i must move vertex n + _vertices[n]->setPoint2d(_vertices[n-1]->point2d()-userDir*(h)); + //_vertices[n-1]->setPoint2d(_vertices[n-1]->point2d()-t*x); + //_vertices[n]->setPoint2d(_vertices[n]->point2d()+t*x); + }else{ + //i'm in the lower-left part of the unit circle + // i must move vertex n-1 + _vertices[n-1]->setPoint2d(_vertices[n]->point2d()+userDir*(h)); + //_vertices[n-1]->setPoint2d(_vertices[n-1]->point2d()+t*x); + //_vertices[n]->setPoint2d(_vertices[n]->point2d()-t*x); + } + } + } + + + // check whether the orientation of the extremity + // was user defined + // userDir = _stroke->getEndingOrientation(); + // if(userDir != Vec2r(0,0)){ + // userDir.normalize(); + // real o1 = (orthDir*userDir); + // real o2 = crossP(orthDir,userDir); + // real orientation = o1 * o2; + // if(orientation > 0){ + // // then the vertex to move is vn + // if(o1 < 0) + // _vertex[n]=_vertex[n-1]+userDir; + // else + // _vertex[n]=_vertex[n-1]-userDir; + // } + // if(orientation < 0){ + // // then we must move vn-1 + // if(o1 > 0) + // _vertex[n-1]=_vertex[n]+userDir; + // else + // _vertex[n-1]=_vertex[n]-userDir; + // } + // } + + _averageThickness/=float(iStrokeVertices.size()-2); + //I did not use the first and last vertex for the average + if (iStrokeVertices.size()<3) + _averageThickness=0.5*(thicknessLast[1]+thicknessLast[0]+thickness[0]+thickness[1]); + + if (i != 2*(int)iStrokeVertices.size()) + cerr << "Warning: problem with stripe size\n"; + + cleanUpSingularities (iStrokeVertices); +} + +// CLEAN UP +///////////////////////// + +void +Strip::cleanUpSingularities (const vector<StrokeVertex*>& iStrokeVertices) +{ + int k; + int sizeStrip = _vertices.size(); + + for (k=0; k<sizeStrip; k++) + if (notValid(_vertices[k]->point2d())) + { + cerr << "Warning: strip vertex " << k << " non valid" << endl; + return; + } + + //return; + if (iStrokeVertices.size()<2) return; + int i=0, j; + vector<StrokeVertex*>::const_iterator v ,vend, v2, vPrev; +StrokeVertex *sv, *sv2; //soc unused - *svPrev; + + bool singu1=false, singu2=false; + int timeSinceSingu1=0, timeSinceSingu2=0; + + //special case of first vertex + v=iStrokeVertices.begin(); + for(vend=iStrokeVertices.end(); + v!=vend; + v++) + { + v2=v; ++v2; + if (v2==vend) break; + sv= (*v); sv2 = (*v2); + Vec2r p(sv->getPoint()), p2(sv2->getPoint()); + + Vec2r dir(p2-p); + if (dir.norm() > ZERO) + dir.normalize(); + Vec2r dir1, dir2; + dir1=_vertices[2*i+2]->point2d()-_vertices[2*i]->point2d(); + dir2=_vertices[2*i+3]->point2d()-_vertices[2*i+1]->point2d(); + + if ((dir1 * dir) < -ZERO) + { + singu1=true; + timeSinceSingu1++; + } + else + { + if (singu1) + { + int toto=i-timeSinceSingu1; + if (toto<0) + cerr << "Stephane dit \"Toto\"" << endl; + //traverse all the vertices of the singularity and average them + Vec2r avP(0.0,0.0); + for (j=i-timeSinceSingu1; j<i+1; j++) + avP=Vec2r(avP+_vertices[2*j]->point2d()); + avP=Vec2r(1.0/float(timeSinceSingu1+1)*avP); + for (j=i-timeSinceSingu1; j<i+1; j++) + _vertices[2*j]->setPoint2d(avP); + //_vertex[2*j]=_vertex[2*i]; + singu1=false; timeSinceSingu1=0; + } + } + if ((dir2 * dir) < -ZERO) + { + singu2=true; + timeSinceSingu2++; + } + else + { + if (singu2) + { + int toto=i-timeSinceSingu2; + if (toto<0) + cerr << "Stephane dit \"Toto\"" << endl; + //traverse all the vertices of the singularity and average them + Vec2r avP(0.0,0.0); + for (j=i-timeSinceSingu2; j<i+1; j++) + avP=Vec2r(avP+_vertices[2*j+1]->point2d()); + avP=Vec2r(1.0/float(timeSinceSingu2+1)*avP); + for (j=i-timeSinceSingu2; j<i+1; j++) + _vertices[2*j+1]->setPoint2d(avP); + //_vertex[2*j+1]=_vertex[2*i+1]; + singu2=false; timeSinceSingu2=0; + } + } + i++; + } + + if (singu1) + { + //traverse all the vertices of the singularity and average them + Vec2r avP(0.0,0.0); + for (j=i-timeSinceSingu1; j<i; j++) + avP=Vec2r(avP+_vertices[2*j]->point2d()); + avP=Vec2r(1.0/float(timeSinceSingu1)*avP); + for (j=i-timeSinceSingu1; j<i; j++) + _vertices[2*j]->setPoint2d(avP); + } + if (singu2) + { + //traverse all the vertices of the singularity and average them + Vec2r avP(0.0,0.0); + for (j=i-timeSinceSingu2; j<i; j++) + avP=Vec2r(avP+_vertices[2*j+1]->point2d()); + avP=Vec2r(1.0/float(timeSinceSingu2)*avP); + for (j=i-timeSinceSingu2; j<i; j++) + _vertices[2*j+1]->setPoint2d(avP); + } + + + for (k=0; k<sizeStrip; k++) + if (notValid(_vertices[k]->point2d())) + { + cerr << "Warning: strip vertex " << k << " non valid after cleanup"<<endl; + return; + } +} + + +// Texture coordinates +//////////////////////////////// + +void +Strip::computeTexCoord (const vector<StrokeVertex*>& iStrokeVertices) +{ + vector<StrokeVertex*>::const_iterator v ,vend; + StrokeVertex *sv; + int i=0; + for(v=iStrokeVertices.begin(), vend=iStrokeVertices.end(); + v!=vend; v++) + { + sv= (*v); + _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / _averageThickness),0)); + _vertices[i]->setColor(Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2])); + _vertices[i]->setAlpha(sv->attribute().getAlpha()); + i++; + _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / _averageThickness),1)); + _vertices[i]->setColor(Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2])); + _vertices[i]->setAlpha(sv->attribute().getAlpha()); + i++; + // cerr<<"col=("<<sv->attribute().getColor()[0]<<", " + // <<sv->attribute().getColor()[1]<<", "<<sv->attribute().getColor()[2]<<")"<<endl; + } +} + +void +Strip::computeTexCoordWithTips (const vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd) +{ + //soc unused - unsigned int sizeStrip = _vertices.size()+8; //for the transition between the tip and the body + vector<StrokeVertex*>::const_iterator v ,vend; + StrokeVertex *sv = 0; + + v=iStrokeVertices.begin(); + vend=iStrokeVertices.end(); + float l=(*v)->strokeLength()/_averageThickness; + int tiles=int(l); + float fact=(float(tiles)+0.5)/l; + //soc unused - float uTip2=float(tiles)+0.25; + float u=0; + float uPrev=0; + int i=0; + float t; + StrokeVertexRep *tvRep1, *tvRep2; + + // cerr<<"l="<<l<<" tiles="<<tiles<<" _averageThicnkess=" + // <<_averageThickness<<" strokeLength="<<(*v)->strokeLength()<<endl; + // + vector<StrokeVertexRep*>::iterator currentSV = _vertices.begin(); + StrokeVertexRep *svRep; + if(tipBegin){ + for(;v!=vend; v++) + { + sv= (*v); + svRep = *currentSV; + u=sv->curvilinearAbscissa()/_averageThickness*fact; + if (u>0.25) break; + + + svRep->setTexCoord(Vec2r((real)u, 0.5)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + + svRep = *currentSV; + svRep->setTexCoord(Vec2r((real)u, 1)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + uPrev=u; + } + //first transition vertex + + if (fabs(u-uPrev)>ZERO) + t= (0.25-uPrev)/(u-uPrev); + else t=0; + //if (!tiles) t=0.5; + tvRep1 = new StrokeVertexRep(Vec2r((1-t)*_vertices[i-2]->point2d()+t*_vertices[i]->point2d())); + tvRep1->setTexCoord(Vec2r(0.25,0.5)); + tvRep1->setColor(Vec3r((1-t)*_vertices[i-2]->color()+ + t*Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2]))); + tvRep1->setAlpha((1-t)*_vertices[i-2]->alpha()+t*sv->attribute().getAlpha()); + i++; + + tvRep2 = new StrokeVertexRep(Vec2r((1-t)*_vertices[i-2]->point2d()+t*_vertices[i]->point2d())); + tvRep2->setTexCoord(Vec2r(0.25,1)); + tvRep2->setColor(Vec3r((1-t)*_vertices[i-2]->color()+ + t*Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2]))); + tvRep2->setAlpha((1-t)*_vertices[i-2]->alpha()+t*sv->attribute().getAlpha()); + i++; + + currentSV = _vertices.insert(currentSV, tvRep1); + ++currentSV; + currentSV = _vertices.insert(currentSV, tvRep2); + ++currentSV; + + //copy the vertices with different texture coordinates + tvRep1 = new StrokeVertexRep(_vertices[i-2]->point2d()); + tvRep1->setTexCoord(Vec2r(0.25,0)); + tvRep1->setColor(_vertices[i-2]->color()); + tvRep1->setAlpha(_vertices[i-2]->alpha()); + i++; + + tvRep2 = new StrokeVertexRep(_vertices[i-2]->point2d()); + tvRep2->setTexCoord(Vec2r(0.25,0.5)); + tvRep2->setColor(_vertices[i-2]->color()); + tvRep2->setAlpha(_vertices[i-2]->alpha()); + i++; + + currentSV = _vertices.insert(currentSV, tvRep1); + ++currentSV; + currentSV = _vertices.insert(currentSV, tvRep2); + ++currentSV; + } + uPrev=0; + + //body of the stroke + for(;v!=vend; v++) + { + sv= (*v); + svRep = *currentSV; + u=sv->curvilinearAbscissa()/_averageThickness*fact-0.25; + if (u>tiles) break; + + svRep->setTexCoord(Vec2r((real)u, 0)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + + svRep = *currentSV; + svRep->setTexCoord(Vec2r((real)u, 0.5)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + + uPrev=u; + } + if(tipEnd){ + //second transition vertex + if ((fabs(u-uPrev)>ZERO)) + t= (float(tiles)-uPrev)/(u-uPrev); + else t=0; + + tvRep1 = new StrokeVertexRep(Vec2r((1-t)*_vertices[i-2]->point2d()+t*_vertices[i]->point2d())); + tvRep1->setTexCoord(Vec2r((real)tiles,0)); + tvRep1->setColor(Vec3r((1-t)*_vertices[i-2]->color()+ + t*Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2]))); + tvRep1->setAlpha((1-t)*_vertices[i-2]->alpha()+t*sv->attribute().getAlpha()); + i++; + + tvRep2 = new StrokeVertexRep(Vec2r((1-t)*_vertices[i-2]->point2d()+t*_vertices[i]->point2d())); + tvRep2->setTexCoord(Vec2r((real)tiles,0.5)); + tvRep2->setColor(Vec3r((1-t)*_vertices[i-2]->color()+ + t*Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2]))); + tvRep2->setAlpha((1-t)*_vertices[i-2]->alpha()+t*sv->attribute().getAlpha()); + i++; + + currentSV = _vertices.insert(currentSV, tvRep1); + ++currentSV; + currentSV = _vertices.insert(currentSV, tvRep2); + ++currentSV; + + //copy the vertices with different texture coordinates + tvRep1 = new StrokeVertexRep(_vertices[i-2]->point2d()); + tvRep1->setTexCoord(Vec2r(0.75,0.5)); + tvRep1->setColor(_vertices[i-2]->color()); + tvRep1->setAlpha(_vertices[i-2]->alpha()); + i++; + + tvRep2 = new StrokeVertexRep(_vertices[i-2]->point2d()); + tvRep2->setTexCoord(Vec2r(0.75,1)); + tvRep2->setColor(_vertices[i-2]->color()); + tvRep2->setAlpha(_vertices[i-2]->alpha()); + i++; + + currentSV = _vertices.insert(currentSV, tvRep1); + ++currentSV; + currentSV = _vertices.insert(currentSV, tvRep2); + ++currentSV; + + //end tip + for(;v!=vend; v++) + { + sv= (*v); + svRep = *currentSV; + u=0.75+sv->curvilinearAbscissa()/_averageThickness*fact-float(tiles)-0.25; + + svRep->setTexCoord(Vec2r((real)u, 0.5)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + + svRep = *currentSV; + svRep->setTexCoord(Vec2r((real)u, 1)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + } + } + //cerr<<"u="<<u<<" i="<<i<<"/"<<_sizeStrip<<endl;; + + // for (i=0; i<_sizeStrip; i++) + // _alpha[i]=1.0; + + // for (i=0; i<_sizeStrip; i++) + // cerr<<"("<<_texCoord[i][0]<<", "<<_texCoord[i][1]<<") "; + // cerr<<endl; + + + // Vec2r vec_tmp; + // for (i=0; i<_sizeStrip/2; i++) + // vec_tmp = _vertex[2*i] - _vertex[2*i+1]; + // if (vec_tmp.norm() > 4*_averageThickness) + // cerr << "Warning (from Fredo): There is a pb in the texture coordinates computation" << endl; +} + +// +// StrokeRep +///////////////////////////////////// + +StrokeRep::StrokeRep() +{ + _stroke = 0; + _strokeType=Stroke::OPAQUE_MEDIUM; + TextureManager * ptm = TextureManager::getInstance(); + if(ptm) + _textureId = ptm->getDefaultTextureId(); + // _averageTextureAlpha=0.5; //default value + // if (_strokeType==OIL_STROKE) + // _averageTextureAlpha=0.75; + // if (_strokeType>=NO_BLEND_STROKE) + // _averageTextureAlpha=1.0 +} + +StrokeRep::StrokeRep(Stroke *iStroke) +{ + _stroke = iStroke; + _strokeType = iStroke->getMediumType(); + _textureId = iStroke->getTextureId(); + if(_textureId == 0){ + TextureManager * ptm = TextureManager::getInstance(); + if(ptm) + _textureId = ptm->getDefaultTextureId(); + } + + // _averageTextureAlpha=0.5; //default value + // if (_strokeType==OIL_STROKE) + // _averageTextureAlpha=0.75; + // if (_strokeType>=NO_BLEND_STROKE) + // _averageTextureAlpha=1.0; + create(); +} + +StrokeRep::StrokeRep(const StrokeRep& iBrother) +{ + //soc unused - int i=0; + _stroke = iBrother._stroke; + _strokeType=iBrother._strokeType; + _textureId = iBrother._textureId; + for(vector<Strip*>::const_iterator s=iBrother._strips.begin(), send=iBrother._strips.end(); + s!=send; + ++s){ + _strips.push_back(new Strip(**s)); + } +} + + +StrokeRep::~StrokeRep() +{ + if(!_strips.empty()){ + for(vector<Strip*>::iterator s=_strips.begin(), send=_strips.end(); + s!=send; + ++s){ + delete (*s); + } + _strips.clear(); + } +} + +void StrokeRep::create(){ + vector<StrokeVertex*> strip; + StrokeInternal::StrokeVertexIterator v = _stroke->strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator vend = _stroke->strokeVerticesEnd(); + + bool first=true; + bool end=false; + while(v!=vend){ + while((v!=vend) && (!(*v).attribute().isVisible())){ + ++v; + first = false; + } + while( (v!=vend) && ((*v).attribute().isVisible()) ) { + strip.push_back(&(*v)); + ++v; + } + if(v!=vend){ + // add the last vertex and create + strip.push_back(&(*v)); + }else{ + end=true; + } + if((!strip.empty()) && (strip.size()>1) ){ + _strips.push_back(new Strip(strip, _stroke->hasTips(), first, end)); + strip.clear(); + } + first = false; + } +} + +void StrokeRep::Render(const StrokeRenderer *iRenderer) +{ + iRenderer->RenderStrokeRep(this); +} + + + diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.h b/source/blender/freestyle/intern/stroke/StrokeRep.h new file mode 100755 index 00000000000..d8a8dc2d609 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeRep.h @@ -0,0 +1,138 @@ +// +// Filename : StrokeRep.h +// Author(s) : Stephane Grabli +// Purpose : Class to define the representation of a stroke +// (for display purpose) +// Date of creation : 05/03/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef STROKEREP_H +# define STROKEREP_H + +# include "../geometry/Geom.h" +using namespace Geometry; + +//symbolic constant to call the appropriate renderers and textures +// # define NO_TEXTURE_WITH_BLEND_STROKE -2 +// # define NO_TEXTURE_STROKE -1 +// # define PSEUDO_CHARCOAL_STROKE 0 +// # define WASH_BRUSH_STROKE 1 +// # define OIL_STROKE 2 +// # define NO_BLEND_STROKE 3 +// # define CHARCOAL_MIN_STROKE 4 +// # define BRUSH_MIN_STROKE 5 +// # define OPAQUE_DRY_STROKE 6 +// # define OPAQUE_STROKE 7 +// +// # define DEFAULT_STROKE 0 +// +// # define NUMBER_STROKE_RENDERER 8 + +#include "Stroke.h" + +class StrokeVertexRep{ +public: + StrokeVertexRep(){} + StrokeVertexRep(const Vec2r& iPoint2d){_point2d=iPoint2d;} + StrokeVertexRep(const StrokeVertexRep& iBrother); + virtual ~StrokeVertexRep(){} + + inline Vec2r& point2d() {return _point2d;} + inline Vec2r& texCoord() {return _texCoord;} + inline Vec3r& color() {return _color;} + inline float alpha() {return _alpha;} + + inline void setPoint2d(const Vec2r& p){_point2d = p;} + inline void setTexCoord(const Vec2r& p){_texCoord = p;} + inline void setColor(const Vec3r& p){_color = p;} + inline void setAlpha(float a){_alpha = a;} +protected: + Vec2r _point2d; + Vec2r _texCoord; + Vec3r _color; + float _alpha; +}; + +class Strip{ +public: + typedef std::vector<StrokeVertexRep*> vertex_container; +protected: + vertex_container _vertices; + float _averageThickness; + + +public: + Strip(const std::vector<StrokeVertex*>& iStrokeVertices, bool hasTips=false, bool tipBegin=false, bool tipEnd=false) ; + Strip(const Strip& iBrother); + virtual ~Strip() ; + +protected: + void createStrip(const std::vector<StrokeVertex*>& iStrokeVertices); + void cleanUpSingularities(const std::vector<StrokeVertex*>& iStrokeVertices); + void computeTexCoord (const std::vector<StrokeVertex*>& iStrokeVertices); + void computeTexCoordWithTips (const std::vector<StrokeVertex*>& iStrokeVertices, bool tipBegin, bool tipEnd); +public: + inline int sizeStrip() const {return _vertices.size();} + inline vertex_container& vertices() {return _vertices;} +}; + +class StrokeRep +{ +protected: + Stroke *_stroke; + vector<Strip*> _strips; + Stroke::MediumType _strokeType; + unsigned int _textureId; + + // float _averageTextureAlpha; + + +public: + StrokeRep(); + StrokeRep(const StrokeRep&); + StrokeRep(Stroke *iStroke); + virtual ~StrokeRep(); + + /*! Creates the strips */ + virtual void create() ; + + /*! Renders the stroke using a Renderer */ + virtual void Render(const StrokeRenderer *iRenderer) ; + + /*! accessors */ + inline Stroke::MediumType getMediumType() const {return _strokeType;} + inline unsigned getTextureId() const {return _textureId;} + inline vector<Strip*>& getStrips() {return _strips;} + inline unsigned int getNumberOfStrips() const {return _strips.size();} + inline Stroke * getStroke() {return _stroke;} + + /*! modifiers */ + inline void setMediumType(Stroke::MediumType itype) {_strokeType=itype;} + inline void setTextureId(unsigned textureId) {_textureId = textureId;} + + +}; + +#endif // STROKEREP_H diff --git a/source/blender/freestyle/intern/stroke/StrokeShader.h b/source/blender/freestyle/intern/stroke/StrokeShader.h new file mode 100755 index 00000000000..63185438e91 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeShader.h @@ -0,0 +1,124 @@ +// +// Filename : StrokeShader.h +// Author(s) : Stephane Grabli, Emmanuel Turquin +// Purpose : Class defining StrokeShader +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef SHADERS_H +# define SHADERS_H + +# include <iostream> +# include <vector> + +# include "../python/Director.h" + +// +// StrokeShader base class +// +////////////////////////////////////////////////////// + +class Stroke; +/*! Base class for Stroke Shaders. + * Any Stroke Shader must inherit from + * this class and overload the shade() method. + * A StrokeShader is designed to modify any + * Stroke's attribute such as Thickness, Color, + * Geometry, Texture, Blending mode... + * The basic way to achieve this operation consists + * in iterating over the StrokeVertices of the Stroke + * and to modify each one's StrokeAttribute. + * Here is a python code example of such an iteration: + * \code + * it = ioStroke.strokeVerticesBegin() + * while it.isEnd() == 0: + * att = it.getObject().attribute() + * ## perform here any attribute modification + * it.increment() + * \endcode + * Here is a C++ code example of such an iteration: + * \code + * for(StrokeInternal::StrokeVertexIterator v=ioStroke.strokeVerticesBegin(), vend=ioStroke.strokeVerticesEnd(); + * v!=vend; + * ++v){ + * StrokeAttribute& att = v->attribute(); + * // perform any attribute modification here... + * } + * \endcode + */ +class LIB_STROKE_EXPORT StrokeShader +{ +public: + + PyObject *py_ss; + + /*! Default constructor. */ + StrokeShader() { py_ss = 0; } + /*! Destructor. */ + virtual ~StrokeShader() {} + /*! Returns the string corresponding to the + * shader's name. + */ + virtual string getName() const { + return "StrokeShader"; + } + /*! The shading method. This method must + * be overloaded by inherited classes. + * The shading method is designed to modify any + * Stroke's attribute such as Thickness, Color, + * Geometry, Texture, Blending mode... + * The basic way to achieve this operation consists + * in iterating over the StrokeVertices of the Stroke + * and to modify each one's StrokeAttribute. + * Here is a python code example of such an iteration: + * \code + * it = ioStroke.strokeVerticesBegin() + * while it.isEnd() == 0: + * att = it.getObject().attribute() + * ## perform here any attribute modification + * it.increment() + * \endcode + * Here is a C++ code example of such an iteration: + * \code + * for(StrokeInternal::StrokeVertexIterator v=ioStroke.strokeVerticesBegin(), vend=ioStroke.strokeVerticesEnd(); + * v!=vend; + * ++v){ + * StrokeAttribute& att = v->attribute(); + * // perform any attribute modification here... + * } + * \endcode + * \param ioStroke + * The stroke we wish to shade. this Stroke + * is modified by the Shader (which typically + * modifies the Stroke's attribute's values such + * as Color, Thickness, Geometry...) + */ + virtual int shade(Stroke& ioStroke) const { + return Director_BPy_StrokeShader_shade( const_cast<StrokeShader *>(this), ioStroke ); + } + +}; + +# endif // SHADERS_H diff --git a/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp b/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp new file mode 100755 index 00000000000..465e5662774 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp @@ -0,0 +1,88 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "../scene_graph/OrientedLineRep.h" +#include "../scene_graph/NodeGroup.h" +#include "../scene_graph/NodeShape.h" +#include "StrokeTesselator.h" +#include "StrokeAdvancedIterators.h" + +LineRep* StrokeTesselator::Tesselate(Stroke *iStroke) +{ + if(0 == iStroke) + return 0; + + LineRep* line; + line = new OrientedLineRep(); + + Stroke::vertex_iterator v,vend; + if(2 == iStroke->vertices_size()) + { + line->setStyle(LineRep::LINES); + v = iStroke->vertices_begin(); + StrokeVertex *svA= (*v); + v++; + StrokeVertex *svB = (*v); + Vec3r A((*svA)[0], (*svA)[1], 0); + Vec3r B((*svB)[0], (*svB)[1], 0); + line->AddVertex(A); + line->AddVertex(B); + } + else + { + if(_overloadFrsMaterial) + line->setFrsMaterial(_FrsMaterial); + + line->setStyle(LineRep::LINE_STRIP); + + for(v=iStroke->vertices_begin(), vend=iStroke->vertices_end(); + v!=vend; + v++) + { + StrokeVertex *sv= (*v); + Vec3r V((*sv)[0], (*sv)[1], 0); + line->AddVertex(V); + } + } + line->setId(iStroke->getId()); + line->ComputeBBox(); + + return line; +} + +template<class StrokeVertexIterator> +NodeGroup* StrokeTesselator::Tesselate(StrokeVertexIterator begin, StrokeVertexIterator end) +{ + NodeGroup *group = new NodeGroup; + NodeShape *tshape = new NodeShape; + group->AddChild(tshape); + //tshape->material().setDiffuse(0.f, 0.f, 0.f, 1.f); + tshape->setFrsMaterial(_FrsMaterial); + + for(StrokeVertexIterator c=begin, cend=end; + c!=cend; + c++) + { + tshape->AddRep(Tesselate((*c))); + } + + return group; +} diff --git a/source/blender/freestyle/intern/stroke/StrokeTesselator.h b/source/blender/freestyle/intern/stroke/StrokeTesselator.h new file mode 100755 index 00000000000..1de281734cd --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StrokeTesselator.h @@ -0,0 +1,67 @@ +// +// Filename : StrokeTesselator.h +// Author(s) : Stephane Grabli +// Purpose : Class to build a Node Tree designed to be displayed +// from a set of strokes structure. +// Date of creation : 26/03/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef STROKETESSELATOR_H +# define STROKETESSELATOR_H + +# include "../scene_graph/LineRep.h" +# include "Stroke.h" + +class StrokeTesselator +{ +public: + + inline StrokeTesselator() {_FrsMaterial.setDiffuse(0,0,0,1);_overloadFrsMaterial=false;} + virtual ~StrokeTesselator() {} + + /*! Builds a line rep contained from a Stroke + */ + LineRep* Tesselate(Stroke* iStroke) ; + + /*! Builds a set of lines rep contained under a + * a NodeShape, itself contained under a NodeGroup from a + * set of strokes + */ + template<class StrokeIterator> + NodeGroup* Tesselate(StrokeIterator begin, StrokeIterator end) ; + + + + inline void setFrsMaterial(const FrsMaterial& iMaterial) {_FrsMaterial=iMaterial;_overloadFrsMaterial=true;} + inline const FrsMaterial& frs_material() const {return _FrsMaterial;} + +private: + + FrsMaterial _FrsMaterial; + bool _overloadFrsMaterial; +}; + +#endif // STROKETESSELATOR_H + diff --git a/source/blender/freestyle/intern/stroke/StyleModule.h b/source/blender/freestyle/intern/stroke/StyleModule.h new file mode 100755 index 00000000000..c023ad7517b --- /dev/null +++ b/source/blender/freestyle/intern/stroke/StyleModule.h @@ -0,0 +1,157 @@ +// +// Filename : StyleModule.h +// Author(s) : Stephane Grabli, Emmanuel Turquin +// Purpose : Class representing a style module +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef STYLE_MODULE_H +# define STYLE_MODULE_H + +# include <iostream> +# include <string> +# include "../system/StringUtils.h" +# include "StrokeLayer.h" +# include "../system/Interpreter.h" +# include "Operators.h" +# include "StrokeShader.h" + +using namespace std; + +class StyleModule +{ +public: + + StyleModule(const string& file_name, + Interpreter* inter) : _file_name(file_name) { + _always_refresh = false; + _causal = false; + _drawable = true; + _modified = true; + _displayed = true; + _inter = inter; + } + + ~StyleModule() {} + + StrokeLayer* execute() { + if (!_inter) { + cerr << "Error: no interpreter was found to execute the script" << endl; + return NULL; + } + + if (!_drawable) { + cerr << "Error: not drawable" << endl; + return NULL; + } + + Operators::reset(); + + if( _inter->interpretFile(_file_name) ) { + cerr << "Error: interpretation failed" << endl; + return NULL; + } + + Operators::StrokesContainer* strokes_set = Operators::getStrokesSet(); + if( strokes_set->empty() ) { + cerr << "Error: strokes set empty" << endl; + return NULL; + } + + StrokeLayer* sl = new StrokeLayer; + for (Operators::StrokesContainer::iterator it = strokes_set->begin(); + it != strokes_set->end(); + ++it) + sl->AddStroke(*it); + + return sl; + } + + // accessors + + const string getFileName() const { + return _file_name; + } + + bool getAlwaysRefresh() const { + return _always_refresh; + } + + bool getCausal() const { + return _causal; + } + + bool getDrawable() const { + return _drawable; + } + + bool getModified() const { + return _modified; + } + + bool getDisplayed() const { + return _displayed; + } + + // modifiers + + void setFileName(const string& file_name) { + _file_name = file_name; + } + + void setAlwaysRefresh(bool b = true) { + _always_refresh = b; + } + + void setCausal(bool b = true) { + _causal = b; + } + + void setDrawable(bool b = true) { + _drawable = b; + } + + void setModified(bool b = true) { + if (_always_refresh) + return; + _modified = b; + } + + void setDisplayed(bool b = true) { + _displayed = b; + } + +private: + + string _file_name; + bool _always_refresh; + bool _causal; + bool _drawable; + bool _modified; + bool _displayed; + Interpreter* _inter; +}; + +#endif // STYLE_MODULE_H diff --git a/source/blender/freestyle/intern/stroke/TextStrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/TextStrokeRenderer.cpp new file mode 100755 index 00000000000..ea5af287bbe --- /dev/null +++ b/source/blender/freestyle/intern/stroke/TextStrokeRenderer.cpp @@ -0,0 +1,73 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +# include "TextStrokeRenderer.h" +# include "Canvas.h" +# include "StrokeIterators.h" + +TextStrokeRenderer::TextStrokeRenderer(const char* iFileName) +:StrokeRenderer(){ + if(!iFileName) + iFileName = "freestyle.txt"; + // open the stream: + _ofstream.open(iFileName, ios::out); + if(!_ofstream.is_open()){ + cerr << "couldn't open the output file " << iFileName << endl; + } + _ofstream << "%!FREESTYLE" << endl; + _ofstream << "%Creator: Freestyle (http://artis.imag.fr/Software/Freestyle)" << endl; + // Bounding box + _ofstream << 0 << " "<< 0 << " " << Canvas::getInstance()->width() << " " << Canvas::getInstance()->height() << endl; + _ofstream << "%u x y z tleft tright r g b ..." << endl; +} + +TextStrokeRenderer::~TextStrokeRenderer(){ + Close(); +} + +void TextStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const{ + RenderStrokeRepBasic(iStrokeRep); +} + +void TextStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const{ + Stroke *stroke = iStrokeRep->getStroke(); + if(!stroke){ + cerr << "no stroke associated with Rep" << endl; + return; + } + + StrokeInternal::StrokeVertexIterator v = stroke->strokeVerticesBegin(); + StrokeAttribute att; + while(!v.isEnd()){ + att = v->attribute(); + _ofstream << v->u() << " " << v->getProjectedX() << " " << v->getProjectedY() << " " << v->getProjectedZ() << " " \ + << att.getThicknessL() << " " << att.getThicknessR() << " " \ + << att.getColorR() << " " << att.getColorG() << " " << att.getColorB() << " "; + ++v; + } + _ofstream << endl; +} + +void TextStrokeRenderer::Close(){ + if(_ofstream.is_open()) + _ofstream.close(); +} + diff --git a/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h b/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h new file mode 100755 index 00000000000..ef610d63bdd --- /dev/null +++ b/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h @@ -0,0 +1,68 @@ +// +// Filename : TextStrokeRenderer.h +// Author(s) : Stephane Grabli +// Purpose : Class to define the text rendering of a stroke +// Format: +// x y width height // bbox +// //list of vertices : +// t x y z t1 t2 r g b alpha ... +// ... +// Date of creation : 01/14/2005 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef TEXTSTROKERENDERER_H +# define TEXTSTROKERENDERER_H + +# include "../system/FreestyleConfig.h" +# include "StrokeRenderer.h" +# include <fstream> + +/**********************************/ +/* */ +/* */ +/* TextStrokeRenderer */ +/* */ +/* */ +/**********************************/ + +class LIB_STROKE_EXPORT TextStrokeRenderer : public StrokeRenderer +{ +public: + TextStrokeRenderer(const char * iFileName = 0); + virtual ~TextStrokeRenderer(); + + /*! Renders a stroke rep */ + virtual void RenderStrokeRep(StrokeRep *iStrokeRep) const; + virtual void RenderStrokeRepBasic(StrokeRep *iStrokeRep) const; + + /*! Closes the output file */ + void Close(); + +protected: + mutable ofstream _ofstream; +}; + +#endif // TEXTSTROKERENDERER_H + diff --git a/source/blender/freestyle/intern/system/BaseIterator.h b/source/blender/freestyle/intern/system/BaseIterator.h new file mode 100755 index 00000000000..45cc19df4fe --- /dev/null +++ b/source/blender/freestyle/intern/system/BaseIterator.h @@ -0,0 +1,90 @@ +// +// Filename : BaseIterator.h +// Author(s) : Stephane Grabli +// Purpose : Classes defining the basic "Iterator" design pattern +// Date of creation : 18/03/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BASEITERATOR_H +# define BASEITERATOR_H + +# include <iterator> + +// use for iterators defintions +template <class Element> +class Nonconst_traits; + +template <class Element> +class Const_traits { +public: + typedef Element value_type; + typedef const Element& reference; + typedef const Element* pointer; + typedef ptrdiff_t difference_type; + typedef Nonconst_traits<Element> Non_const_traits; +}; + +template <class Element> +class Nonconst_traits { +public: + typedef Element value_type; + typedef Element& reference; + typedef Element* pointer; + typedef ptrdiff_t difference_type; + typedef Nonconst_traits<Element> Non_const_traits; +}; + +class InputIteratorTag_Traits { +public: + typedef std::input_iterator_tag iterator_category; +}; + +class BidirectionalIteratorTag_Traits { +public: + typedef std::bidirectional_iterator_tag iterator_category; +}; + +template<class Traits, class IteratorTagTraits> +class IteratorBase +{ +public: + + virtual ~IteratorBase() {} + + virtual bool begin() const = 0; + virtual bool end() const = 0; + + typedef typename IteratorTagTraits::iterator_category iterator_category; + typedef typename Traits::value_type value_type; + typedef typename Traits::difference_type difference_type; + typedef typename Traits::pointer pointer; + typedef typename Traits::reference reference; + +protected: + + IteratorBase() {} +}; + +#endif // BASEITERATOR_H diff --git a/source/blender/freestyle/intern/system/BaseObject.cpp b/source/blender/freestyle/intern/system/BaseObject.cpp new file mode 100755 index 00000000000..0cf1c917195 --- /dev/null +++ b/source/blender/freestyle/intern/system/BaseObject.cpp @@ -0,0 +1 @@ +#include "BaseObject.h" diff --git a/source/blender/freestyle/intern/system/BaseObject.h b/source/blender/freestyle/intern/system/BaseObject.h new file mode 100755 index 00000000000..a8515f98385 --- /dev/null +++ b/source/blender/freestyle/intern/system/BaseObject.h @@ -0,0 +1,73 @@ +// +// Filename : BaseObject.h +// Author(s) : Stephane Grabli +// Purpose : Base Class for most shared objects (Node, Rep). +// Defines the addRef, release system. +// Inspired by COM IUnknown system. +// Date of creation : 06/02/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BASEOBJECT_H +# define BASEOBJECT_H + +#include "FreestyleConfig.h" + +class LIB_SYSTEM_EXPORT BaseObject +{ +public: + + inline BaseObject() { + _ref_counter = 0; + } + + virtual ~BaseObject() {} + + /*! At least makes a release on this. + * The BaseObject::destroy method must be + * explicitely called at the end of any + * overloaded destroy + */ + virtual int destroy() { + return release(); + } + + /*! Increments the reference counter */ + inline int addRef() { + return ++_ref_counter; + } + + /*! Decrements the reference counter */ + inline int release() { + if (_ref_counter) + _ref_counter--; + return _ref_counter; + } + +private: + + unsigned _ref_counter; +}; + +#endif // BASEOBJECT_H diff --git a/source/blender/freestyle/intern/system/Cast.h b/source/blender/freestyle/intern/system/Cast.h new file mode 100755 index 00000000000..15af767443e --- /dev/null +++ b/source/blender/freestyle/intern/system/Cast.h @@ -0,0 +1,44 @@ +// +// Filename : Cast.h +// Author(s) : Emmanuel Turquin +// Purpose : Cast function +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef CAST_HPP +# define CAST_HPP + +namespace Cast { + + template <class T, class U> + U* cast(T* in) { + if (!in) + return NULL; + return dynamic_cast<U*>(in); + } + +} // end of namespace Cast + +#endif // CAST_HPP diff --git a/source/blender/freestyle/intern/system/Exception.cpp b/source/blender/freestyle/intern/system/Exception.cpp new file mode 100755 index 00000000000..d1d12d18297 --- /dev/null +++ b/source/blender/freestyle/intern/system/Exception.cpp @@ -0,0 +1,24 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "Exception.h" + +Exception::exception_type Exception::_exception = Exception::NO_EXCEPTION; diff --git a/source/blender/freestyle/intern/system/Exception.h b/source/blender/freestyle/intern/system/Exception.h new file mode 100755 index 00000000000..378de6b558f --- /dev/null +++ b/source/blender/freestyle/intern/system/Exception.h @@ -0,0 +1,64 @@ +// +// Filename : Exception.h +// Author(s) : Stephane Grabli +// Purpose : Singleton to manage exceptions +// Date of creation : 10/01/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef EXCEPTION_H +# define EXCEPTION_H + +# include "FreestyleConfig.h" + +class LIB_SYSTEM_EXPORT Exception +{ +public: + + typedef enum { + NO_EXCEPTION, + UNDEFINED + } exception_type; + + static int getException() { + exception_type e = _exception; + _exception = NO_EXCEPTION; + return e; + } + + static int raiseException(exception_type exception = UNDEFINED) { + _exception = exception; + return _exception; + } + + static void reset() { + _exception = NO_EXCEPTION; + } + +private: + + static exception_type _exception; +}; + +#endif // EXCEPTION_H diff --git a/source/blender/freestyle/intern/system/FreestyleConfig.h b/source/blender/freestyle/intern/system/FreestyleConfig.h new file mode 100755 index 00000000000..f06b9928d1d --- /dev/null +++ b/source/blender/freestyle/intern/system/FreestyleConfig.h @@ -0,0 +1,90 @@ +// +// Filename : Config.h +// Author(s) : Emmanuel Turquin +// Purpose : Configuration definitions +// Date of creation : 25/02/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + + +#ifndef CONFIG_H +# define CONFIG_H + +# include <string> +# include "BLI_math.h" + +using namespace std; + +namespace Config { + + // Directory separators +# ifdef WIN32 + static const string DIR_SEP("\\"); + static const string PATH_SEP(";"); +# else + static const string DIR_SEP("/"); + static const string PATH_SEP(":"); +# endif // WIN32 + + // DLL import/export macros for Win32 + +# ifndef LIB_SYSTEM_EXPORT +# define LIB_SYSTEM_EXPORT +# endif // LIB_SYSTEM_EXPORT + +# ifndef LIB_IMAGE_EXPORT +# define LIB_IMAGE_EXPORT +# endif // LIB_IMAGE_EXPORT + +# ifndef LIB_GEOMETRY_EXPORT +# define LIB_GEOMETRY_EXPORT +# endif // LIB_GEOMETRY_EXPORT + +# ifndef LIB_SCENE_GRAPH_EXPORT +# define LIB_SCENE_GRAPH_EXPORT +# endif // LIB_SCENE_GRAPH_EXPORT + +# ifndef LIB_WINGED_EDGE_EXPORT +# define LIB_WINGED_EDGE_EXPORT +# endif // LIB_WINGED_EDGE_EXPORT + +# ifndef LIB_VIEW_MAP_EXPORT +# define LIB_VIEW_MAP_EXPORT +# endif // LIB_VIEW_MAP_EXPORT + +# ifndef LIB_STROKE_EXPORT +# define LIB_STROKE_EXPORT +# endif // LIB_STROKE_EXPORT + +# ifndef LIB_RENDERING_EXPORT +# define LIB_RENDERING_EXPORT +# endif // LIB_RENDERING_EXPORT + +# ifndef LIB_WRAPPER_EXPORT +# define LIB_WRAPPER_EXPORT +# endif // LIB_WRAPPER_EXPORT + +} // end of namespace Config + +#endif // CONFIG_H diff --git a/source/blender/freestyle/intern/system/Id.h b/source/blender/freestyle/intern/system/Id.h new file mode 100755 index 00000000000..1f2206ed337 --- /dev/null +++ b/source/blender/freestyle/intern/system/Id.h @@ -0,0 +1,126 @@ +// +// Filename : Id.h +// Author(s) : Emmanuel Turquin +// Purpose : Identification system +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef ID_H +# define ID_H + +/*! Class used to tag any object by an id . + * It is made of two unsigned integers. + */ +class Id +{ +public: + + typedef unsigned id_type; + + /*! Default constructor */ + Id() { + _first = 0; + _second = 0; + } + + /*! Builds an Id from an integer. + * The second number is set to 0. + */ + Id(id_type id) { + _first = id; + _second = 0; + } + + /*! Builds the Id from the two numbers */ + Id(id_type ifirst, id_type isecond) { + _first = ifirst; + _second = isecond; + } + + /*! Copy constructor */ + Id(const Id& iBrother) { + _first = iBrother._first; + _second = iBrother._second; + } + + /*! Operator= */ + Id& operator=(const Id& iBrother) { + _first = iBrother._first; + _second = iBrother._second; + return *this; + } + + /*! Returns the first Id number */ + id_type getFirst() const { + return _first; + } + + /*! Returns the second Id number */ + id_type getSecond() const { + return _second; + } + + /*! Sets the first number constituing the Id */ + void setFirst(id_type first) { + _first = first; + } + + /*! Sets the second number constituing the Id */ + void setSecond(id_type second) { + _second = second; + } + + /*! Operator== */ + bool operator==(const Id& id) const { + return ((_first == id._first) && (_second == id._second)); + } + + /*! Operator!= */ + bool operator!=(const Id& id) const { + return !((*this)==id); + } + + /*! Operator< */ + bool operator<(const Id& id) const { + if (_first < id._first) + return true; + if (_first == id._first && _second < id._second) + return true; + return false; +} + +private: + + id_type _first; + id_type _second; +}; + +// stream operator +inline std::ostream& operator<<(std::ostream& s, const Id& id) { + s << "[" << id.getFirst() << ", " << id.getSecond() << "]"; + return s; +} + +# endif // ID_H diff --git a/source/blender/freestyle/intern/system/Interpreter.h b/source/blender/freestyle/intern/system/Interpreter.h new file mode 100755 index 00000000000..75aaa2ccd18 --- /dev/null +++ b/source/blender/freestyle/intern/system/Interpreter.h @@ -0,0 +1,56 @@ +// +// Filename : Interpreter.h +// Author(s) : Emmanuel Turquin +// Purpose : Base Class of all script interpreters +// Date of creation : 17/04/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef INTERPRETER_H +# define INTERPRETER_H + +# include <string> + +using namespace std; + +class LIB_SYSTEM_EXPORT Interpreter +{ + public: + + Interpreter() { _language = "Unknown"; } + + virtual ~Interpreter() {}; //soc + + virtual int interpretFile(const string& filename) = 0; + + virtual string getLanguage() const { return _language; } + + virtual void reset() = 0; + + protected: + + string _language; +}; + +#endif // INTERPRETER_H diff --git a/source/blender/freestyle/intern/system/Iterator.cpp b/source/blender/freestyle/intern/system/Iterator.cpp new file mode 100644 index 00000000000..67acc893589 --- /dev/null +++ b/source/blender/freestyle/intern/system/Iterator.cpp @@ -0,0 +1 @@ +#include "Iterator.h" diff --git a/source/blender/freestyle/intern/system/Iterator.h b/source/blender/freestyle/intern/system/Iterator.h new file mode 100644 index 00000000000..1801c1e3b2f --- /dev/null +++ b/source/blender/freestyle/intern/system/Iterator.h @@ -0,0 +1,41 @@ +#ifndef ITERATOR_H +#define ITERATOR_H + +#include <iostream> +#include <string> +using namespace std; + + +class Iterator +{ +public: + + virtual ~Iterator() {} + + virtual string getExactTypeName() const { + return "Iterator"; + } + + virtual int increment() { + cerr << "Warning: increment() not implemented" << endl; + return 0; + } + + virtual int decrement() { + cerr << "Warning: decrement() not implemented" << endl; + return 0; + } + + virtual bool isBegin() const { + cerr << "Warning: isBegin() not implemented" << endl; + return false; + } + + virtual bool isEnd() const { + cerr << "Warning: isEnd() not implemented" << endl; + return false; + } + +}; + +#endif // ITERATOR_H diff --git a/source/blender/freestyle/intern/system/Precision.h b/source/blender/freestyle/intern/system/Precision.h new file mode 100755 index 00000000000..24327a280df --- /dev/null +++ b/source/blender/freestyle/intern/system/Precision.h @@ -0,0 +1,39 @@ +// +// Filename : Precision.h +// Author(s) : Stephane Grabli +// Purpose : Define the float precision used in the program +// Date of creation : 30/07/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef PRECISION_H +# define PRECISION_H + +typedef double real; + +# ifndef SWIG +static const real M_EPSILON = 0.00000001; +# endif // SWIG + +#endif // PRECISION_H diff --git a/source/blender/freestyle/intern/system/ProgressBar.h b/source/blender/freestyle/intern/system/ProgressBar.h new file mode 100755 index 00000000000..5b61f936c90 --- /dev/null +++ b/source/blender/freestyle/intern/system/ProgressBar.h @@ -0,0 +1,85 @@ +// +// Filename : ProgressBar.h +// Author(s) : Stephane Grabli +// Purpose : Class to encapsulate a progress bar +// Date of creation : 27/08/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef PROGRESSBAR_H +# define PROGRESSBAR_H + +# include <string> + +using namespace std; + +class ProgressBar +{ +public: + + inline ProgressBar() { + _numtotalsteps = 0; + _progress = 0; + } + + virtual ~ProgressBar() {} + + virtual void reset() { + _numtotalsteps = 0; + _progress = 0; + } + + virtual void setTotalSteps(unsigned n) { + _numtotalsteps = n; + } + + virtual void setProgress(unsigned i) { + _progress = i; + } + + virtual void setLabelText(const string& s) { + _label = s; + } + + /*! accessors */ + inline unsigned int getTotalSteps() const { + return _numtotalsteps; + } + + inline unsigned int getProgress() const { + return _progress; + } + + inline string getLabelText() const { + return _label; + } + +protected: + + unsigned _numtotalsteps; + unsigned _progress; + string _label; +}; + +#endif // PROGRESSBAR_H diff --git a/source/blender/freestyle/intern/system/PseudoNoise.cpp b/source/blender/freestyle/intern/system/PseudoNoise.cpp new file mode 100755 index 00000000000..87ee45e69b2 --- /dev/null +++ b/source/blender/freestyle/intern/system/PseudoNoise.cpp @@ -0,0 +1,108 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <math.h> +#include "RandGen.h" +#include "PseudoNoise.h" + +static const unsigned NB_VALUE_NOISE = 512; + +real *PseudoNoise::_values; + +PseudoNoise::PseudoNoise () +{ +} + +void +PseudoNoise::init (long seed) +{ + _values = new real[NB_VALUE_NOISE]; + RandGen::srand48(seed); + for (unsigned int i=0; i<NB_VALUE_NOISE; i++) + _values[i] = -1.0 + 2.0 * RandGen::drand48(); +} + +real +PseudoNoise::linearNoise (real x) +{ + int i = x*NB_VALUE_NOISE; + real x1=_values[i%NB_VALUE_NOISE], x2=_values[(i+1)%NB_VALUE_NOISE]; + real t=x*real(NB_VALUE_NOISE)-real(i); + return x1*(1-t)+x2*t; +} + +real +LanczosWindowed(real t) +{ + if (fabs(t)>2) return 0; + if (fabs(t)<M_EPSILON) return 1.0; + return sin(M_PI*t)/(M_PI*t) * sin(M_PI*t/2.0)/(M_PI*t/2.0); +} + +real +PseudoNoise::smoothNoise (real x) +{ + int i = x*NB_VALUE_NOISE; + real t=x*real(NB_VALUE_NOISE)-real(i); + if (i - 1 < 0) + { + int plus=-i/NB_VALUE_NOISE; + i=i+NB_VALUE_NOISE*(plus+2); + t=(x+plus+2)*real(NB_VALUE_NOISE)-real(i); + } + + real x1=_values[i%NB_VALUE_NOISE], x2=_values[(i+1)%NB_VALUE_NOISE]; + real x0=_values[(i-1)%NB_VALUE_NOISE], x3=_values[(i+2)%NB_VALUE_NOISE]; + + real y0=LanczosWindowed(-1-t); + real y1=LanczosWindowed(-t); + real y2=LanczosWindowed(1-t); + real y3=LanczosWindowed(2-t); + // cerr<<"x0="<<x0<<" x1="<<x1<<" x2="<<x2<<" x3="<<x3<<endl; + // cerr<<"y0="<<y0<<" y1="<<y1<<" y2="<<y2<<" y3="<<y3<<" :"; + return (x0*y0+x1*y1+x2*y2+x3*y3)/(y0+y1+y2+y3); +} + +real +PseudoNoise::turbulenceSmooth (real x, unsigned nbOctave) +{ + real y=0; + real k=1.0; + for (unsigned i=0; i<nbOctave; i++) + { + y=y+k*smoothNoise(x*k); + k=k/2.0; + } + return y; +} + +real +PseudoNoise::turbulenceLinear (real x, unsigned nbOctave) +{ + real y=0; + real k=1.0; + for (unsigned i=0; i<nbOctave; i++) + { + y=y+k*linearNoise(x*k); + k=k/2.0; + } + return y; +} diff --git a/source/blender/freestyle/intern/system/PseudoNoise.h b/source/blender/freestyle/intern/system/PseudoNoise.h new file mode 100755 index 00000000000..43143865600 --- /dev/null +++ b/source/blender/freestyle/intern/system/PseudoNoise.h @@ -0,0 +1,58 @@ +// +// Filename : PseudoNoise.h +// Author(s) : Fredo Durand +// Purpose : Class to define a pseudo Perlin noise +// Date of creation : 16/06/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef PSEUDONOISE_H +# define PSEUDONOISE_H + +# include "FreestyleConfig.h" +# include "Precision.h" + +class LIB_SYSTEM_EXPORT PseudoNoise +{ +public: + + PseudoNoise (); + + virtual ~PseudoNoise () {} + + real smoothNoise (real x); + real linearNoise (real x); + + real turbulenceSmooth (real x, unsigned nbOctave = 8); + real turbulenceLinear (real x, unsigned nbOctave = 8); + + static void init (long seed); + +protected: + + static real *_values; +}; + +#endif // PSEUDONOISE_H + diff --git a/source/blender/freestyle/intern/system/PythonInterpreter.cpp b/source/blender/freestyle/intern/system/PythonInterpreter.cpp new file mode 100755 index 00000000000..821bd32b40b --- /dev/null +++ b/source/blender/freestyle/intern/system/PythonInterpreter.cpp @@ -0,0 +1,25 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "PythonInterpreter.h" + +string PythonInterpreter::_path = ""; +bool PythonInterpreter::_initialized = false; diff --git a/source/blender/freestyle/intern/system/PythonInterpreter.h b/source/blender/freestyle/intern/system/PythonInterpreter.h new file mode 100755 index 00000000000..bf1a5064d3e --- /dev/null +++ b/source/blender/freestyle/intern/system/PythonInterpreter.h @@ -0,0 +1,158 @@ +// +// Filename : PythonInterpreter.h +// Author(s) : Emmanuel Turquin +// Purpose : Python Interpreter +// Date of creation : 17/04/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef PYTHON_INTERPRETER_H +# define PYTHON_INTERPRETER_H + +# include <iostream> +# include <Python.h> +# include "StringUtils.h" +# include "Interpreter.h" + +//soc +extern "C" { +#include "MEM_guardedalloc.h" +#include "BKE_main.h" +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_report.h" +#include "BKE_text.h" +#include "BKE_library.h" +#include "BPY_extern.h" +} + +class LIB_SYSTEM_EXPORT PythonInterpreter : public Interpreter +{ + public: + + PythonInterpreter() { + _language = "Python"; + _context = 0; + //Py_Initialize(); + } + + virtual ~PythonInterpreter() { + //Py_Finalize(); + } + + void setContext(bContext *C) { + _context = C; + } + + int interpretFile(const string& filename) { + + initPath(); + + ReportList* reports = CTX_wm_reports(_context); + BKE_reports_clear(reports); + char *fn = const_cast<char*>(filename.c_str()); +#if 0 + int status = BPY_run_python_script(_context, fn, NULL, reports); +#else + int status; + Text *text = add_text(fn, G.sce); + if (text) { + status = BPY_run_python_script(_context, NULL, text, reports); + unlink_text(G.main, text); + free_libblock(&G.main->text, text); + } else { + BKE_reportf(reports, RPT_ERROR, "Cannot open file: %s", fn); + status = 0; + } +#endif + + if (status != 1) { + cout << "\nError executing Python script from PythonInterpreter::interpretFile" << endl; + cout << "File: " << fn << endl; + cout << "Errors: " << endl; + BKE_reports_print(reports, RPT_ERROR); + return 1; + } + + // cleaning up + BKE_reports_clear(reports); + + return 0; + } + + struct Options + { + static void setPythonPath(const string& path) { + _path = path; + } + + static string getPythonPath() { + return _path; + } + }; + + void reset() { + Py_Finalize(); + Py_Initialize(); + _initialized = false; + } + +private: + + bContext* _context; + + void initPath() { + if (_initialized) + return; + + vector<string> pathnames; + StringUtils::getPathName(_path, "", pathnames); + + struct Text *text = add_empty_text("tmp_freestyle_initpath.txt"); + string cmd = "import sys\n"; + txt_insert_buf(text, const_cast<char*>(cmd.c_str())); + + for (vector<string>::const_iterator it = pathnames.begin(); it != pathnames.end();++it) { + if ( !it->empty() ) { + cout << "Adding Python path: " << *it << endl; + cmd = "sys.path.append(r\"" + *it + "\")\n"; + txt_insert_buf(text, const_cast<char*>(cmd.c_str())); + } + } + + BPY_run_python_script(_context, NULL, text, NULL); + + // cleaning up + unlink_text(G.main, text); + free_libblock(&G.main->text, text); + + //PyRun_SimpleString("from Freestyle import *"); + _initialized = true; + } + + static bool _initialized; + static string _path; +}; + +#endif // PYTHON_INTERPRETER_H diff --git a/source/blender/freestyle/intern/system/RandGen.cpp b/source/blender/freestyle/intern/system/RandGen.cpp new file mode 100755 index 00000000000..a328cb7f583 --- /dev/null +++ b/source/blender/freestyle/intern/system/RandGen.cpp @@ -0,0 +1,86 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "RandGen.h" + +// +// Macro definitions +// +/////////////////////////////////////////////////////////////////////////////// + +#define N 16 +#define MASK ((unsigned)(1 << (N - 1)) + (1 << (N - 1)) - 1) +#define X0 0x330E +#define X1 0xABCD +#define X2 0x1234 +#define A0 0xE66D +#define A1 0xDEEC +#define A2 0x5 +#define C 0xB +#define HI_BIT (1L << (2 * N - 1)) + +#define LOW(x) ((unsigned)(x) & MASK) +#define HIGH(x) LOW((x) >> N) +#define MUL(x, y, z) { long l = (long)(x) * (long)(y); \ + (z)[0] = LOW(l); (z)[1] = HIGH(l); } +#define CARRY(x, y) ((unsigned long)((long)(x) + (long)(y)) > MASK) +#define ADDEQU(x, y, z) (z = CARRY(x, (y)), x = LOW(x + (y))) +#define SET3(x, x0, x1, x2) ((x)[0] = (x0), (x)[1] = (x1), (x)[2] = (x2)) +#define SETLOW(x, y, n) SET3(x, LOW((y)[n]), LOW((y)[(n)+1]), LOW((y)[(n)+2])) +#define SEED(x0, x1, x2) (SET3(x, x0, x1, x2), SET3(a, A0, A1, A2), c = C) +#define REST(v) for (i = 0; i < 3; i++) { xsubi[i] = x[i]; x[i] = temp[i]; } \ + return (v); +#define NEST(TYPE, f, F) TYPE f(register unsigned short *xsubi) { \ + register int i; register TYPE v; unsigned temp[3]; \ + for (i = 0; i < 3; i++) { temp[i] = x[i]; x[i] = LOW(xsubi[i]); } \ + v = F(); REST(v); } + +static unsigned x[3] = { X0, X1, X2 }, a[3] = { A0, A1, A2 }, c = C; + +// +// Methods implementation +// +/////////////////////////////////////////////////////////////////////////////// + +real RandGen::drand48() { + static real two16m = 1.0 / (1L << N); + next(); + return (two16m * (two16m * (two16m * x[0] + x[1]) + x[2])); +} + +void RandGen::srand48(long seedval) { + SEED(X0, LOW(seedval), HIGH(seedval)); +} + +void RandGen::next() { + unsigned p[2], q[2], r[2], carry0, carry1; + + MUL(a[0], x[0], p); + ADDEQU(p[0], c, carry0); + ADDEQU(p[1], carry0, carry1); + MUL(a[0], x[1], q); + ADDEQU(p[1], q[0], carry0); + MUL(a[1], x[0], r); + x[2] = LOW(carry0 + carry1 + CARRY(p[1], r[0]) + q[1] + r[1] + + a[0] * x[2] + a[1] * x[1] + a[2] * x[0]); + x[1] = LOW(p[1] + r[0]); + x[0] = LOW(p[0]); +} diff --git a/source/blender/freestyle/intern/system/RandGen.h b/source/blender/freestyle/intern/system/RandGen.h new file mode 100755 index 00000000000..409d3b79609 --- /dev/null +++ b/source/blender/freestyle/intern/system/RandGen.h @@ -0,0 +1,48 @@ +// +// Filename : RandGen.h +// Author(s) : Fredo Durand +// Purpose : Pseudo-random number generator +// Date of creation : 20/05/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef RAND_GEN_H +# define RAND_GEN_H + +# include "FreestyleConfig.h" +# include "../system/Precision.h" + +class LIB_SYSTEM_EXPORT RandGen +{ +public: + + static real drand48(); + static void srand48(long value); + +private: + + static void next(); +}; + +#endif // RAND_GEN_H diff --git a/source/blender/freestyle/intern/system/StringUtils.cpp b/source/blender/freestyle/intern/system/StringUtils.cpp new file mode 100755 index 00000000000..58798daf42a --- /dev/null +++ b/source/blender/freestyle/intern/system/StringUtils.cpp @@ -0,0 +1,74 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +//soc #include <qfileinfo.h> +#include "FreestyleConfig.h" +#include "StringUtils.h" + +namespace StringUtils { + + void getPathName(const string& path, const string& base, vector<string>& pathnames) { + string dir; + string res; + char cleaned[FILE_MAX]; + unsigned size = path.size(); + + pathnames.push_back(base); + + for ( unsigned pos = 0, sep = path.find(Config::PATH_SEP, pos); + pos < size; + pos = sep + 1, sep = path.find(Config::PATH_SEP, pos)) { + + if (sep == (unsigned)string::npos) + sep = size; + + dir = path.substr(pos, sep - pos); + + BLI_strncpy(cleaned, dir.c_str(), FILE_MAX); + BLI_cleanup_file(NULL, cleaned); + res = toAscii( string(cleaned) ); + + if (!base.empty()) + res += Config::DIR_SEP + base; + + pathnames.push_back(res); + } + } + + string toAscii( const string &str ){ + stringstream out(""); + char s; + + for(unsigned int i=0; i < str.size() ; i++){ + s = ((char)(str.at(i) & 0x7F)); + out << s; + } + + return out.str(); + } + + const char* toAscii( const char *str ){ + return toAscii(string(str)).c_str(); + } + + + +} // end of namespace StringUtils diff --git a/source/blender/freestyle/intern/system/StringUtils.h b/source/blender/freestyle/intern/system/StringUtils.h new file mode 100755 index 00000000000..d44d3f62732 --- /dev/null +++ b/source/blender/freestyle/intern/system/StringUtils.h @@ -0,0 +1,62 @@ +// +// Filename : StringUtils.h +// Author(s) : Emmanuel Turquin +// Purpose : String utilities +// Date of creation : 20/05/2003 +// +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef STRING_UTILS_H +# define STRING_UTILS_H + +# include <cstring> +# include <vector> +# include <string> +# include <sstream> +# include <iostream> +# include "FreestyleConfig.h" + +//soc +extern "C" { +#include "BKE_utildefines.h" +#include "BLI_blenlib.h" +} + +using namespace std; + +namespace StringUtils { + + LIB_SYSTEM_EXPORT + void getPathName(const string& path, const string& base, vector<string>& pathnames); + string toAscii( const string &str ); + const char* toAscii( const char *str ); + + // STL related + struct ltstr{ + bool operator()(const char* s1, const char* s2) const{ + return strcmp(s1, s2) < 0; + } +}; + +} // end of namespace StringUtils + +#endif // STRING_UTILS_H diff --git a/source/blender/freestyle/intern/system/TimeStamp.cpp b/source/blender/freestyle/intern/system/TimeStamp.cpp new file mode 100755 index 00000000000..c66e1131611 --- /dev/null +++ b/source/blender/freestyle/intern/system/TimeStamp.cpp @@ -0,0 +1,25 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "TimeStamp.h" + +LIB_SYSTEM_EXPORT +TimeStamp* TimeStamp::_instance = 0; diff --git a/source/blender/freestyle/intern/system/TimeStamp.h b/source/blender/freestyle/intern/system/TimeStamp.h new file mode 100755 index 00000000000..568a7851e30 --- /dev/null +++ b/source/blender/freestyle/intern/system/TimeStamp.h @@ -0,0 +1,71 @@ +// +// Filename : TimeStamp.h +// Author(s) : Stephane Grabli +// Purpose : Class defining a singleton used as timestamp +// Date of creation : 12/12/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef TIMESTAMP_H +# define TIMESTAMP_H + +# include "FreestyleConfig.h" + +class LIB_SYSTEM_EXPORT TimeStamp +{ + public: + + static inline TimeStamp* instance() { + if (_instance == 0) + _instance = new TimeStamp; + return _instance; + } + + inline unsigned getTimeStamp() const { + return _time_stamp; + } + + inline void increment() { + ++_time_stamp; + } + + inline void reset() { + _time_stamp = 1; + } + + protected: + + TimeStamp() { + _time_stamp = 1; + } + + TimeStamp(const TimeStamp&) {} + + private: + + static TimeStamp* _instance; + unsigned _time_stamp; +}; + +#endif // TIMESTAMP_H diff --git a/source/blender/freestyle/intern/system/TimeUtils.h b/source/blender/freestyle/intern/system/TimeUtils.h new file mode 100755 index 00000000000..99dd5b0a669 --- /dev/null +++ b/source/blender/freestyle/intern/system/TimeUtils.h @@ -0,0 +1,58 @@ +// +// Filename : TimeUtils.h +// Author(s) : Stephane Grabli +// Purpose : Class to measure ellapsed time +// Date of creation : 10/04/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef TIMEUTILS_H +# define TIMEUTILS_H + +#include <time.h> +#include "FreestyleConfig.h" + +class Chronometer +{ + public: + + inline Chronometer() {} + inline ~Chronometer() {} + + inline clock_t start() { + _start = clock(); + return _start; + } + + inline double stop() { + clock_t stop = clock(); + return (double)(stop - _start) / CLOCKS_PER_SEC ; + } + + private: + + clock_t _start; +}; + +#endif // TIMEUTILS_H diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp new file mode 100755 index 00000000000..0551fd3ac15 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp @@ -0,0 +1,700 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "FEdgeXDetector.h" +#include "float.h" +#include "../geometry/GeomUtils.h" +#include <math.h> +#include "../geometry/normal_cycle.h" + +void FEdgeXDetector::processShapes(WingedEdge& we) { + bool progressBarDisplay = false; + Vec3r Min, Max; + vector<WShape*> wshapes = we.getWShapes(); + WXShape * wxs; + + if(_pProgressBar != NULL) { + _pProgressBar->reset(); + _pProgressBar->setLabelText("Detecting feature lines"); + _pProgressBar->setTotalSteps(wshapes.size() * 3); + _pProgressBar->setProgress(0); + progressBarDisplay = true; + } + + for(vector<WShape*>::const_iterator it = wshapes.begin(); + it != wshapes.end(); + it++){ + wxs = dynamic_cast<WXShape*>(*it); + wxs->bbox(Min, Max); + _bbox_diagonal = (Max-Min).norm(); + if(_changes){ + vector<WFace*>& wfaces = wxs->GetFaceList(); + for(vector<WFace*>::iterator wf=wfaces.begin(), wfend=wfaces.end(); + wf!=wfend; + ++wf){ + WXFace* wxf = dynamic_cast<WXFace*>(*wf); + wxf->Clear(); + } + _computeViewIndependant = true; + } else if (!(wxs)->getComputeViewIndependantFlag()) { + wxs->Reset(); + _computeViewIndependant = false; + } else { + _computeViewIndependant = true; + } + preProcessShape(wxs); + if (progressBarDisplay) + _pProgressBar->setProgress(_pProgressBar->getProgress() + 1); + processBorderShape(wxs); + processCreaseShape(wxs); + if(_computeRidgesAndValleys) + processRidgesAndValleysShape(wxs); + if(_computeSuggestiveContours) + processSuggestiveContourShape(wxs); + processSilhouetteShape(wxs); + if (progressBarDisplay) + _pProgressBar->setProgress(_pProgressBar->getProgress() + 1); + + // build smooth edges: + buildSmoothEdges(wxs); + + // Post processing for suggestive contours + if(_computeSuggestiveContours) + postProcessSuggestiveContourShape(wxs); + if (progressBarDisplay) + _pProgressBar->setProgress(_pProgressBar->getProgress() + 1); + + wxs->setComputeViewIndependantFlag(false); + _computeViewIndependant = false; + _changes = false; + + // reset user data + (*it)->ResetUserData(); + } +} + +// GENERAL STUFF +//////////////// +void FEdgeXDetector::preProcessShape(WXShape* iWShape) { + _meanK1 = 0; + _meanKr = 0; + _minK1 = FLT_MAX; + _maxK1 = -FLT_MAX; + _minKr = FLT_MAX; + _maxKr = -FLT_MAX; + _nPoints = 0; + _meanEdgeSize = iWShape->getMeanEdgeSize(); + + vector<WFace*>& wfaces = iWShape->GetFaceList(); + vector<WFace*>::iterator f,fend; + // view dependant stuff + for(f=wfaces.begin(), fend=wfaces.end(); + f!=fend; + ++f){ + preProcessFace((WXFace*)(*f)); + } + + vector<WVertex*>& wvertices = iWShape->getVertexList(); + for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end(); + wv!=wvend; + ++wv){ + // Compute curvatures + WXVertex * wxv = dynamic_cast<WXVertex*>(*wv); + computeCurvatures(wxv); + } + _meanK1 /= (real)(_nPoints); + _meanKr /= (real)(_nPoints); +} + +void FEdgeXDetector::preProcessFace(WXFace *iFace){ + Vec3r firstPoint = iFace->GetVertex(0)->GetVertex(); + Vec3r N = iFace->GetNormal(); + + // Compute the dot product between V (=_Viewpoint - firstPoint) and N: + Vec3r V; + if (_orthographicProjection) { + V = Vec3r(0.0, 0.0, _Viewpoint.z() - firstPoint.z()); + } else { + V = Vec3r(_Viewpoint - firstPoint); + } + N.normalize(); + V.normalize(); + iFace->setDotP(N * V); + + // compute the distance between the face center and the viewpoint: + if (_orthographicProjection) { + iFace->setZ(iFace->center().z() - _Viewpoint.z()); + } else { + Vec3r dist_vec(iFace->center() - _Viewpoint); + iFace->setZ(dist_vec.norm()); + } +} + +void FEdgeXDetector::computeCurvatures(WXVertex *vertex){ + // CURVATURE LAYER + // store all the curvature datas for each vertex + + //soc unused - real K1, K2 + real cos2theta, sin2theta; + Vec3r e1, n, v; + // one vertex curvature info : + CurvatureInfo *C; + float radius = _sphereRadius*_meanEdgeSize; + + // view independant stuff + if(_computeViewIndependant){ + C = new CurvatureInfo(); + vertex->setCurvatures(C); + OGF::NormalCycle ncycle ; + ncycle.begin() ; + if(radius > 0) { + OGF::compute_curvature_tensor(vertex, radius, ncycle) ; + } else { + OGF::compute_curvature_tensor_one_ring(vertex, ncycle) ; + } + ncycle.end() ; + C->K1 = ncycle.kmin(); + C->K2 = ncycle.kmax(); + C->e1 = ncycle.Kmax(); //ncycle.kmin() * ncycle.Kmax(); + C->e2 = ncycle.Kmin(); //ncycle.kmax() * ncycle.Kmin() ; + + real absK1 = fabs(C->K1); + _meanK1 += absK1; + if(absK1 > _maxK1) + _maxK1 = absK1; + if(absK1 < _minK1) + _minK1 = absK1; + } + // view dependant + C = vertex->curvatures(); + if(C == 0) + return; + + // compute radial curvature : + n = C->e1 ^ C->e2; + if (_orthographicProjection) { + v = Vec3r(0.0, 0.0, _Viewpoint.z() - vertex->GetVertex().z()); + } else { + v = Vec3r(_Viewpoint - vertex->GetVertex()); + } + C->er = v - (v * n) * n; + C->er.normalize(); + e1 = C->e1; + e1.normalize(); + cos2theta = C->er * e1; + cos2theta *= cos2theta; + sin2theta = 1 - cos2theta; + C->Kr = C->K1 * cos2theta + C->K2 * sin2theta; + real absKr = fabs(C->Kr); + _meanKr += absKr; + if(absKr > _maxKr) + _maxKr = absKr; + if(absKr < _minKr) + _minKr = absKr; + + ++_nPoints; +} + +// SILHOUETTE +///////////// +void FEdgeXDetector::processSilhouetteShape(WXShape* iWShape) { + // Make a first pass on every polygons in order + // to compute all their silhouette relative values: + //------------------------------------------------ + vector<WFace*>& wfaces = iWShape->GetFaceList(); + vector<WFace*>::iterator f,fend; + for(f=wfaces.begin(), fend=wfaces.end(); + f!=fend; + ++f) + { + ProcessSilhouetteFace((WXFace*)(*f)); + } + + // Make a pass on the edges to detect + // the silhouette edges that are not smooth + // -------------------- + vector<WEdge*>::iterator we, weend; + vector<WEdge*> &wedges = iWShape->getEdgeList(); + for(we=wedges.begin(), weend=wedges.end(); + we!=weend; + ++we) + { + ProcessSilhouetteEdge((WXEdge*)(*we)); + } +} + +void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace) +{ + + // SILHOUETTE LAYER + Vec3r normal; + // Compute the dot products between View direction and N at each vertex + // of the face: + Vec3r point; + int closestPointId = 0; + real dist, minDist = FLT_MAX; + int numVertices = iFace->numberOfVertices(); + WXFaceLayer * faceLayer = new WXFaceLayer(iFace, Nature::SILHOUETTE, true); + for(int i=0; i<numVertices; i++){ + point = iFace->GetVertex(i)->GetVertex(); + normal = iFace->GetVertexNormal(i); + normal.normalize(); + Vec3r V; + if (_orthographicProjection) { + V = Vec3r(0.0, 0.0, _Viewpoint.z() - point.z()); + } else { + V = Vec3r(_Viewpoint - point); + } + V.normalize(); + real d = normal * V; + faceLayer->PushDotP(d); + // Find the point the closest to the viewpoint + if (_orthographicProjection) { + dist = point.z() - _Viewpoint.z(); + } else { + Vec3r dist_vec(point - _Viewpoint); + dist = dist_vec.norm(); + } + if(dist < minDist) { + minDist = dist; + closestPointId = i; + } + } + // Set the closest point id: + faceLayer->setClosestPointIndex(closestPointId); + // Add this layer to the face: + iFace->AddSmoothLayer(faceLayer); +} + +void FEdgeXDetector::ProcessSilhouetteEdge(WXEdge *iEdge) +{ + if(iEdge->nature() & Nature::BORDER) + return; + // SILHOUETTE ? + //------------- + WXFace * fA = (WXFace *)iEdge->GetaOEdge()->GetaFace(); + WXFace * fB = (WXFace *)iEdge->GetaOEdge()->GetbFace(); + + if((fA->front())^(fB->front())){ // fA->visible XOR fB->visible (true if one is 0 and the other is 1) + // The only edges we want to set as silhouette edges in this + // way are the ones with 2 different normals for 1 vertex + // for these two faces + //-------------------- + // In reality we only test the normals for 1 of the 2 vertices. + if(fA->GetVertexNormal(iEdge->GetaVertex()) == fB->GetVertexNormal(iEdge->GetaVertex())) + return; + iEdge->AddNature(Nature::SILHOUETTE); + if(fB->front()) + iEdge->setOrder(1); + else + iEdge->setOrder(-1); + } +} + + +// BORDER +///////// +void FEdgeXDetector::processBorderShape(WXShape* iWShape) { + + if(!_computeViewIndependant) + return; + // Make a pass on the edges to detect + // the BORDER + // -------------------- + vector<WEdge*>::iterator we, weend; + vector<WEdge*> &wedges = iWShape->getEdgeList(); + for(we=wedges.begin(), weend=wedges.end(); + we!=weend; + ++we){ + ProcessBorderEdge((WXEdge*)(*we)); + } +} + +void FEdgeXDetector::ProcessBorderEdge(WXEdge *iEdge) +{ + // first check whether it is a border edge: + // BORDER ? + //--------- + if(iEdge->GetaFace() == 0){ + // it is a border edge + iEdge->AddNature(Nature::BORDER); + } +} + + +// CREASE +///////// +void FEdgeXDetector::processCreaseShape(WXShape* iWShape) { + if(!_computeViewIndependant) + return; + + // Make a pass on the edges to detect + // the CREASE + // -------------------- + vector<WEdge*>::iterator we, weend; + vector<WEdge*> &wedges = iWShape->getEdgeList(); + for(we=wedges.begin(), weend=wedges.end(); + we!=weend; + ++we){ + ProcessCreaseEdge((WXEdge*)(*we)); + } +} + +void FEdgeXDetector::ProcessCreaseEdge(WXEdge *iEdge) +{ + // CREASE ? + //--------- + if(iEdge->nature() & Nature::BORDER) + return; + WXFace * fA = (WXFace *)iEdge->GetaOEdge()->GetaFace(); + WXFace * fB = (WXFace *)iEdge->GetaOEdge()->GetbFace(); + + WVertex * aVertex = iEdge->GetaVertex(); + if((fA->GetVertexNormal(aVertex) * fB->GetVertexNormal(aVertex)) <= 0.7) // angle of 140 degrees + iEdge->AddNature(Nature::CREASE); +} + +// RIDGES AND VALLEYS +///////////////////// + +void FEdgeXDetector::processRidgesAndValleysShape(WXShape* iWShape) { + // Don't forget to add the built layer to the face at the end + // of the ProcessFace: + //iFace->AddSmoothLayer(faceLayer); + + if((!_computeViewIndependant)) + return; + + // Here the curvatures must already have been computed + vector<WFace*>& wfaces = iWShape->GetFaceList(); + vector<WFace*>::iterator f, fend; + for(f=wfaces.begin(), fend=wfaces.end(); + f!=fend; + ++f) + { + ProcessRidgeFace((WXFace*)(*f)); + } +} + + +// RIDGES +///////// + +void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace) +{ + WXFaceLayer * flayer = new WXFaceLayer(iFace, Nature::RIDGE|Nature::VALLEY, false); + iFace->AddSmoothLayer(flayer); + + unsigned int numVertices = iFace->numberOfVertices(); + for(unsigned int i=0; i<numVertices; ++i){ + WVertex *wv = iFace->GetVertex(i); + WXVertex * wxv = dynamic_cast<WXVertex*>(wv); + flayer->PushDotP(wxv->curvatures()->K1); + } + + real threshold = 0; + //real threshold = _maxK1 - (_maxK1-_meanK1)/20.0; + + if(flayer->nPosDotP()!=numVertices){ + if((fabs(flayer->dotP(0)) < threshold) && (fabs(flayer->dotP(1)) < threshold) && (fabs(flayer->dotP(2)) < threshold)){ + flayer->ReplaceDotP(0, 0); + flayer->ReplaceDotP(1, 0); + flayer->ReplaceDotP(2, 0); + } + } +} + +// void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace) +// { + +// // RIDGE LAYER +// // compute the RidgeFunction, that is the derivative of the ppal curvature +// // along e1 at each vertex of the face + +// WVertex *v; +// Vec3r v1v2; +// real t; +// vector<WXFaceLayer*> SmoothLayers; +// WXFaceLayer *faceLayer; +// Face_Curvature_Info *layer_info; +// real K1_a(0), K1_b(0); +// Vec3r Inter_a, Inter_b; + +// // find the ridge layer of the face +// iFace->retrieveSmoothLayers(Nature::RIDGE, SmoothLayers); +// if(SmoothLayers.size()!=1) +// return; +// faceLayer = SmoothLayers[0]; +// // retrieve the curvature info of this layer +// layer_info = (Face_Curvature_Info *)faceLayer->userdata; + +// int numVertices = iFace->numberOfVertices(); +// for(int i=0; i<numVertices; i++){ +// v = iFace->GetVertex(i); +// // vec_curvature_info[i] contains the curvature info of this vertex +// Vec3r e2 = layer_info->vec_curvature_info[i]->K2*layer_info->vec_curvature_info[i]->e2; +// Vec3r e1 = layer_info->vec_curvature_info[i]->K1*layer_info->vec_curvature_info[i]->e1; +// e2.normalize(); + +// WVertex::face_iterator fit = v->faces_begin(); +// WVertex::face_iterator fitend = v->faces_end(); +// for(; fit!=fitend; ++fit){ +// WXFace * wxf = dynamic_cast<WXFace*>(*fit); +// WOEdge * oppositeEdge; +// if(!(wxf->getOppositeEdge(v, oppositeEdge))) +// continue; +// v1v2 = oppositeEdge->GetbVertex()->GetVertex() - oppositeEdge->GetaVertex()->GetVertex(); +// GeomUtils::intersection_test res; +// res = GeomUtils::intersectRayPlane(oppositeEdge->GetaVertex()->GetVertex(), v1v2, +// e2, -(v->GetVertex()*e2), +// t,1.e-06); +// if((res == GeomUtils::DO_INTERSECT) && (t>=0.0) && (t<=1.0)){ +// vector<WXFaceLayer*> second_ridge_layer; +// wxf->retrieveSmoothLayers(Nature::RIDGE, second_ridge_layer); +// if(second_ridge_layer.size()!=1) +// continue; +// Face_Curvature_Info *second_layer_info = (Face_Curvature_Info*)second_ridge_layer[0]->userdata; + +// unsigned index1 = wxf->GetIndex(oppositeEdge->GetaVertex()); +// unsigned index2 = wxf->GetIndex(oppositeEdge->GetbVertex()); +// real K1_1 = second_layer_info->vec_curvature_info[index1]->K1; +// real K1_2 = second_layer_info->vec_curvature_info[index2]->K1; +// real K1 = (1.0-t)*K1_1 + t*K1_2; +// Vec3r inter((1.0-t)*oppositeEdge->GetaVertex()->GetVertex() + t*oppositeEdge->GetbVertex()->GetVertex()); +// Vec3r vtmp(inter - v->GetVertex()); +// // is it K1_a or K1_b ? +// if(vtmp*e1 > 0){ +// K1_b = K1; +// Inter_b = inter; +// }else{ +// K1_a = K1; +// Inter_a = inter; +// } +// } +// } +// // Once we have K1 along the the ppal direction +// // compute the derivative : K1b - K1a +// // put it in DotP +// //real d = fabs(K1_b)-fabs(K1_a); +// real d = 0; +// real threshold = _meanK1 + (_maxK1-_meanK1)/7.0; +// //real threshold = _meanK1; +// //if((fabs(K1_b) > threshold) || ((fabs(K1_a) > threshold))) +// d = (K1_b)-(K1_a)/(Inter_b-Inter_a).norm(); +// faceLayer->PushDotP(d); +// //faceLayer->PushDotP(layer_info->vec_curvature_info[i]->K1); +// } + +// // Make the values relevant by checking whether all principal +// // directions have the "same" direction: +// Vec3r e0((layer_info->vec_curvature_info[0]->K1*layer_info->vec_curvature_info[0]->e1)); +// e0.normalize(); +// Vec3r e1((layer_info->vec_curvature_info[1]->K1*layer_info->vec_curvature_info[1]->e1)); +// e1.normalize(); +// Vec3r e2((layer_info->vec_curvature_info[2]->K1*layer_info->vec_curvature_info[2]->e1)); +// e2.normalize(); +// if (e0 * e1 < 0) +// // invert dotP[1] +// faceLayer->ReplaceDotP(1, -faceLayer->dotP(1)); +// if (e0 * e2 < 0) +// // invert dotP[2] +// faceLayer->ReplaceDotP(2, -faceLayer->dotP(2)); + +// // remove the weakest values; +// //real minDiff = (_maxK1 - _minK1)/10.0; +// // real minDiff = _meanK1; +// // if((faceLayer->dotP(0) < minDiff) && (faceLayer->dotP(1) < minDiff) && (faceLayer->dotP(2) < minDiff)){ +// // faceLayer->ReplaceDotP(0, 0); +// // faceLayer->ReplaceDotP(1, 0); +// // faceLayer->ReplaceDotP(2, 0); +// // } +// } + +// SUGGESTIVE CONTOURS +////////////////////// + +void FEdgeXDetector::processSuggestiveContourShape(WXShape* iWShape) { + + // Here the curvatures must already have been computed + vector<WFace*>& wfaces = iWShape->GetFaceList(); + vector<WFace*>::iterator f, fend; + for(f=wfaces.begin(), fend=wfaces.end(); + f!=fend; + ++f) + { + ProcessSuggestiveContourFace((WXFace*)(*f)); + } +} + +void FEdgeXDetector::ProcessSuggestiveContourFace(WXFace *iFace) +{ + WXFaceLayer *faceLayer = new WXFaceLayer(iFace, Nature::SUGGESTIVE_CONTOUR, true); + iFace->AddSmoothLayer(faceLayer); + + unsigned int numVertices = iFace->numberOfVertices(); + for(unsigned int i=0; i<numVertices; ++i){ + WVertex *wv = iFace->GetVertex(i); + WXVertex * wxv = dynamic_cast<WXVertex*>(wv); + faceLayer->PushDotP(wxv->curvatures()->Kr); + } + + // FIXME: find a more clever way to compute the threshold +// real threshold = _meanKr; +// if(faceLayer->nPosDotP()!=numVertices){ +// if((fabs(faceLayer->dotP(0)) < threshold) && (fabs(faceLayer->dotP(1)) < threshold) && (fabs(faceLayer->dotP(2)) < threshold)){ +// faceLayer->ReplaceDotP(0, 0); +// faceLayer->ReplaceDotP(1, 0); +// faceLayer->ReplaceDotP(2, 0); +// } +// } +} + +void FEdgeXDetector::postProcessSuggestiveContourShape(WXShape* iShape) { + vector<WFace*>& wfaces = iShape->GetFaceList(); + vector<WFace*>::iterator f, fend; + for(f=wfaces.begin(), fend=wfaces.end(); + f!=fend; + ++f) + { + postProcessSuggestiveContourFace((WXFace*)(*f)); + } +} + +void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace) { + + // Compute the derivative of the radial curvature in the radial direction, + // at the two extremities of the smooth edge. + // If the derivative is smaller than a given threshold _kr_derivative_epsilon, + // discard the edge. + + // Find the suggestive contour layer of the face (zero or one edge). + vector<WXFaceLayer*> sc_layers; + iFace->retrieveSmoothEdgesLayers(Nature::SUGGESTIVE_CONTOUR, sc_layers); + if(sc_layers.empty()) + return; + + WXFaceLayer *sc_layer; + sc_layer = sc_layers[0]; + + // Compute the derivative value at each vertex of the face, and add it in a vector. + vector<real> kr_derivatives; + + unsigned vertices_nb = iFace->numberOfVertices(); + WXVertex *v, *opposite_vertex_a, *opposite_vertex_b; + WXFace *wxf; + WOEdge *opposite_edge; + Vec3r opposite_edge_vec, normal_vec, radial_normal_vec, er_vec, v_vec, inter, inter1, inter2, tmp_vec; + GeomUtils::intersection_test res; + real kr(0), kr1(0), kr2(0), t; + + for (unsigned i = 0; i < vertices_nb; ++i) { + v = (WXVertex*)(iFace->GetVertex(i)); + + // v is a singular vertex, skip it. + if (v->isBoundary()) { + kr_derivatives.push_back(0); + continue; + } + + v_vec = v->GetVertex(); + er_vec = v->curvatures()->er; + + // For each vertex, iterate on its adjacent faces. + for (WVertex::face_iterator fit = v->faces_begin(), fitend = v->faces_end(); + fit != fitend; + ++fit) { + wxf = dynamic_cast<WXFace*>(*fit); + if(!(wxf->getOppositeEdge(v, opposite_edge))) + continue; + + opposite_vertex_a = (WXVertex*)opposite_edge->GetaVertex(); + opposite_vertex_b = (WXVertex*)opposite_edge->GetbVertex(); + opposite_edge_vec = opposite_vertex_b->GetVertex() - opposite_vertex_a->GetVertex(); + normal_vec = wxf->GetVertexNormal(v); // FIXME: what about e1 ^ e2 ? + radial_normal_vec = er_vec ^ normal_vec; + + // Test wether the radial plan intersects with the edge at the opposite of v. + res = GeomUtils::intersectRayPlane(opposite_vertex_a->GetVertex(), opposite_edge_vec, + radial_normal_vec, -(v_vec * radial_normal_vec), + t, + 1.e-06); + + // If there is an intersection, compute the value of the derivative ath that point. + if ((res == GeomUtils::DO_INTERSECT) && (t >= 0) && (t <= 1)) { + kr = t * opposite_vertex_a->curvatures()->Kr + (1 - t) * opposite_vertex_b->curvatures()->Kr; + inter = opposite_vertex_a->GetVertex() + t * opposite_edge_vec; + tmp_vec = inter - v->GetVertex(); + // Is it kr1 or kr2? + if (tmp_vec * er_vec > 0) { + kr2 = kr; + inter2 = inter; + } else { + kr1 = kr; + inter1 = inter; + } + } + } + + // Now we have kr1 and kr2 along the radial direction, for one vertex of iFace. + // We have to compute the derivative of kr for that vertex, equal to: + // (kr2 - kr1) / dist(inter1, inter2). + // Then we add it to the vector of derivatives. + v->curvatures()->dKr = (kr2 - kr1) / (inter2 - inter1).norm(); + kr_derivatives.push_back(v->curvatures()->dKr); + } + + // At that point, we have the derivatives for each vertex of iFace. + // All we have to do now is to use linear interpolation to compute the values at + // the extremities of the smooth edge. + WXSmoothEdge *sc_edge = sc_layer->getSmoothEdge(); + WOEdge *sc_oedge = sc_edge->woea(); + t = sc_edge->ta(); + if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] + + (1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon) { + sc_layer->removeSmoothEdge(); + return; + } + sc_oedge = sc_edge->woeb(); + t = sc_edge->tb(); + if (t * kr_derivatives[iFace->GetIndex(sc_oedge->GetaVertex())] + + (1 - t) * kr_derivatives[iFace->GetIndex(sc_oedge->GetbVertex())] < _kr_derivative_epsilon) + sc_layer->removeSmoothEdge(); +} + + +// Build Smooth edges +///////////////////// +void FEdgeXDetector::buildSmoothEdges(WXShape* iShape){ + // Make a last pass to build smooth edges from the previous stored values: + //-------------------------------------------------------------------------- + vector<WFace*>& wfaces = iShape->GetFaceList(); + for(vector<WFace*>::iterator f=wfaces.begin(), fend=wfaces.end(); + f!=fend; + ++f) + { + vector<WXFaceLayer*>& faceLayers = ((WXFace*)(*f))->getSmoothLayers(); + for(vector<WXFaceLayer*>::iterator wxfl = faceLayers.begin(), wxflend=faceLayers.end(); + wxfl!=wxflend; + ++wxfl){ + (*wxfl)->BuildSmoothEdge(); + } + } +} diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h new file mode 100755 index 00000000000..28034f3f42b --- /dev/null +++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h @@ -0,0 +1,153 @@ +// +// Filename : FEdgeXDetector.h +// Author(s) : Stephane Grabli +// Purpose : Detects/flags/builds extended features edges on the +// WXEdge structure +// Date of creation : 26/10/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + + +#ifndef FEDGEXDETECTOR_H +# define FEDGEXDETECTOR_H + +# include <vector> +# include "../system/FreestyleConfig.h" +# include "../geometry/Geom.h" +# include "../winged_edge/WXEdge.h" +# include "../winged_edge/Curvature.h" +# include "../system/ProgressBar.h" + +using namespace Geometry; + +/*! This class takes as input a WXEdge structure and fills it + */ + +class LIB_VIEW_MAP_EXPORT FEdgeXDetector +{ +public: + + FEdgeXDetector() { + _pProgressBar = 0; + _computeViewIndependant = true; + _bbox_diagonal = 1.0; + _meanEdgeSize = 0; + _computeRidgesAndValleys = true; + _computeSuggestiveContours = true; + _sphereRadius = 1.0; + _orthographicProjection = false; + _changes = false; + _kr_derivative_epsilon = 0.0; + } + virtual ~FEdgeXDetector() {} + + /*! Process shapes from a WingedEdge containing a list of WShapes */ + virtual void processShapes(WingedEdge&); + + // GENERAL STUFF + virtual void preProcessShape(WXShape* iShape); + virtual void preProcessFace(WXFace* iFace); + virtual void computeCurvatures(WXVertex *iVertex); + + // SILHOUETTE + virtual void processSilhouetteShape(WXShape* iShape); + virtual void ProcessSilhouetteFace(WXFace *iFace); + virtual void ProcessSilhouetteEdge(WXEdge *iEdge); + + // CREASE + virtual void processCreaseShape(WXShape* iShape); + virtual void ProcessCreaseEdge(WXEdge *iEdge); + + // BORDER + virtual void processBorderShape(WXShape* iShape); + virtual void ProcessBorderEdge(WXEdge *iEdge); + + // RIDGES AND VALLEYS + virtual void processRidgesAndValleysShape(WXShape* iShape); + virtual void ProcessRidgeFace(WXFace *iFace); + + // SUGGESTIVE CONTOURS + virtual void processSuggestiveContourShape(WXShape* iShape); + virtual void ProcessSuggestiveContourFace(WXFace *iFace); + virtual void postProcessSuggestiveContourShape(WXShape* iShape); + virtual void postProcessSuggestiveContourFace(WXFace *iFace); + /*! Sets the minimal derivative of the radial curvature for suggestive contours + * \param dkr + * The minimal derivative of the radial curvature + */ + inline void setSuggestiveContourKrDerivativeEpsilon(real dkr) { + if (dkr != _kr_derivative_epsilon){ + _kr_derivative_epsilon = dkr; + _changes = true; + } + } + + // EVERYBODY + virtual void buildSmoothEdges(WXShape* iShape); + + /*! Sets the current viewpoint */ + inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;} + inline void enableOrthographicProjection(bool b) {_orthographicProjection = b;} + inline void enableRidgesAndValleysFlag(bool b) {_computeRidgesAndValleys = b;} + inline void enableSuggestiveContours(bool b) {_computeSuggestiveContours = b;} + /*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation) + * \param r + * The radius of the sphere expressed as a ratio of the mean edge size + */ + inline void setSphereRadius(real r) { + if(r!=_sphereRadius){ + _sphereRadius = r; + _changes=true; + } + } + + inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;} + +protected: + + Vec3r _Viewpoint; + real _bbox_diagonal; // diagonal of the current processed shape bbox + //oldtmp values + bool _computeViewIndependant; + real _meanK1; + real _meanKr; + real _minK1; + real _minKr; + real _maxK1; + real _maxKr; + unsigned _nPoints; + real _meanEdgeSize; + bool _orthographicProjection; + + bool _computeRidgesAndValleys; + bool _computeSuggestiveContours; + real _sphereRadius; // expressed as a ratio of the mean edge size + bool _changes; + + real _kr_derivative_epsilon; + + ProgressBar *_pProgressBar; +}; + +#endif // FEDGEDXETECTOR_H diff --git a/source/blender/freestyle/intern/view_map/Functions0D.cpp b/source/blender/freestyle/intern/view_map/Functions0D.cpp new file mode 100755 index 00000000000..b28ac575d00 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/Functions0D.cpp @@ -0,0 +1,365 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +# include "Functions0D.h" +# include "ViewMap.h" + +using namespace std; + +namespace Functions0D { + + // Internal function + FEdge* getFEdge(Interface0D& it1, Interface0D& it2){ + return it1.getFEdge(it2); + } + + void getFEdges(Interface0DIterator& it, + FEdge*& fe1, + FEdge*& fe2) { + // count number of vertices + Interface0DIterator prev = it, next = it; + ++next; + int count = 1; + while((!prev.isBegin()) && (count < 3)) + { + --prev; + ++count; + } + while((!next.isEnd()) && (count < 3)) + { + ++next; + ++count; + } + if(count < 3) + { + // if we only have 2 vertices + FEdge * fe = 0; + Interface0DIterator tmp = it; + if(it.isBegin()) + { + ++tmp; + fe = it->getFEdge(*tmp); + } + else + { + --tmp; + fe = it->getFEdge(*tmp); + } + fe1 = fe; + fe2 = 0; + } + else + { + // we have more than 2 vertices + bool begin=false,last=false; + Interface0DIterator previous = it; + if(!previous.isBegin()) + --previous; + else + begin=true; + Interface0DIterator next = it; + ++next; + if(next.isEnd()) + last = true; + if(begin) + { + fe1 = it->getFEdge(*next); + fe2 = 0; + } + else if(last) + { + fe1 = previous->getFEdge(*it); + fe2 = 0; + } + else + { + fe1 = previous->getFEdge(*it); + fe2 = it->getFEdge(*next); + } + } + } + + void getViewEdges(Interface0DIterator &it, + ViewEdge *&ve1, + ViewEdge *&ve2) + { + FEdge * fe1, *fe2; + getFEdges(it, fe1, fe2); + ve1 = fe1->viewedge(); + if(fe2 != 0) + { + ve2 = fe2->viewedge(); + if(ve2 == ve1) + ve2 = 0; + } + else + ve2 = 0; + } + + ViewShape* getShapeF0D(Interface0DIterator& it) + { + ViewEdge *ve1, *ve2; + getViewEdges(it, ve1, ve2); + return ve1->viewShape(); + } + + void getOccludersF0D(Interface0DIterator& it, set<ViewShape*>& oOccluders){ + ViewEdge * ve1, *ve2; + getViewEdges(it, ve1, ve2); + occluder_container::const_iterator oit = ve1->occluders_begin(); + occluder_container::const_iterator oitend = ve1->occluders_end(); + + for(;oit!=oitend; ++oit) + oOccluders.insert((*oit)); + + if(ve2!=0){ + oit = ve2->occluders_begin(); + oitend = ve2->occluders_end(); + for(;oit!=oitend; ++oit) + oOccluders.insert((*oit)); + } + } + + ViewShape * getOccludeeF0D(Interface0DIterator& it){ + ViewEdge * ve1, *ve2; + getViewEdges(it, ve1, ve2); + ViewShape *aShape = ve1->aShape(); + return aShape; + } + + // + int VertexOrientation2DF0D::operator()(Interface0DIterator& iter) { + Vec2f A,C; + Vec2f B(iter->getProjectedX(), iter->getProjectedY()); + if(iter.isBegin()) + A = Vec2f(iter->getProjectedX(), iter->getProjectedY()); + else + { + Interface0DIterator previous = iter; + --previous ; + A = Vec2f(previous->getProjectedX(), previous->getProjectedY()); + } + Interface0DIterator next = iter; + ++next ; + if(next.isEnd()) + C = Vec2f(iter->getProjectedX(), iter->getProjectedY()); + else + C = Vec2f(next->getProjectedX(), next->getProjectedY()); + + Vec2f AB(B-A); + if(AB.norm() != 0) + AB.normalize(); + Vec2f BC(C-B); + if(BC.norm() != 0) + BC.normalize(); + result = AB + BC; + if(result.norm() != 0) + result.normalize(); + return 0; + } + + int VertexOrientation3DF0D::operator()(Interface0DIterator& iter) { + Vec3r A,C; + Vec3r B(iter->getX(), iter->getY(), iter->getZ()); + if(iter.isBegin()) + A = Vec3r(iter->getX(), iter->getY(), iter->getZ()); + else + { + Interface0DIterator previous = iter; + --previous ; + A = Vec3r(previous->getX(), previous->getY(), previous->getZ()); + } + Interface0DIterator next = iter; + ++next ; + if(next.isEnd()) + C = Vec3r(iter->getX(), iter->getY(), iter->getZ()); + else + C = Vec3r(next->getX(), next->getY(), next->getZ()); + + Vec3r AB(B-A); + if(AB.norm() != 0) + AB.normalize(); + Vec3r BC(C-B); + if(BC.norm() != 0) + BC.normalize(); + result = AB + BC; + if(result.norm() != 0) + result.normalize(); + return 0; + } + + int Curvature2DAngleF0D::operator()(Interface0DIterator& iter) { + Interface0DIterator tmp1 = iter, tmp2 = iter; + ++tmp2; + unsigned count = 1; + while((!tmp1.isBegin()) && (count < 3)) + { + --tmp1; + ++count; + } + while((!tmp2.isEnd()) && (count < 3)) + { + ++tmp2; + ++count; + } + if(count < 3) { + // if we only have 2 vertices + result = 0; + return 0; + } + + Interface0DIterator v = iter; + if(iter.isBegin()) + ++v; + Interface0DIterator next=v; + ++next; + if(next.isEnd()) + { + next = v; + --v; + } + Interface0DIterator prev=v; + --prev; + + Vec2r A(prev->getProjectedX(), prev->getProjectedY()); + Vec2r B(v->getProjectedX(), v->getProjectedY()); + Vec2r C(next->getProjectedX(), next->getProjectedY()); + Vec2r AB(B-A); + Vec2r BC(C-B); + Vec2r N1(-AB[1], AB[0]); + if(N1.norm() != 0) + N1.normalize(); + Vec2r N2(-BC[1], BC[0]); + if(N2.norm() != 0) + N2.normalize(); + if((N1.norm() == 0) && (N2.norm() == 0)) + { + Exception::raiseException(); + result = 0; + return -1; + } + double cosin = N1*N2; + if(cosin > 1) + cosin = 1; + if(cosin < -1) + cosin = -1; + result = acos(cosin); + return 0; + } + + int ZDiscontinuityF0D::operator()(Interface0DIterator& iter) { + FEdge *fe1, *fe2; + getFEdges(iter, fe1, fe2); + result = fe1->z_discontinuity(); + if(fe2!=0){ + result += fe2->z_discontinuity(); + result /= 2.f; + } + return 0; + } + + int Normal2DF0D::operator()(Interface0DIterator& iter) { + FEdge *fe1, *fe2; + getFEdges(iter,fe1,fe2); + Vec3f e1(fe1->orientation2d()); + Vec2f n1(e1[1], -e1[0]); + Vec2f n(n1); + if(fe2 != 0) + { + Vec3f e2(fe2->orientation2d()); + Vec2f n2(e2[1], -e2[0]); + n += n2; + } + n.normalize(); + result = n; + return 0; + } + + int MaterialF0D::operator()(Interface0DIterator& iter) { + FEdge *fe1, *fe2; + getFEdges(iter,fe1,fe2); + + if(fe1 == 0) + getFEdges(iter, fe1, fe2); + if(fe1->isSmooth()) + result = ((FEdgeSmooth*)fe1)->frs_material(); + else + result = ((FEdgeSharp*)fe1)->bFrsMaterial(); + // const SShape * sshape = getShapeF0D(iter); + // return sshape->material(); + return 0; + } + + int ShapeIdF0D::operator()(Interface0DIterator& iter) { + ViewShape * vshape = getShapeF0D(iter); + result = vshape->getId(); + return 0; + } + + int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter) { + ViewEdge * ve1, *ve2; + getViewEdges(iter,ve1,ve2); + unsigned int qi1, qi2; + qi1 = ve1->qi(); + if(ve2 != 0){ + qi2 = ve2->qi(); + if(qi2!=qi1) + cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl; + } + result = qi1; + return 0; + } + + int CurveNatureF0D::operator()(Interface0DIterator& iter) { + Nature::EdgeNature nat = 0; + ViewEdge * ve1, *ve2; + getViewEdges(iter, ve1, ve2); + nat |= ve1->getNature(); + if(ve2!=0) + nat |= ve2->getNature(); + result = nat; + return 0; + } + + int GetOccludersF0D::operator()(Interface0DIterator& iter) { + set<ViewShape*> occluders; + getOccludersF0D(iter,occluders); + result.clear(); + // vsOccluders.insert(vsOccluders.begin(), occluders.begin(), occluders.end()); + for(set<ViewShape*>::iterator it=occluders.begin(), itend=occluders.end(); + it!=itend; + ++it){ + result.push_back((*it)); + } + return 0; + } + + int GetShapeF0D::operator()(Interface0DIterator& iter) { + result = getShapeF0D(iter); + return 0; + } + + int GetOccludeeF0D::operator()(Interface0DIterator& iter) { + result = getOccludeeF0D(iter); + return 0; + } + +} // end of namespace Functions0D diff --git a/source/blender/freestyle/intern/view_map/Functions0D.h b/source/blender/freestyle/intern/view_map/Functions0D.h new file mode 100755 index 00000000000..4adbc8a1bf5 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/Functions0D.h @@ -0,0 +1,500 @@ +// +// Filename : Functions0D.h +// Author(s) : Stephane Grabli, Emmanuel Turquin +// Purpose : Functions taking 0D input +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef FUNCTIONS0D_H +# define FUNCTIONS0D_H + +# include "../system/Precision.h" +# include "Interface0D.h" +# include "../geometry/Geom.h" +# include "../system/Exception.h" +# include "../scene_graph/FrsMaterial.h" +# include <set> +# include <vector> +class FEdge; +class ViewEdge; +class SShape; + +using namespace Geometry; + +#include "../python/Director.h" + +// +// UnaryFunction0D (base class for functions in 0D) +// +/////////////////////////////////////////////////////////// + +template <class T> +/*! Base class for Unary Functions (functors) working + * on Interface0DIterator. + * A unary function will be used by calling + * its operator() on an Interface0DIterator. + * \attention In the scripting language, there exists + * several prototypes depending on the returned value type. + * For example, you would inherit from a UnaryFunction0DDouble + * if you wish to define a function that returns a double. + * The different existing prototypes are: + * - UnaryFunction0DVoid + * - UnaryFunction0DUnsigned + * - UnaryFunction0DReal + * - UnaryFunction0DFloat + * - UnaryFunction0DDouble + * - UnaryFunction0DVec2f + * - UnaryFunction0DVec3f + */ +class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction0D +{ +public: + + T result; + PyObject *py_uf0D; + + /*! The type of the value + * returned by the functor. + */ + typedef T ReturnedValueType; + /*! Default constructor. */ +UnaryFunction0D() { py_uf0D = 0;} + /*! Destructor; */ + virtual ~UnaryFunction0D() {} + /*! Returns the string "UnaryFunction0D" */ + virtual string getName() const { + return "UnaryFunction0D"; + } + /*! The operator (). + * \param iter + * An Interface0DIterator pointing onto + * the point at which we wish to evaluate + * the function. + * \return the result of the function of type T. + */ + virtual int operator()(Interface0DIterator& iter) { + return Director_BPy_UnaryFunction0D___call__( this, py_uf0D, iter ); + } + +}; + +# ifdef SWIG +%feature("director") UnaryFunction0D<void>; +%feature("director") UnaryFunction0D<unsigned>; +%feature("director") UnaryFunction0D<float>; +%feature("director") UnaryFunction0D<double>; +%feature("director") UnaryFunction0D<Vec2f>; +%feature("director") UnaryFunction0D<Vec3f>; +%feature("director") UnaryFunction0D<Id>; + +%template(UnaryFunction0DVoid) UnaryFunction0D<void>; +%template(UnaryFunction0DUnsigned) UnaryFunction0D<unsigned>; +%template(UnaryFunction0DFloat) UnaryFunction0D<float>; +%template(UnaryFunction0DDouble) UnaryFunction0D<double>; +%template(UnaryFunction0DVec2f) UnaryFunction0D<Vec2f>; +%template(UnaryFunction0DVec3f) UnaryFunction0D<Vec3f>; +%template(UnaryFunction0DId) UnaryFunction0D<Id>; +%template(UnaryFunction0DViewShape) UnaryFunction0D<ViewShape*>; +%template(UnaryFunction0DVectorViewShape) UnaryFunction0D<std::vector<ViewShape*> >; +# endif // SWIG + + +// +// Functions definitions +// +/////////////////////////////////////////////////////////// +class ViewShape; +namespace Functions0D { + + // GetXF0D + /*! Returns the X 3D coordinate of an Interface0D. */ + class LIB_VIEW_MAP_EXPORT GetXF0D : public UnaryFunction0D<real> + { + public: + /*! Returns the string "GetXF0D"*/ + string getName() const { + return "GetXF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter) { + result = iter->getX(); + return 0; + } + }; + + // GetYF0D + /*! Returns the Y 3D coordinate of an Interface0D. */ + class LIB_VIEW_MAP_EXPORT GetYF0D : public UnaryFunction0D<real> + { + public: + /*! Returns the string "GetYF0D"*/ + string getName() const { + return "GetYF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter) { + result = iter->getY(); + return 0; + } + }; + + // GetZF0D + /*! Returns the Z 3D coordinate of an Interface0D. */ + class LIB_VIEW_MAP_EXPORT GetZF0D : public UnaryFunction0D<real> + { + public: + /*! Returns the string "GetZF0D"*/ + string getName() const { + return "GetZF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter) { + result = iter->getZ(); + return 0; + } + }; + + // GetProjectedXF0D + /*! Returns the X 3D projected coordinate of an Interface0D. */ + class LIB_VIEW_MAP_EXPORT GetProjectedXF0D : public UnaryFunction0D<real> + { + public: + /*! Returns the string "GetProjectedXF0D"*/ + string getName() const { + return "GetProjectedXF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter) { + result = iter->getProjectedX(); + return 0; + } + }; + + // GetProjectedYF0D + /*! Returns the Y projected 3D coordinate of an Interface0D. */ + class LIB_VIEW_MAP_EXPORT GetProjectedYF0D : public UnaryFunction0D<real> + { + public: + /*! Returns the string "GetProjectedYF0D"*/ + string getName() const { + return "GetProjectedYF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter) { + result = iter->getProjectedY(); + return 0; + } + }; + + // GetProjectedZF0D + /*! Returns the Z projected 3D coordinate of an Interface0D. */ + class LIB_VIEW_MAP_EXPORT GetProjectedZF0D : public UnaryFunction0D<real> + { + public: + /*! Returns the string "GetProjectedZF0D"*/ + string getName() const { + return "GetProjectedZF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter) { + result = iter->getProjectedZ(); + return 0; + } + }; + + // GetCurvilinearAbscissaF0D + /*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */ + class LIB_VIEW_MAP_EXPORT GetCurvilinearAbscissaF0D : public UnaryFunction0D<float> + { + public: + /*! Returns the string "GetCurvilinearAbscissaF0D"*/ + string getName() const { + return "GetCurvilinearAbscissaF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter) { + result = iter.t(); + return 0; + } + }; + + // GetParameterF0D + /*! Returns the parameter of an Interface0D in the context of its 1D element. */ + class LIB_VIEW_MAP_EXPORT GetParameterF0D : public UnaryFunction0D<float> + { + public: + /*! Returns the string "GetCurvilinearAbscissaF0D"*/ + string getName() const { + return "GetParameterF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter) { + result = iter.u(); + return 0; + } + }; + + // VertexOrientation2DF0D + /*! Returns a Vec2r giving the 2D oriented tangent to the 1D element + * to which the Interface0DIterator& belongs to and + * evaluated at the Interface0D pointed by this Interface0DIterator&. + */ + class LIB_VIEW_MAP_EXPORT VertexOrientation2DF0D : public UnaryFunction0D<Vec2f> + { + public: + /*! Returns the string "VertexOrientation2DF0D"*/ + string getName() const { + return "VertexOrientation2DF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // VertexOrientation3DF0D + /*! Returns a Vec3r giving the 3D oriented tangent to the 1D element + * to which the Interface0DIterator& belongs to and + * evaluated at the Interface0D pointed by this Interface0DIterator&. + */ + class LIB_VIEW_MAP_EXPORT VertexOrientation3DF0D : public UnaryFunction0D<Vec3f> + { + public: + /*! Returns the string "VertexOrientation3DF0D"*/ + string getName() const { + return "VertexOrientation3DF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // Curvature2DAngleF0D + /*! Returns a real giving the 2D curvature (as an angle) of the 1D element + * to which the Interface0DIterator& belongs to and + * evaluated at the Interface0D pointed by this Interface0DIterator&. + */ + class LIB_VIEW_MAP_EXPORT Curvature2DAngleF0D : public UnaryFunction0D<real> + { + public: + /*! Returns the string "Curvature2DAngleF0D"*/ + string getName() const { + return "Curvature2DAngleF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // ZDiscontinuity + /*! Returns a real giving the distance between + * and Interface0D and the shape that lies behind (occludee). + * This distance is evaluated in the camera space and normalized + * between 0 and 1. Therefore, if no oject is occluded by the + * shape to which the Interface0D belongs to, 1 is returned. + */ + class LIB_VIEW_MAP_EXPORT ZDiscontinuityF0D : public UnaryFunction0D<real> + { + public: + /*! Returns the string "ZDiscontinuityF0D"*/ + string getName() const { + return "ZDiscontinuityF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // Normal2DF0D + /*! Returns a Vec2f giving the normalized 2D normal to the 1D element + * to which the Interface0DIterator& belongs to and + * evaluated at the Interface0D pointed by this Interface0DIterator&. + */ + class LIB_VIEW_MAP_EXPORT Normal2DF0D : public UnaryFunction0D<Vec2f> + { + public: + /*! Returns the string "Normal2DF0D"*/ + string getName() const { + return "Normal2DF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // MaterialF0D + /*! Returns the material of the object evaluated at the Interface0D. + * This evaluation can be ambiguous (in the case of a TVertex for example. + * This functor tries to remove this ambiguity using the context + * offered by the 1D element to which the Interface0DIterator& belongs + * to and by arbitrary chosing the material of the face + * that lies on its left when following the 1D element if there + * are two different materials on each side of the point. + * However, there still can be problematic cases, and the user willing + * to deal with this cases in a specific way should implement + * its own getMaterial functor. + */ + class LIB_VIEW_MAP_EXPORT MaterialF0D : public UnaryFunction0D<FrsMaterial> + { + public: + /*! Returns the string "MaterialF0D"*/ + string getName() const { + return "MaterialF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // ShapeIdF0D + /*! Returns the Id of the Shape the Interface0D belongs to. + * This evaluation can be ambiguous (in the case of a TVertex for example). + * This functor tries to remove this ambiguity using the context + * offered by the 1D element to which the Interface0DIterator& belongs + * to. + * However, there still can be problematic cases, and the user willing + * to deal with this cases in a specific way should implement + * its own getShapeIdF0D functor. + */ + class LIB_VIEW_MAP_EXPORT ShapeIdF0D : public UnaryFunction0D<Id> + { + public: + /*! Returns the string "ShapeIdF0D"*/ + string getName() const { + return "ShapeIdF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // QiF0D + /*! Returns the quantitative invisibility of this Interface0D. + * This evaluation can be ambiguous (in the case of a TVertex for example). + * This functor tries to remove this ambiguity using the context + * offered by the 1D element to which the Interface0DIterator& belongs + * to. + * However, there still can be problematic cases, and the user willing + * to deal with this cases in a specific way should implement + * its own getQIF0D functor. + */ + class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int> + { + public: + /*! Returns the string "QuantitativeInvisibilityF0D"*/ + string getName() const { + return "QuantitativeInvisibilityF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // CurveNatureF0D + /*! Returns the Nature::EdgeNature of the 1D element the + * Interface0DIterator& belongs to. + */ + class LIB_VIEW_MAP_EXPORT CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature> + { + public: + /*! Returns the string "QuantitativeInvisibilityF0D"*/ + string getName() const { + return "CurveNatureF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // GetShapeF0D + /*! Returns the ViewShape* + * containing the Interface0D + */ + class LIB_VIEW_MAP_EXPORT GetShapeF0D : public UnaryFunction0D< ViewShape*> + { + public: + /*! Returns the string "GetShapeF0D"*/ + string getName() const { + return "GetShapeF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // GetOccludersF0D + /*! Returns a vector containing the ViewShape* + * occluding the Interface0D + */ + class LIB_VIEW_MAP_EXPORT GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> > + { + public: + /*! Returns the string "GetOccludersF0D"*/ + string getName() const { + return "GetOccludersF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + // GetOccludeeF0D + /*! Returns the ViewShape* + * "occluded" by the Interface0D + */ + class LIB_VIEW_MAP_EXPORT GetOccludeeF0D: public UnaryFunction0D< ViewShape*> + { + public: + /*! Returns the string "GetOccludeeF0D"*/ + string getName() const { + return "GetOccludeeF0D"; + } + /*! the () operator.*/ + int operator()(Interface0DIterator& iter); + }; + + + + /////////////////////////// Internal //////////////////////////// + + // getFEdge + LIB_VIEW_MAP_EXPORT + FEdge* getFEdge(Interface0D& it1, Interface0D& it2); + + // getFEdges + LIB_VIEW_MAP_EXPORT + void getFEdges(Interface0DIterator& it, + FEdge*& fe1, + FEdge*& fe2); + + // getViewEdges + LIB_VIEW_MAP_EXPORT + void getViewEdges(Interface0DIterator& it, + ViewEdge *&ve1, + ViewEdge *&ve2); + + // getShapeF0D + LIB_VIEW_MAP_EXPORT + ViewShape* getShapeF0D(Interface0DIterator& it); + + // getOccludersF0D + LIB_VIEW_MAP_EXPORT + void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders); + + // getOccludeeF0D + LIB_VIEW_MAP_EXPORT + ViewShape* getOccludeeF0D(Interface0DIterator& it); + +} // end of namespace Functions0D + +#endif // FUNCTIONS0D_H diff --git a/source/blender/freestyle/intern/view_map/Functions1D.cpp b/source/blender/freestyle/intern/view_map/Functions1D.cpp new file mode 100755 index 00000000000..8545c660084 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/Functions1D.cpp @@ -0,0 +1,231 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +# include "Functions1D.h" +using namespace std; + +namespace Functions1D { + + int GetXF1D::operator()(Interface1D& inter) { + result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + + int GetYF1D::operator()(Interface1D& inter) { + result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + + int GetZF1D::operator()(Interface1D& inter) { + result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + + int GetProjectedXF1D::operator()(Interface1D& inter) { + result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + + int GetProjectedYF1D::operator()(Interface1D& inter) { + result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + + int GetProjectedZF1D::operator()(Interface1D& inter) { + result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + + int Orientation2DF1D::operator()(Interface1D& inter) { + FEdge * fe = dynamic_cast<FEdge*>(&inter); + if(fe){ + Vec3r res = fe->orientation2d(); + result = Vec2f(res[0], res[1]); + } else { + result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); + } + return 0; + } + + int Orientation3DF1D::operator()(Interface1D& inter) { + result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + + int ZDiscontinuityF1D::operator()(Interface1D& inter) { + result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + + int QuantitativeInvisibilityF1D::operator()(Interface1D& inter) { + ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); + if (ve) { + result = ve->qi(); + return 0; + } + FEdge *fe = dynamic_cast<FEdge*>(&inter); + if (fe) { + result = ve->qi(); + return 0; + } + result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + + int CurveNatureF1D::operator()(Interface1D& inter) { + ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); + if (ve) + result = ve->getNature(); + else{ + // we return a nature that contains every + // natures of the viewedges spanned by the chain. + Nature::EdgeNature nat = Nature::NO_FEATURE; + Interface0DIterator it = inter.verticesBegin(); + while(!it.isEnd()){ + nat |= _func(it); + ++it; + } + result = nat; + } + return 0; + } + + int TimeStampF1D::operator()(Interface1D& inter) { + TimeStamp *timestamp = TimeStamp::instance(); + inter.setTimeStamp(timestamp->getTimeStamp()); + return 0; + } + + int ChainingTimeStampF1D::operator()(Interface1D& inter) { + TimeStamp *timestamp = TimeStamp::instance(); + ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); + if(ve) + ve->setChainingTimeStamp(timestamp->getTimeStamp()); + return 0; + } + + int IncrementChainingTimeStampF1D::operator()(Interface1D& inter) { + ViewEdge *ve = dynamic_cast<ViewEdge*>(&inter); + if(ve) + ve->setChainingTimeStamp(ve->getChainingTimeStamp()+1); + return 0; + } + + int GetShapeF1D::operator()(Interface1D& inter) { + vector<ViewShape*> shapesVector; + set<ViewShape*> shapesSet; + ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); + if (ve){ + shapesVector.push_back(ve->viewShape()); + }else{ + Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd(); + for(;it!=itend;++it) + shapesSet.insert(Functions0D::getShapeF0D(it)); + shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end()); + } + result = shapesVector; + return 0; + } + + int GetOccludersF1D::operator()(Interface1D& inter) { + vector<ViewShape*> shapesVector; + set<ViewShape*> shapesSet; + ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); + if (ve){ + result = ve->occluders(); + }else{ + Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd(); + for(;it!=itend;++it){ + Functions0D::getOccludersF0D(it, shapesSet); + } + shapesVector.insert(shapesVector.begin(), shapesSet.begin(), shapesSet.end()); + result = shapesVector; + } + return 0; + } + + int GetOccludeeF1D::operator()(Interface1D& inter) { + vector<ViewShape*> shapesVector; + set<ViewShape*> shapesSet; + ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); + if (ve){ + ViewShape * aShape = ve->aShape(); + shapesVector.push_back(aShape); + }else{ + Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd(); + for(;it!=itend;++it){ + shapesSet.insert(Functions0D::getOccludeeF0D(it)); + } + shapesVector.insert<set<ViewShape*>::iterator>(shapesVector.begin(), shapesSet.begin(), shapesSet.end()); + } + result = shapesVector; + return 0; + } + // Internal + //////////// + + void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes){ + ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); + if (ve){ + ViewShape * aShape = ve->aShape(); + if(aShape == 0){ + oShapes.insert(0); + return; + } + oShapes.insert(aShape); + } + else{ + Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd(); + for(;it!=itend;++it) + oShapes.insert(Functions0D::getOccludeeF0D(it)); + } + } + + void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes){ + ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); + if (ve){ + vector<ViewShape*>& occluders = ve->occluders(); + oShapes.insert<vector<ViewShape*>::iterator>(occluders.begin(), occluders.end()); + } + else{ + Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd(); + for(;it!=itend;++it){ + set<ViewShape*> shapes; + Functions0D::getOccludersF0D(it, shapes); + for(set<ViewShape*>::iterator s=shapes.begin(), send=shapes.end(); + s!=send; + ++s) + oShapes.insert(*s); + } + } + } + + void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes){ + ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); + if (ve){ + oShapes.insert(ve->viewShape()); + }else{ + Interface0DIterator it=inter.verticesBegin(), itend=inter.verticesEnd(); + for(;it!=itend;++it) + oShapes.insert(Functions0D::getShapeF0D(it)); + } + } +} // end of namespace Functions1D diff --git a/source/blender/freestyle/intern/view_map/Functions1D.h b/source/blender/freestyle/intern/view_map/Functions1D.h new file mode 100755 index 00000000000..c4060e0897f --- /dev/null +++ b/source/blender/freestyle/intern/view_map/Functions1D.h @@ -0,0 +1,555 @@ +// +// Filename : Functions1D.h +// Author(s) : Stephane Grabli, Emmanuel Turquin +// Purpose : Functions taking 1D input +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef FUNCTIONS1D_HPP +# define FUNCTIONS1D_HPP + +# include "../system/Precision.h" +# include "../system/TimeStamp.h" +# include "ViewMap.h" +# include "Functions0D.h" +# include "Interface1D.h" +# include "../system/FreestyleConfig.h" + +#include "../python/Director.h" + +// +// UnaryFunction1D (base class for functions in 1D) +// +/////////////////////////////////////////////////////////// + +/*! Base class for Unary Functions (functors) working + * on Interface1D. + * A unary function will be used by calling + * its operator() on an Interface1D. + * \attention In the scripting language, there exists + * several prototypes depending on the returned value type. + * For example, you would inherit from a UnaryFunction1DDouble + * if you wish to define a function that returns a double. + * The different existing prototypes are: + * - UnaryFunction1DVoid + * - UnaryFunction1DUnsigned + * - UnaryFunction1DReal + * - UnaryFunction1DFloat + * - UnaryFunction1DDouble + * - UnaryFunction1DVec2f + * - UnaryFunction1DVec3f + */ +template <class T> +class /*LIB_VIEW_MAP_EXPORT*/ UnaryFunction1D +{ +public: + + T result; + PyObject *py_uf1D; + + /*! The type of the value + * returned by the functor. + */ + typedef T ReturnedValueType; + + /*! Default constructor */ + UnaryFunction1D(){_integration = MEAN;} + /*! Builds a UnaryFunction1D from an integration type. + * \param iType + * In case the result for the Interface1D would be + * obtained by evaluating a 0D function over the different + * Interface0D of the Interface1D, \a iType tells which + * integration method to use. + * The default integration method is the MEAN. + */ + UnaryFunction1D(IntegrationType iType){_integration = iType;} + /*! destructor. */ + virtual ~UnaryFunction1D() {} + + /*! returns the string "UnaryFunction1D". */ + virtual string getName() const { + return "UnaryFunction1D"; + } + /*! The operator (). + * \param inter + * The Interface1D on which we wish to evaluate + * the function. + * \return the result of the function of type T. + */ + virtual int operator()(Interface1D& inter) { + return Director_BPy_UnaryFunction1D___call__( this, py_uf1D, inter ); + } + + /*! Sets the integration method */ + void setIntegrationType(IntegrationType integration) { + _integration = integration; + } + /*! Returns the integration method. */ + IntegrationType getIntegrationType() const { + return _integration; + } + +protected: + + IntegrationType _integration; +}; + + +class UnaryFunction1D_void +{ +public: + + PyObject *py_uf1D; + + UnaryFunction1D_void(){_integration = MEAN;} + UnaryFunction1D_void(IntegrationType iType){_integration = iType;} + virtual ~UnaryFunction1D_void() {} + + virtual string getName() const { + return "UnaryFunction1D_void"; + } + + int operator()(Interface1D& inter) { + return Director_BPy_UnaryFunction1D___call__( this, py_uf1D, inter ); + } + + void setIntegrationType(IntegrationType integration) { _integration = integration; } + IntegrationType getIntegrationType() const { return _integration; } + + protected: + IntegrationType _integration; +}; + + +// +// Functions definitions +// +/////////////////////////////////////////////////////////// + +namespace Functions1D { + + // GetXF1D + /*! Returns the X 3D coordinate of an Interface1D. */ + class LIB_VIEW_MAP_EXPORT GetXF1D : public UnaryFunction1D<real> + { + private: + Functions0D::GetXF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + GetXF1D(IntegrationType iType) : UnaryFunction1D<real>(iType){} + /*! Returns the string "GetXF1D"*/ + string getName() const { + return "GetXF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter) ; + }; + + // GetYF1D + /*! Returns the Y 3D coordinate of an Interface1D. */ + class LIB_VIEW_MAP_EXPORT GetYF1D : public UnaryFunction1D<real> + { + private: + Functions0D::GetYF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + GetYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){} + /*! Returns the string "GetYF1D"*/ + string getName() const { + return "GetYF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter) ; + }; + + // GetZF1D + /*! Returns the Z 3D coordinate of an Interface1D. */ + class LIB_VIEW_MAP_EXPORT GetZF1D : public UnaryFunction1D<real> + { + private: + Functions0D::GetZF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + GetZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){} + /*! Returns the string "GetZF1D"*/ + string getName() const { + return "GetZF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter) ; + }; + + // GetProjectedXF1D + /*! Returns the projected X 3D coordinate of an Interface1D. */ + class LIB_VIEW_MAP_EXPORT GetProjectedXF1D : public UnaryFunction1D<real> + { + private: + Functions0D::GetProjectedXF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + GetProjectedXF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){} + public: + /*! Returns the string "GetProjectedXF1D"*/ + string getName() const { + return "GetProjectedXF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // GetProjectedYF1D + /*! Returns the projected Y 3D coordinate of an Interface1D. */ + class LIB_VIEW_MAP_EXPORT GetProjectedYF1D : public UnaryFunction1D<real> + { + private: + Functions0D::GetProjectedYF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + GetProjectedYF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){} + public: + /*! Returns the string "GetProjectedYF1D"*/ + string getName() const { + return "GetProjectedYF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // GetProjectedZF1D + /*! Returns the projected Z 3D coordinate of an Interface1D. */ + class LIB_VIEW_MAP_EXPORT GetProjectedZF1D : public UnaryFunction1D<real> + { + private: + Functions0D::GetProjectedZF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + GetProjectedZF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){} + public: + /*! Returns the string "GetProjectedZF1D"*/ + string getName() const { + return "GetProjectedZF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // Orientation2DF1D + /*! Returns the 2D orientation as a Vec2f*/ + class LIB_VIEW_MAP_EXPORT Orientation2DF1D : public UnaryFunction1D<Vec2f> + { + private: + Functions0D::VertexOrientation2DF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + Orientation2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType){} + /*! Returns the string "Orientation2DF1D"*/ + string getName() const { + return "Orientation2DF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // Orientation3DF1D + /*! Returns the 3D orientation as a Vec3f. */ + class LIB_VIEW_MAP_EXPORT Orientation3DF1D : public UnaryFunction1D<Vec3f> + { + private: + Functions0D::VertexOrientation3DF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + Orientation3DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec3f>(iType){} + /*! Returns the string "Orientation3DF1D"*/ + string getName() const { + return "Orientation3DF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // ZDiscontinuityF1D + /*! Returns a real giving the distance between + * and Interface1D and the shape that lies behind (occludee). + * This distance is evaluated in the camera space and normalized + * between 0 and 1. Therefore, if no oject is occluded by the + * shape to which the Interface1D belongs to, 1 is returned. + */ + class LIB_VIEW_MAP_EXPORT ZDiscontinuityF1D : public UnaryFunction1D<real> + { + private: + Functions0D::ZDiscontinuityF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + ZDiscontinuityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType){} + /*! Returns the string "ZDiscontinuityF1D"*/ + string getName() const { + return "ZDiscontinuityF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // QuantitativeInvisibilityF1D + /*! Returns the Quantitative Invisibility of an Interface1D element. + * If the Interface1D is a ViewEdge, then there is no ambiguity + * concerning the result. But, if the Interface1D results of a chaining + * (chain, stroke), then it might be made of several 1D elements + * of different Quantitative Invisibilities. + */ + class LIB_VIEW_MAP_EXPORT QuantitativeInvisibilityF1D : public UnaryFunction1D<unsigned> + { + private: + Functions0D::QuantitativeInvisibilityF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + QuantitativeInvisibilityF1D(IntegrationType iType = MEAN) : UnaryFunction1D<unsigned int>(iType) {} + /*! Returns the string "QuantitativeInvisibilityF1D"*/ + string getName() const { + return "QuantitativeInvisibilityF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // CurveNatureF1D +/*! Returns the nature of the Interface1D (silhouette, ridge, crease...). + * Except if the Interface1D is a ViewEdge, this result might be ambiguous. + * Indeed, the Interface1D might result from the gathering of several 1D elements, + * each one being of a different nature. An integration method, such as + * the MEAN, might give, in this case, irrelevant results. + */ + class LIB_VIEW_MAP_EXPORT CurveNatureF1D : public UnaryFunction1D<Nature::EdgeNature> + { + private: + Functions0D::CurveNatureF0D _func; + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + CurveNatureF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Nature::EdgeNature>(iType) {} + /*! Returns the string "CurveNatureF1D"*/ + string getName() const { + return "CurveNatureF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // TimeStampF1D +/*! Returns the time stamp of the Interface1D. */ + class LIB_VIEW_MAP_EXPORT TimeStampF1D : public UnaryFunction1D_void + { + public: + /*! Returns the string "TimeStampF1D"*/ + string getName() const { + return "TimeStampF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // IncrementChainingTimeStampF1D +/*! Increments the chaining time stamp of the Interface1D. */ + class LIB_VIEW_MAP_EXPORT IncrementChainingTimeStampF1D : public UnaryFunction1D_void + { + public: + /*! Returns the string "IncrementChainingTimeStampF1D"*/ + string getName() const { + return "IncrementChainingTimeStampF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // ChainingTimeStampF1D +/*! Sets the chaining time stamp of the Interface1D. */ + class LIB_VIEW_MAP_EXPORT ChainingTimeStampF1D : public UnaryFunction1D_void + { + public: + /*! Returns the string "ChainingTimeStampF1D"*/ + string getName() const { + return "ChainingTimeStampF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + + // Curvature2DAngleF1D +/*! Returns the 2D curvature as an angle for an Interface1D. */ + class LIB_VIEW_MAP_EXPORT Curvature2DAngleF1D : public UnaryFunction1D<real> + { + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + Curvature2DAngleF1D(IntegrationType iType = MEAN) : UnaryFunction1D<real>(iType) {} + /*! Returns the string "Curvature2DAngleF1D"*/ + string getName() const { + return "Curvature2DAngleF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter) { + result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + private: + Functions0D::Curvature2DAngleF0D _fun; + }; + + // Normal2DF1D + /*! Returns the 2D normal for an interface 1D. */ + class LIB_VIEW_MAP_EXPORT Normal2DF1D : public UnaryFunction1D<Vec2f> + { + public: + /*! Builds the functor. + * \param iType + * The integration method used to compute + * a single value from a set of values. + */ + Normal2DF1D(IntegrationType iType = MEAN) : UnaryFunction1D<Vec2f>(iType) {} + /*! Returns the string "Normal2DF1D"*/ + string getName() const { + return "Normal2DF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter) { + result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + private: + Functions0D::Normal2DF0D _fun; + }; + + // GetShapeF1D + /*! Returns list of shapes covered by this Interface1D. */ + class LIB_VIEW_MAP_EXPORT GetShapeF1D : public UnaryFunction1D<std::vector<ViewShape*> > + { + public: + /*! Builds the functor. + */ + GetShapeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {} + /*! Returns the string "GetShapeF1D"*/ + string getName() const { + return "GetShapeF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // GetOccludersF1D + /*! Returns list of occluding shapes covered by this Interface1D. */ + class LIB_VIEW_MAP_EXPORT GetOccludersF1D : public UnaryFunction1D<std::vector<ViewShape*> > + { + public: + /*! Builds the functor. + */ + GetOccludersF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {} + /*! Returns the string "GetOccludersF1D"*/ + string getName() const { + return "GetOccludersF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // GetOccludeeF1D + /*! Returns list of occluded shapes covered by this Interface1D. */ + class LIB_VIEW_MAP_EXPORT GetOccludeeF1D : public UnaryFunction1D<std::vector<ViewShape*> > + { + public: + /*! Builds the functor. + */ + GetOccludeeF1D() : UnaryFunction1D<std::vector<ViewShape*> >() {} + /*! Returns the string "GetOccludeeF1D"*/ + string getName() const { + return "GetOccludeeF1D"; + } + /*! the () operator.*/ + int operator()(Interface1D& inter); + }; + + // internal + //////////// + + // getOccludeeF1D + LIB_VIEW_MAP_EXPORT + void getOccludeeF1D(Interface1D& inter, set<ViewShape*>& oShapes); + + // getOccludersF1D + LIB_VIEW_MAP_EXPORT + void getOccludersF1D(Interface1D& inter, set<ViewShape*>& oShapes); + + // getShapeF1D + LIB_VIEW_MAP_EXPORT + void getShapeF1D(Interface1D& inter, set<ViewShape*>& oShapes); + +} // end of namespace Functions1D + +#endif // FUNCTIONS1D_HPP diff --git a/source/blender/freestyle/intern/view_map/Interface0D.h b/source/blender/freestyle/intern/view_map/Interface0D.h new file mode 100755 index 00000000000..5108524cdd3 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/Interface0D.h @@ -0,0 +1,369 @@ +// +// Filename : Interface0D.h +// Author(s) : Emmanuel Turquin +// Purpose : Interface to 0D elts +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef INTERFACE0D_H +# define INTERFACE0D_H + +# include <string> +# include <iostream> +# include "../system/Id.h" +# include "../system/Precision.h" +# include "../winged_edge/Nature.h" +# include "../geometry/Geom.h" +using namespace std; + +#include "../system/Iterator.h" //soc + +#ifdef __cplusplus +extern "C" { +#endif + +#include <Python.h> + +#ifdef __cplusplus +} +#endif + +// +// Interface0D +// +////////////////////////////////////////////////// + +class FEdge; +class SVertex; +class ViewVertex; +class NonTVertex; +class TVertex; +/*! Base class for any 0D element. */ +class Interface0D +{ +public: + + /*! Default constructor */ + Interface0D() {} + virtual ~Interface0D() {}; //soc + + /*! Returns the string "Interface0D".*/ + virtual string getExactTypeName() const { + return "Interface0D"; + } + + // Data access methods + + /*! Returns the 3D x coordinate of the point. */ + virtual real getX() const { + PyErr_SetString(PyExc_TypeError, "method getX() not properly overridden"); + return 0; + } + + /*! Returns the 3D y coordinate of the point. */ + virtual real getY() const { + PyErr_SetString(PyExc_TypeError, "method getY() not properly overridden"); + return 0; + } + + /*! Returns the 3D z coordinate of the point. */ + virtual real getZ() const { + PyErr_SetString(PyExc_TypeError, "method getZ() not properly overridden"); + return 0; + } + + /*! Returns the 3D point. */ + virtual Geometry::Vec3f getPoint3D() const { + PyErr_SetString(PyExc_TypeError, "method getPoint3D() not properly overridden"); + return 0; + } + + /*! Returns the 2D x coordinate of the point. */ + virtual real getProjectedX() const { + PyErr_SetString(PyExc_TypeError, "method getProjectedX() not properly overridden"); + return 0; + } + + /*! Returns the 2D y coordinate of the point. */ + virtual real getProjectedY() const { + PyErr_SetString(PyExc_TypeError, "method getProjectedY() not properly overridden"); + return 0; + } + + /*! Returns the 2D z coordinate of the point. */ + virtual real getProjectedZ() const { + PyErr_SetString(PyExc_TypeError, "method getProjectedZ() not properly overridden"); + return 0; + } + + /*! Returns the 2D point. */ + virtual Geometry::Vec2f getPoint2D() const { + PyErr_SetString(PyExc_TypeError, "method getPoint2D() not properly overridden"); + return 0; + } + + /*! Returns the FEdge that lies between this Interface0D and the + * Interface0D given as argument. */ + virtual FEdge* getFEdge(Interface0D&) { + PyErr_SetString(PyExc_TypeError, "method getFEdge() not properly overridden"); + return 0; + } + + /*! Returns the Id of the point. */ + virtual Id getId() const { + PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden"); + return 0; + } + + /*! Returns the nature of the point. */ + virtual Nature::VertexNature getNature() const { + PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden"); + return Nature::POINT; + } + + + /*! Cast the Interface0D in SVertex if it can be. */ + virtual SVertex * castToSVertex(){ + PyErr_SetString(PyExc_TypeError, "method castToSVertex() not properly overridden"); + return 0; + } + + /*! Cast the Interface0D in ViewVertex if it can be. */ + virtual ViewVertex * castToViewVertex(){ + PyErr_SetString(PyExc_TypeError, "method castToViewVertex() not properly overridden"); + return 0; + } + + /*! Cast the Interface0D in NonTVertex if it can be. */ + virtual NonTVertex * castToNonTVertex(){ + PyErr_SetString(PyExc_TypeError, "method castToNonTVertex() not properly overridden"); + return 0; + } + + /*! Cast the Interface0D in TVertex if it can be. */ + virtual TVertex * castToTVertex(){ + PyErr_SetString(PyExc_TypeError, "method castToTVertex() not properly overridden"); + return 0; + } + +}; + + +// +// Interface0DIteratorNested +// +////////////////////////////////////////////////// + +class Interface0DIteratorNested : public Iterator +{ +public: + + virtual ~Interface0DIteratorNested() {} + + virtual string getExactTypeName() const { + return "Interface0DIteratorNested"; + } + + virtual Interface0D& operator*() = 0; + + virtual Interface0D* operator->() { + return &(operator*()); + } + + virtual int increment() = 0; + + virtual int decrement() = 0; + + virtual bool isBegin() const = 0; + + virtual bool isEnd() const = 0; + + virtual bool operator==(const Interface0DIteratorNested& it) const = 0; + + virtual bool operator!=(const Interface0DIteratorNested& it) const { + return !(*this == it); + } + + /*! Returns the curvilinear abscissa */ + virtual float t() const = 0; + /*! Returns the point parameter 0<u<1 */ + virtual float u() const = 0; + + virtual Interface0DIteratorNested* copy() const = 0; +}; + + +// +// Interface0DIterator +// +////////////////////////////////////////////////// + +/*! Class defining an iterator over Interface0D elements. + * An instance of this iterator is always obtained + * from a 1D element. + * \attention In the scripting language, you must call + * \code it2 = Interface0DIterator(it1) \endcode instead of \code it2 = it1 \endcode + * where \a it1 and \a it2 are 2 Interface0DIterator. + * Otherwise, incrementing \a it1 will also increment \a it2. + */ +class Interface0DIterator : public Iterator +{ +public: + + Interface0DIterator(Interface0DIteratorNested* it = NULL) { + _iterator = it; + } + + /*! Copy constructor */ + Interface0DIterator(const Interface0DIterator& it) { + _iterator = it._iterator->copy(); + } + + /*! Destructor */ + virtual ~Interface0DIterator() { + if (_iterator) + delete _iterator; + } + + /*! Operator = + * \attention In the scripting language, you must call + * \code it2 = Interface0DIterator(it1) \endcode instead of \code it2 = it1 \endcode + * where \a it1 and \a it2 are 2 Interface0DIterator. + * Otherwise, incrementing \a it1 will also increment \a it2. + */ + Interface0DIterator& operator=(const Interface0DIterator& it) { + if(_iterator) + delete _iterator; + _iterator = it._iterator->copy(); + return *this; + } + + /*! Returns the string "Interface0DIterator". */ + virtual string getExactTypeName() const { + if (!_iterator) + return "Interface0DIterator"; + return _iterator->getExactTypeName() + "Proxy"; + } + + // FIXME test it != 0 (exceptions ?) + + /*! Returns a reference to the pointed Interface0D. + * In the scripting language, you must call + * "getObject()" instead using this operator. + */ + Interface0D& operator*() { + return _iterator->operator*(); + } + + /*! Returns a pointer to the pointed Interface0D. + * Can't be called in the scripting language. + */ + Interface0D* operator->() { + return &(operator*()); + } + + /*! Increments. In the scripting language, call + * "increment()". + */ + Interface0DIterator& operator++() { + _iterator->increment(); + return *this; + } + + /*! Increments. In the scripting language, call + * "increment()". + */ + Interface0DIterator operator++(int) { + Interface0DIterator ret(*this); + _iterator->increment(); + return ret; + } + + /*! Decrements. In the scripting language, call + * "decrement()". + */ + Interface0DIterator& operator--() { + _iterator->decrement(); + return *this; + } + + /*! Decrements. In the scripting language, call + * "decrement()". + */ + Interface0DIterator operator--(int) { + Interface0DIterator ret(*this); + _iterator->decrement(); + return ret; + } + + /*! Increments. */ + virtual int increment() { + return _iterator->increment(); + } + + /*! Decrements. */ + virtual int decrement() { + return _iterator->decrement(); + } + + /*! Returns true if the pointed Interface0D is the + * first of the 1D element containing the points over + * which we're iterating. + */ + virtual bool isBegin() const { + return _iterator->isBegin(); + } + + /*! Returns true if the pointed Interface0D is after the + * after the last point of the 1D element we're iterating from. + */ + virtual bool isEnd() const { + return _iterator->isEnd(); + } + + /*! operator == . */ + bool operator==(const Interface0DIterator& it) const { + return _iterator->operator==(*(it._iterator)); + } + + /*! operator != . */ + bool operator!=(const Interface0DIterator& it) const { + return !(*this == it); + } + + /*! Returns the curvilinear abscissa. */ + inline float t() const { + return _iterator->t(); + } + /*! Returns the point parameter in the curve 0<=u<=1. */ + inline float u() const { + return _iterator->u(); + } +protected: + + Interface0DIteratorNested* _iterator; +}; + +#endif // INTERFACE0D_H diff --git a/source/blender/freestyle/intern/view_map/Interface1D.h b/source/blender/freestyle/intern/view_map/Interface1D.h new file mode 100755 index 00000000000..17dee3973de --- /dev/null +++ b/source/blender/freestyle/intern/view_map/Interface1D.h @@ -0,0 +1,235 @@ +// +// Filename : Interface1D.h +// Author(s) : Emmanuel Turquin +// Purpose : Interface to 1D elts +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef INTERFACE1D_H +# define INTERFACE1D_H + +# include <string> +# include <iostream> +# include <float.h> +# include "../system/Id.h" +# include "../system/Precision.h" +# include "../winged_edge/Nature.h" +# include "Functions0D.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <Python.h> + +#ifdef __cplusplus +} +#endif + +using namespace std; +/*! \file Interface1D.h + * Interface1D and related tools definitions + */ +// Integration method +/*! The different integration + * methods that can be invoked + * to integrate into a single value the set of values obtained + * from each 0D element of a 1D element. + */ +typedef enum { + MEAN,/*!< The value computed for the 1D element is the mean of the values obtained for the 0D elements.*/ + MIN,/*!< The value computed for the 1D element is the minimum of the values obtained for the 0D elements.*/ + MAX,/*!< The value computed for the 1D element is the maximum of the values obtained for the 0D elements.*/ + FIRST,/*!< The value computed for the 1D element is the first of the values obtained for the 0D elements.*/ + LAST/*!< The value computed for the 1D element is the last of the values obtained for the 0D elements.*/ +} IntegrationType; + +/*! Returns a single + * value from a set of values evaluated at each 0D element + * of this 1D element. + * \param fun + * The UnaryFunction0D used to compute a value at each Interface0D. + * \param it + * The Interface0DIterator used to iterate over the 0D elements of + * this 1D element. The integration will occur over the 0D elements + * starting from the one pointed by it. + * \param it_end + * The Interface0DIterator pointing the end of the 0D elements of the + * 1D element. + * \param integration_type + * The integration method used to compute a single value from + * a set of values. + * \return the single value obtained for the 1D element. + */ +template <class T> +T integrate(UnaryFunction0D<T>& fun, + Interface0DIterator it, + Interface0DIterator it_end, + IntegrationType integration_type = MEAN) { + T res; + unsigned size; + switch (integration_type) { + case MIN: + fun(it); + res = fun.result;++it; + for (; !it.isEnd(); ++it) { + fun(it); + if (fun.result < res) + res = fun.result; + } + break; + case MAX: + fun(it); + res = fun.result;++it; + for (; !it.isEnd(); ++it) { + fun(it); + if (fun.result > res) + res = fun.result; + } + break; + case FIRST: + fun(it); + res = fun.result; + break; + case LAST: + fun(--it_end); + res = fun.result; + break; + case MEAN: + default: + fun(it); + res = fun.result;++it; + for (size = 1; !it.isEnd(); ++it, ++size) { + fun(it); + res += fun.result; + } + res /= (size ? size : 1); + break; + } + return res; +} + +// +// Interface1D +// +////////////////////////////////////////////////// + +/*! Base class for any 1D element. */ +class Interface1D +{ +public: + + /*! Default constructor */ + Interface1D() {_timeStamp=0;} + virtual ~Interface1D() {}; //soc + + /*! Returns the string "Interface1D" .*/ + virtual string getExactTypeName() const { + return "Interface1D"; + } + + // Iterator access + + /*! Returns an iterator over the Interface1D vertices, + * pointing to the first vertex. + */ + virtual Interface0DIterator verticesBegin() { + PyErr_SetString(PyExc_TypeError, "method verticesBegin() not properly overridden"); + return Interface0DIterator(); + } + + /*! Returns an iterator over the Interface1D vertices, + * pointing after the last vertex. + */ + virtual Interface0DIterator verticesEnd(){ + PyErr_SetString(PyExc_TypeError, "method verticesEnd() not properly overridden"); + return Interface0DIterator(); + } + + /*! Returns an iterator over the Interface1D points, + * pointing to the first point. The difference with + * verticesBegin() is that here we can iterate over + * points of the 1D element at a any given sampling. + * Indeed, for each iteration, a virtual point is created. + * \param t + * The sampling with which we want to iterate over points of + * this 1D element. + */ + virtual Interface0DIterator pointsBegin(float t=0.f) { + PyErr_SetString(PyExc_TypeError, "method pointsBegin() not properly overridden"); + return Interface0DIterator(); + } + + /*! Returns an iterator over the Interface1D points, + * pointing after the last point. The difference with + * verticesEnd() is that here we can iterate over + * points of the 1D element at a any given sampling. + * Indeed, for each iteration, a virtual point is created. + * \param t + * The sampling with which we want to iterate over points of + * this 1D element. + */ + virtual Interface0DIterator pointsEnd(float t=0.f) { + PyErr_SetString(PyExc_TypeError, "method pointsEnd() not properly overridden"); + return Interface0DIterator(); + } + + // Data access methods + + /*! Returns the 2D length of the 1D element. */ + virtual real getLength2D() const { + PyErr_SetString(PyExc_TypeError, "method getLength2D() not properly overridden"); + return 0; + } + + /*! Returns the Id of the 1D element .*/ + virtual Id getId() const { + PyErr_SetString(PyExc_TypeError, "method getId() not properly overridden"); + return Id(0, 0); + } + + + // FIXME: ce truc n'a rien a faire la...(c une requete complexe qui doit etre ds les Function1D) + /*! Returns the nature of the 1D element. */ + virtual Nature::EdgeNature getNature() const { + PyErr_SetString(PyExc_TypeError, "method getNature() not properly overridden"); + return Nature::NO_FEATURE; + } + + /*! Returns the time stamp of the 1D element. Mainly used for selection. */ + virtual unsigned getTimeStamp() const { + return _timeStamp; + } + + /*! Sets the time stamp for the 1D element. */ + inline void setTimeStamp(unsigned iTimeStamp){ + _timeStamp = iTimeStamp; + } + +protected: + unsigned _timeStamp; +}; + +#endif // INTERFACE1D_H diff --git a/source/blender/freestyle/intern/view_map/Silhouette.cpp b/source/blender/freestyle/intern/view_map/Silhouette.cpp new file mode 100755 index 00000000000..7a7d0a51d4b --- /dev/null +++ b/source/blender/freestyle/intern/view_map/Silhouette.cpp @@ -0,0 +1,370 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "Silhouette.h" +#include "ViewMap.h" + + /**********************************/ + /* */ + /* */ + /* SVertex */ + /* */ + /* */ + /**********************************/ + +Nature::VertexNature SVertex::getNature() const { + Nature::VertexNature nature = Nature::S_VERTEX; + if (_pViewVertex) + nature |= _pViewVertex->getNature(); + return nature; +} + +SVertex * SVertex::castToSVertex(){ + return this; +} + +ViewVertex * SVertex::castToViewVertex(){ + return _pViewVertex; +} + +NonTVertex * SVertex::castToNonTVertex(){ + return dynamic_cast<NonTVertex*>(_pViewVertex); +} + +TVertex * SVertex::castToTVertex(){ + return dynamic_cast<TVertex*>(_pViewVertex); +} + +float SVertex::shape_importance() const +{ + return shape()->importance(); +} + +//Material SVertex::material() const {return _Shape->material();} +Id SVertex::shape_id() const {return _Shape->getId();} +const SShape * SVertex::shape() const {return _Shape;} + +const int SVertex::qi() const +{ + if (getNature() & Nature::T_VERTEX) + Exception::raiseException(); + return (_FEdges[0])->qi(); +} + +occluder_container::const_iterator SVertex::occluders_begin() const +{ + if (getNature() & Nature::T_VERTEX) + Exception::raiseException(); + return (_FEdges[0])->occluders_begin(); +} + +occluder_container::const_iterator SVertex::occluders_end() const +{ + if (getNature() & Nature::T_VERTEX) + Exception::raiseException(); + return (_FEdges[0])->occluders_end(); +} + +bool SVertex::occluders_empty() const +{ + if (getNature() & Nature::T_VERTEX) + Exception::raiseException(); + return (_FEdges[0])->occluders_empty(); +} + +int SVertex::occluders_size() const +{ + if (getNature() & Nature::T_VERTEX) + Exception::raiseException(); + return (_FEdges[0])->occluders_size(); +} + +const Polygon3r& SVertex::occludee() const +{ + if (getNature() & Nature::T_VERTEX) + Exception::raiseException(); + return (_FEdges[0])->occludee(); +} + +const SShape* SVertex::occluded_shape() const +{ + if (getNature() & Nature::T_VERTEX) + Exception::raiseException(); + return (_FEdges[0])->occluded_shape(); +} + +const bool SVertex::occludee_empty() const +{ + if (getNature() & Nature::T_VERTEX) + Exception::raiseException(); + return (_FEdges[0])->occludee_empty(); +} + +real SVertex::z_discontinuity() const +{ + if (getNature() & Nature::T_VERTEX) + Exception::raiseException(); + return (_FEdges[0])->z_discontinuity(); +} + +FEdge* SVertex::fedge() +{ + if (getNature() & Nature::T_VERTEX) + return 0; + return _FEdges[0]; +} + +FEdge* SVertex::getFEdge(Interface0D& inter) +{ + FEdge * result = 0; + SVertex* iVertexB = dynamic_cast<SVertex*>(&inter); + if (!iVertexB) + return result; + vector<FEdge*>::const_iterator fe=_FEdges.begin(), feend=_FEdges.end(); + for(; + fe!=feend; + ++fe) + { + if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == iVertexB)) + || (((*fe)->vertexB() == this) && ((*fe)->vertexA() == iVertexB))) + result = (*fe); + } + if((result == 0) && (getNature() & Nature::T_VERTEX)) + { + SVertex *brother; + ViewVertex *vvertex = viewvertex(); + TVertex * tvertex = dynamic_cast<TVertex*>(vvertex); + if(tvertex) + { + brother = tvertex->frontSVertex(); + if(this == brother) + brother = tvertex->backSVertex(); + const vector<FEdge*>& fedges = brother->fedges(); + for(fe=fedges.begin(),feend=fedges.end(); + fe!=feend; + ++fe) + { + if( (((*fe)->vertexA() == brother) && ((*fe)->vertexB() == iVertexB)) + || (((*fe)->vertexB() == brother) && ((*fe)->vertexA() == iVertexB))) + result = (*fe); + } + } + } + if((result == 0) && (iVertexB->getNature() & Nature::T_VERTEX)) + { + SVertex *brother; + ViewVertex *vvertex = iVertexB->viewvertex(); + TVertex * tvertex = dynamic_cast<TVertex*>(vvertex); + if(tvertex) + { + brother = tvertex->frontSVertex(); + if(iVertexB == brother) + brother = tvertex->backSVertex(); + for(fe=_FEdges.begin(),feend=_FEdges.end(); + fe!=feend; + ++fe) + { + if( (((*fe)->vertexA() == this) && ((*fe)->vertexB() == brother)) + || (((*fe)->vertexB() == this) && ((*fe)->vertexA() == brother))) + result = (*fe); + } + } + } + + return result; +} + + + /**********************************/ + /* */ + /* */ + /* FEdge */ + /* */ + /* */ + /**********************************/ + + +int FEdge::viewedge_nature() const {return _ViewEdge->getNature();} +//float FEdge::viewedge_length() const {return _ViewEdge->viewedge_length();} +const SShape* FEdge::occluded_shape() const +{ + ViewShape * aShape = _ViewEdge->aShape(); + if(aShape == 0) + return 0; + return aShape->sshape(); +} + +float FEdge::shape_importance() const +{ + return _VertexA->shape()->importance(); +} + +int FEdge::invisibility() const +{ + return _ViewEdge->qi(); +} + +occluder_container::const_iterator FEdge::occluders_begin() const {return _ViewEdge->occluders_begin();} +occluder_container::const_iterator FEdge::occluders_end() const {return _ViewEdge->occluders_end();} +bool FEdge::occluders_empty() const {return _ViewEdge->occluders_empty();} +int FEdge::occluders_size() const {return _ViewEdge->occluders_size();} +const bool FEdge::occludee_empty() const +{ + return _ViewEdge->occludee_empty(); +} + + + +Id FEdge::shape_id() const +{ + return _VertexA->shape()->getId(); +} +const SShape* FEdge::shape() const +{ + return _VertexA->shape(); +} + +real FEdge::z_discontinuity() const +{ + if(!(getNature() & Nature::SILHOUETTE) && !(getNature() & Nature::BORDER)) + { + return 0; + } + + BBox<Vec3r> box = ViewMap::getInstance()->getScene3dBBox(); + + Vec3r bbox_size_vec(box.getMax() - box.getMin()); + real bboxsize = bbox_size_vec.norm(); + if(occludee_empty()) + + { + //return FLT_MAX; + + return 1.0; + + //return bboxsize; + + } + // real result; + // z_discontinuity_functor<SVertex> _functor; + + // Evaluate<SVertex,z_discontinuity_functor<SVertex> >(&_functor, iCombination, result ) + Vec3r middle((_VertexB->point3d()-_VertexA->point3d())); + + middle /= 2; + Vec3r disc_vec(middle - _occludeeIntersection); + real res = disc_vec.norm() / bboxsize; + return res; + + //return fabs((middle.z()-_occludeeIntersection.z())); +} + + +//float FEdge::local_average_depth(int iCombination ) const +//{ +// +// float result; +// local_average_depth_functor<SVertex> functor; +// Evaluate(&functor, iCombination, result); +// +// return result; +//} +//float FEdge::local_depth_variance(int iCombination ) const +//{ +// float result; +// +// local_depth_variance_functor<SVertex> functor; +// +// Evaluate(&functor, iCombination, result); +// +// return result; +//} +// +// +//real FEdge::local_average_density( float sigma, int iCombination) const +//{ +// float result; +// +// density_functor<SVertex> functor(sigma); +// +// Evaluate(&functor, iCombination, result); +// +// return result; +//} +// +////Vec3r FEdge::normal(int& oException /* = Exception::NO_EXCEPTION */) +////{ +//// Vec3r Na = _VertexA->normal(oException); +//// if(oException != Exception::NO_EXCEPTION) +//// return Na; +//// Vec3r Nb = _VertexB->normal(oException); +//// if(oException != Exception::NO_EXCEPTION) +//// return Nb; +//// return (Na+Nb)/2.0; +////} +// +//Vec3r FEdge::curvature2d_as_vector(int iCombination) const +//{ +// Vec3r result; +// curvature2d_as_vector_functor<SVertex> _functor; +// Evaluate<Vec3r,curvature2d_as_vector_functor<SVertex> >(&_functor, iCombination, result ); +// return result; +//} +// +//real FEdge::curvature2d_as_angle(int iCombination) const +//{ +// real result; +// curvature2d_as_angle_functor<SVertex> _functor; +// Evaluate<real,curvature2d_as_angle_functor<SVertex> >(&_functor, iCombination, result ); +// return result; +//} + + /**********************************/ + /* */ + /* */ + /* FEdgeSharp */ + /* */ + /* */ + /**********************************/ + +//Material FEdge::material() const +//{ +// return _VertexA->shape()->material(); +//} +const FrsMaterial& FEdgeSharp::aFrsMaterial() const { + return _VertexA->shape()->frs_material(_aFrsMaterialIndex); +} + +const FrsMaterial& FEdgeSharp::bFrsMaterial() const { + return _VertexA->shape()->frs_material(_bFrsMaterialIndex); +} + + /**********************************/ + /* */ + /* */ + /* FEdgeSmooth */ + /* */ + /* */ + /**********************************/ + +const FrsMaterial& FEdgeSmooth::frs_material() const { + return _VertexA->shape()->frs_material(_FrsMaterialIndex); +} diff --git a/source/blender/freestyle/intern/view_map/Silhouette.h b/source/blender/freestyle/intern/view_map/Silhouette.h new file mode 100755 index 00000000000..a928eb87cc9 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/Silhouette.h @@ -0,0 +1,1429 @@ +// +// Filename : Silhouette.h +// Author(s) : Stephane Grabli +// Purpose : Classes to define a silhouette structure +// Date of creation : 25/03/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef SILHOUETTE_H +# define SILHOUETTE_H + +# include <iostream> +# include <string> +# include <vector> +# include <set> +# include <float.h> +# include "../system/FreestyleConfig.h" +# include "../geometry/Geom.h" +# include "../geometry/BBox.h" +# include "../scene_graph/FrsMaterial.h" +# include "../geometry/Polygon.h" +# include "../system/Exception.h" +# include "Interface0D.h" +# include "Interface1D.h" +# include "../winged_edge/Curvature.h" + +using namespace std; +using namespace Geometry; + +class ViewShape; +typedef vector<ViewShape*> occluder_container; + + /**********************************/ + /* */ + /* */ + /* SVertex */ + /* */ + /* */ + /**********************************/ + +class FEdge; +class ViewVertex; +class SShape; + +/*! Class to define a vertex of the embedding. */ +class LIB_VIEW_MAP_EXPORT SVertex : public Interface0D +{ +public: // Implementation of Interface0D + + /*! Returns the string "SVertex" .*/ + virtual string getExactTypeName() const { + return "SVertex"; + } + + // Data access methods + + /*! Returns the 3D x coordinate of the vertex .*/ + virtual real getX() const { + return _Point3D.x(); + } + + /*! Returns the 3D y coordinate of the vertex .*/ + virtual real getY() const { + return _Point3D.y(); + } + + /*! Returns the 3D z coordinate of the vertex .*/ + virtual real getZ() const { + return _Point3D.z(); + } + + /*! Returns the 3D point. */ + virtual Vec3f getPoint3D() const { + return _Point3D; + } + + /*! Returns the projected 3D x coordinate of the vertex .*/ + virtual real getProjectedX() const { + return _Point2D.x(); + } + + /*! Returns the projected 3D y coordinate of the vertex .*/ + virtual real getProjectedY() const { + return _Point2D.y(); + } + + /*! Returns the projected 3D z coordinate of the vertex .*/ + virtual real getProjectedZ() const { + return _Point2D.z(); + } + + /*! Returns the 2D point. */ + virtual Vec2f getPoint2D() const { + return Vec2f((float)_Point2D.x(),(float)_Point2D.y()); + } + + /*! Returns the FEdge that lies between this Svertex and the + * Interface0D given as argument. */ + virtual FEdge* getFEdge(Interface0D&); + + /*! Returns the Id of the vertex .*/ + virtual Id getId() const { + return _Id; + } + + /*! Returns the nature of the vertex .*/ + virtual Nature::VertexNature getNature() const; + + /*! Cast the Interface0D in SVertex if it can be. */ + virtual SVertex * castToSVertex(); + + /*! Cast the Interface0D in ViewVertex if it can be. */ + virtual ViewVertex * castToViewVertex(); + + /*! Cast the Interface0D in NonTVertex if it can be. */ + virtual NonTVertex * castToNonTVertex(); + + /*! Cast the Interface0D in TVertex if it can be. */ + virtual TVertex * castToTVertex(); + +public: + + typedef vector<FEdge*> fedges_container; + +private: + + Id _Id; + Vec3r _Point3D; + Vec3r _Point2D; + set<Vec3r> _Normals; + vector<FEdge*> _FEdges; // the edges containing this vertex + SShape *_Shape; // the shape to which belongs the vertex + ViewVertex *_pViewVertex; // The associated viewvertex, in case there is one. + real _curvatureFredo; + Vec2r _directionFredo; + CurvatureInfo* _curvature_info; + +public: + + /*! A field that can be used by the user to store any data. + * This field must be reseted afterwards using ResetUserData(). + */ + void *userdata; + + /*! Default constructor.*/ + inline SVertex() { + _Id = 0; + userdata = NULL; + _Shape = NULL; + _pViewVertex = 0; + _curvature_info = 0; + } + + /*! Builds a SVertex from 3D coordinates and an Id. */ + inline SVertex(const Vec3r &iPoint3D, const Id& id) { + _Point3D = iPoint3D; + _Id=id; + userdata = NULL; + _Shape = NULL; + _pViewVertex=0; + _curvature_info = 0; + } + + /*! Copy constructor. */ + inline SVertex(SVertex& iBrother) { + _Id = iBrother._Id; + _Point3D = iBrother.point3D(); + _Point2D = iBrother.point2D(); + _Normals = iBrother._Normals; + _FEdges = iBrother.fedges(); + _Shape = iBrother.shape(); + _pViewVertex = iBrother._pViewVertex; + if (!(iBrother._curvature_info)) + _curvature_info = 0; + else + _curvature_info = new CurvatureInfo(*(iBrother._curvature_info)); + iBrother.userdata = this; + userdata = 0; + } + + /*! Destructor. */ + virtual ~SVertex() { + if (_curvature_info) + delete _curvature_info; + } + + /*! Cloning method. */ + virtual SVertex * duplicate() { + SVertex *clone = new SVertex(*this); + return clone; + } + + /*! operator == */ + virtual bool operator==(const SVertex& iBrother) { + return ((_Point2D == iBrother._Point2D) && + (_Point3D == iBrother._Point3D)); + } + + /* accessors */ + inline const Vec3r& point3D() const {return _Point3D;} + inline const Vec3r& point2D() const {return _Point2D;} + /*! Returns the set of normals for this Vertex. + * In a smooth surface, a vertex has exactly one normal. + * In a sharp surface, a vertex can have any number of normals. + */ + inline set<Vec3r> normals() {return _Normals;} + /*! Returns the number of different normals for this vertex. */ + inline unsigned normalsSize() const {return _Normals.size();} + inline const vector<FEdge*>& fedges() {return _FEdges;} + inline fedges_container::iterator fedges_begin() {return _FEdges.begin();} + inline fedges_container::iterator fedges_end() {return _FEdges.end();} + inline SShape * shape() {return _Shape;} + inline real z() const {return _Point2D[2];} + /*! If this SVertex is also a ViewVertex, this method + * returns a pointer onto this ViewVertex. 0 is returned + * otherwise. + */ + inline ViewVertex * viewvertex() {return _pViewVertex;} + + /*! modifiers */ + /*! Sets the 3D coordinates of the SVertex. */ + inline void setPoint3D(const Vec3r &iPoint3D) {_Point3D = iPoint3D;} + /*! Sets the 3D projected coordinates of the SVertex. */ + inline void setPoint2D(const Vec3r &iPoint2D) {_Point2D = iPoint2D;} + /*! Adds a normal to the Svertex's set of normals. If the same + * normal is already in the set, nothing changes. + */ + inline void AddNormal(const Vec3r& iNormal) + { + _Normals.insert(iNormal); // if iNormal in the set already exists, nothing is done + } + + void setCurvatureInfo(CurvatureInfo* ci) { + _curvature_info = ci; + } + + const CurvatureInfo* getCurvatureInfo() const { + return _curvature_info; + } + + /* Fredo's normal and curvature*/ + void setCurvatureFredo(real c) {_curvatureFredo=c;} + void setDirectionFredo(Vec2r d) {_directionFredo=d;} + real curvatureFredo () {return _curvatureFredo;} + const Vec2r directionFredo () {return _directionFredo;} + + /*! Sets the Id */ + inline void setId(const Id& id) {_Id = id;} + inline void setFEdges(const vector<FEdge*>& iFEdges) {_FEdges = iFEdges;} + inline void setShape(SShape *iShape) {_Shape = iShape;} + inline void setViewVertex(ViewVertex *iViewVertex) {_pViewVertex = iViewVertex;} + /*! Add an FEdge to the list of edges emanating from this SVertex. */ + inline void AddFEdge(FEdge* iFEdge) {_FEdges.push_back(iFEdge);} + /* replaces edge 1 by edge 2 in the list of edges */ + inline void Replace(FEdge *e1, FEdge *e2) + { + vector<FEdge*>::iterator insertedfe; + for(vector<FEdge*>::iterator fe=_FEdges.begin(),fend=_FEdges.end(); + fe!=fend; + fe++) + { + if((*fe) == e1) + { + insertedfe = _FEdges.insert(fe, e2);// inserts e2 before fe. + // returns an iterator pointing toward e2. fe is invalidated. + // we want to remove e1, but we can't use fe anymore: + insertedfe++; // insertedfe points now to e1 + _FEdges.erase(insertedfe); + return; + } + } + } + +public: + + /* Information access interface */ + + FEdge *fedge() ; // for non T vertex + inline const Vec3r& point2d() const {return point2D();} + inline const Vec3r& point3d() const {return point3D();} + inline Vec3r normal() const {if(_Normals.size() == 1) return (*(_Normals.begin())); Exception::raiseException(); return *(_Normals.begin());} + //Material material() const ; + Id shape_id() const ; + const SShape* shape() const ; + float shape_importance() const ; + + const int qi() const ; + occluder_container::const_iterator occluders_begin() const ; + occluder_container::const_iterator occluders_end() const ; + bool occluders_empty() const ; + int occluders_size() const ; + const Polygon3r& occludee() const ; + const SShape * occluded_shape() const ; + const bool occludee_empty() const ; + real z_discontinuity() const ; + //inline float local_average_depth() const ; + // inline float local_depth_variance() const ; + // inline real local_average_density(float sigma = 2.3f) const ; + //inline Vec3r shaded_color() const ; + // inline Vec3r orientation2d() const ; + // inline Vec3r orientation3d() const ; + // inline Vec3r curvature2d_as_vector() const ; + /*! angle in radians */ + // inline real curvature2d_as_angle() const ; + +}; + + /**********************************/ + /* */ + /* */ + /* FEdge */ + /* */ + /* */ + /**********************************/ + + +class ViewEdge; +/*! Base Class for feature edges. + * This FEdge can represent a silhouette, a crease, + * a ridge/valley, a border or a suggestive contour. + * For silhouettes, the FEdge is oriented + * such as, the visible face lies on the left of the edge. + * For borders, the FEdge is oriented + * such as, the face lies on the left of the edge. + * An FEdge can represent an initial edge of the mesh + * or runs accross a face of the initial mesh depending + * on the smoothness or sharpness of the mesh. + * This class is specialized into a smooth and a sharp + * version since their properties slightly vary from + * one to the other. + */ +class LIB_VIEW_MAP_EXPORT FEdge : public Interface1D +{ +public: // Implementation of Interface0D + + /*! Returns the string "FEdge" . */ + virtual string getExactTypeName() const { + return "FEdge"; + } + + // Data access methods + + /*! Returns the 2D length of the FEdge. */ + virtual real getLength2D() const { + if (!_VertexA || !_VertexB) + return 0; + return (_VertexB->getPoint2D() - _VertexA->getPoint2D()).norm(); + } + + /*! Returns the Id of the FEdge. */ + virtual Id getId() const { + return _Id; + } + +public: + + // An edge can only be of one kind (SILHOUETTE or BORDER, etc...) + // For an multi-nature edge there must be several different FEdge. + // DEBUG: + // Vec3r A; + // Vec3r u; + // vector<Polygon3r> _Occludees; + // Vec3r intersection; + // vector<Vec3i> _Cells; + +protected: + SVertex *_VertexA; + SVertex *_VertexB; + Id _Id; + Nature::EdgeNature _Nature; + //vector<Polygon3r> _Occluders; // visibility // NON GERE PAR LE COPY CONSTRUCTOR!! + + FEdge *_NextEdge; // next edge on the chain + FEdge *_PreviousEdge; + ViewEdge *_ViewEdge; + // Sometimes we need to deport the visibility computation onto another + // edge. For example the exact edges use edges of the mesh to + // compute their visibility + + Polygon3r _aFace; // The occluded face which lies on the right of a silhouette edge + Vec3r _occludeeIntersection; + bool _occludeeEmpty; + + bool _isSmooth; + +public: + /*! A field that can be used by the user to store any data. + * This field must be reseted afterwards using ResetUserData(). + */ + void *userdata; + /*! Default constructor */ + inline FEdge() { + userdata = NULL; + _VertexA = NULL; + _VertexB = NULL; + _Nature = Nature::NO_FEATURE; + _NextEdge = NULL; + _PreviousEdge = NULL; + _ViewEdge = NULL; + //_hasVisibilityPoint=false; + _occludeeEmpty = true; + _isSmooth = false; + } + /*! Builds an FEdge going from vA to vB. */ + inline FEdge(SVertex *vA, SVertex *vB) { + userdata = NULL; + _VertexA = vA; + _VertexB = vB; + _Nature = Nature::NO_FEATURE; + _NextEdge=NULL; + _PreviousEdge=NULL; + _ViewEdge = NULL; + //_hasVisibilityPoint=false; + _occludeeEmpty = true; + _isSmooth = false; + } + /*! Copy constructor */ + inline FEdge(FEdge& iBrother) + { + _VertexA = iBrother.vertexA(); + _VertexB = iBrother.vertexB(); + _NextEdge = iBrother.nextEdge(); + _PreviousEdge = iBrother._PreviousEdge; + _Nature = iBrother.getNature(); + _Id = iBrother._Id; + _ViewEdge = iBrother._ViewEdge; + //_hasVisibilityPoint = iBrother._hasVisibilityPoint; + //_VisibilityPointA = iBrother._VisibilityPointA; + //_VisibilityPointB = iBrother._VisibilityPointB; + _aFace = iBrother._aFace; + _occludeeEmpty = iBrother._occludeeEmpty; + _isSmooth = iBrother._isSmooth; + iBrother.userdata = this; + userdata = 0; + } + /*! Destructor */ + virtual ~FEdge() {} + /*! Cloning method. */ + virtual FEdge* duplicate() + { + FEdge *clone = new FEdge(*this); + return clone; + } + /* accessors */ + /*! Returns the first SVertex. */ + inline SVertex* vertexA() {return _VertexA;} + /*! Returns the second SVertex. */ + inline SVertex* vertexB() {return _VertexB;} + /*! Returns the first SVertex if i=0, the seccond SVertex + * if i=1. */ + inline SVertex* operator[](const unsigned short int& i) const{ + return i%2==0 ? _VertexA : _VertexB; + } + /*! Returns the nature of the FEdge. */ + inline Nature::EdgeNature getNature() const {return _Nature;} + /*! Returns the FEdge following this one in the ViewEdge. + * If this FEdge is the last of the ViewEdge, 0 is returned. + */ + inline FEdge * nextEdge() {return _NextEdge;} + /*! Returns the Edge preceding this one in the ViewEdge. + * If this FEdge is the first one of the ViewEdge, 0 is returned. + */ + inline FEdge * previousEdge() {return _PreviousEdge;} + inline SShape * shape() {return _VertexA->shape();} + //inline int invisibility() const {return _Occluders.size();} + int invisibility() const ; + //inline const vector<Polygon3r>& occluders() const {return _Occluders;} + /*! Returns a pointer to the ViewEdge to which this FEdge belongs to. */ + inline ViewEdge * viewedge() const {return _ViewEdge;} + inline Vec3r center3d() {return Vec3r((_VertexA->point3D()+_VertexB->point3D())/2.0);} + inline Vec3r center2d() {return Vec3r((_VertexA->point2D()+_VertexB->point2D())/2.0);} + // inline bool hasVisibilityPoint() const {return _hasVisibilityPoint;} + // inline Vec3r visibilityPointA() const {return _VisibilityPointA;} + // inline Vec3r visibilityPointB() const {return _VisibilityPointB;} + inline const Polygon3r& aFace() const {return _aFace;} + inline const Vec3r& getOccludeeIntersection() { return _occludeeIntersection; } + inline bool getOccludeeEmpty() { return _occludeeEmpty; } + /*! Returns true if this FEdge is a smooth FEdge. */ + inline bool isSmooth() const {return _isSmooth;} + + /* modifiers */ + /*! Sets the first SVertex. */ + inline void setVertexA(SVertex *vA) {_VertexA = vA;} + /*! Sets the second SVertex. */ + inline void setVertexB(SVertex *vB) {_VertexB = vB;} + /*! Sets the FEdge Id . */ + inline void setId(const Id& id) {_Id = id;} + /*! Sets the pointer to the next FEdge. */ + inline void setNextEdge(FEdge* iEdge) {_NextEdge = iEdge;} + /*! Sets the pointer to the previous FEdge. */ + inline void setPreviousEdge(FEdge *iEdge) {_PreviousEdge = iEdge;} + /*! Sets the nature of this FEdge. */ + inline void setNature(Nature::EdgeNature iNature) {_Nature = iNature;} + //inline void AddOccluder(Polygon3r& iPolygon) {_Occluders.push_back(iPolygon);} + /*! Sets the ViewEdge to which this FEdge belongs to. */ + inline void setViewEdge(ViewEdge *iViewEdge) {_ViewEdge = iViewEdge;} + // inline void setHasVisibilityPoint(bool iBool) {_hasVisibilityPoint = iBool;} + // inline void setVisibilityPointA(const Vec3r& iPoint) {_VisibilityPointA = iPoint;} + // inline void setVisibilityPointB(const Vec3r& iPoint) {_VisibilityPointB = iPoint;} + inline void setaFace(Polygon3r& iFace) {_aFace = iFace;} + inline void setOccludeeIntersection(const Vec3r& iPoint) {_occludeeIntersection = iPoint;} + inline void setOccludeeEmpty(bool iempty) {_occludeeEmpty = iempty;} + /*! Sets the flag telling whether this FEdge is smooth or sharp. + * true for Smooth, false for Sharp. + */ + inline void setSmooth(bool iFlag) {_isSmooth = iFlag;} + + /* checks whether two FEdge have a common vertex. + * Returns a pointer on the common vertex if it exists, + * NULL otherwise. + */ + static inline SVertex* CommonVertex(FEdge *iEdge1, FEdge* iEdge2) + { + if((NULL == iEdge1) || (NULL == iEdge2)) + return NULL; + + SVertex *sv1 = iEdge1->vertexA(); + SVertex *sv2 = iEdge1->vertexB(); + SVertex *sv3 = iEdge2->vertexA(); + SVertex *sv4 = iEdge2->vertexB(); + + if((sv1 == sv3) || (sv1 == sv4)) + { + return sv1; + } + else if((sv2 == sv3) || (sv2 == sv4)) + { + return sv2; + } + + return NULL; + } + + inline const SVertex* min2d() const + { + if(_VertexA->point2D() < _VertexB->point2D()) + return _VertexA; + else + return _VertexB; + } + inline const SVertex* max2d() const + { + if(_VertexA->point2D() < _VertexB->point2D()) + return _VertexB; + else + return _VertexA; + } + + /* Information access interface */ + /* Information access interface */ + + //Material material() const ; + Id shape_id() const ; + const SShape * shape() const ; + float shape_importance() const ; + inline const int qi() const {return invisibility();} + occluder_container::const_iterator occluders_begin() const ; + occluder_container::const_iterator occluders_end() const ; + bool occluders_empty() const ; + int occluders_size() const ; + inline const Polygon3r& occludee() const {return aFace();} + const SShape * occluded_shape() const ; + //inline const bool occludee_empty() const {return _occludeeEmpty;} + const bool occludee_empty() const ; + real z_discontinuity() const ; + // inline float local_average_depth(int iCombination = 0) const ; + // inline float local_depth_variance(int iCombination = 0) const ; + // inline real local_average_density(float sigma = 2.3f, int iCombination = 0) const ; + //inline Vec3r shaded_color(int iCombination = 0) const {} + int viewedge_nature() const ; + //float viewedge_length() const ; + inline Vec3r orientation2d() const {return Vec3r(_VertexB->point2d()-_VertexA->point2d());} + inline Vec3r orientation3d() const {return Vec3r(_VertexB->point3d()-_VertexA->point3d());} + // //inline real curvature2d() const {return viewedge()->curvature2d((_VertexA->point2d()+_VertexB->point2d())/2.0);} + // inline Vec3r curvature2d_as_vector(int iCombination = 0) const ; + // /* angle in degrees*/ + // inline real curvature2d_as_angle(int iCombination = 0) const ; + + + // Iterator access (Interface1D) + /*! Returns an iterator over the 2 (!) SVertex + * pointing to the first SVertex. */ + virtual inline Interface0DIterator verticesBegin(); + /*! Returns an iterator over the 2 (!) SVertex + * pointing after the last SVertex. */ + virtual inline Interface0DIterator verticesEnd(); + + /*! Returns an iterator over the FEdge points, + * pointing to the first point. The difference with + * verticesBegin() is that here we can iterate over + * points of the FEdge at a any given sampling. + * Indeed, for each iteration, a virtual point is created. + * \param t + * The sampling with which we want to iterate over points of + * this FEdge. + */ + virtual inline Interface0DIterator pointsBegin(float t=0.f); + /*! Returns an iterator over the FEdge points, + * pointing after the last point. The difference with + * verticesEnd() is that here we can iterate over + * points of the FEdge at a any given sampling. + * Indeed, for each iteration, a virtual point is created. + * \param t + * The sampling with which we want to iterate over points of + * this FEdge. + */ + virtual inline Interface0DIterator pointsEnd(float t=0.f); +}; + +// +// SVertexIterator +// +///////////////////////////////////////////////// + +namespace FEdgeInternal { + + class SVertexIterator : public Interface0DIteratorNested + { + public: + + SVertexIterator() { + _vertex = NULL; + _edge = NULL; + } + + SVertexIterator(const SVertexIterator& vi) { + _vertex = vi._vertex; + _edge = vi._edge; + } + + SVertexIterator(SVertex* v, FEdge* edge) { + _vertex = v; + _edge = edge; + } + + SVertexIterator& operator=(const SVertexIterator& vi) { + _vertex = vi._vertex; + _edge = vi._edge; + return *this; + } + + virtual string getExactTypeName() const { + return "SVertexIterator"; + } + + virtual SVertex& operator*() { + return *_vertex; + } + + virtual SVertex* operator->() { + return &(operator*()); + } + + virtual SVertexIterator& operator++() { + increment(); + return *this; + } + + virtual SVertexIterator operator++(int) { + SVertexIterator ret(*this); + increment(); + return ret; + } + + virtual SVertexIterator& operator--() { + decrement(); + return *this; + } + + virtual SVertexIterator operator--(int) { + SVertexIterator ret(*this); + decrement(); + return ret; + } + + virtual int increment() { + if (_vertex == _edge->vertexB()) { + _vertex = 0; + return 0; + } + + _vertex = _edge->vertexB(); + return 0; + } + + virtual int decrement() { + if (_vertex == _edge->vertexA()) { + _vertex = 0; + return 0; + } + _vertex = _edge->vertexA(); + return 0; + } + + virtual bool isBegin() const { + return _vertex == _edge->vertexA(); + } + + virtual bool isEnd() const { + return _vertex == _edge->vertexB(); + } + + virtual bool operator==(const Interface0DIteratorNested& it) const { + const SVertexIterator* it_exact = dynamic_cast<const SVertexIterator*>(&it); + if (!it_exact) + return false; + return ((_vertex == it_exact->_vertex) && + (_edge == it_exact->_edge)); + } + + virtual float t() const{ + if(_vertex == _edge->vertexA()){ + return 0; + } + return ((float)_edge->getLength2D()); + } + virtual float u() const{ + if(_vertex == _edge->vertexA()){ + return 0; + } + return 1.0; + } + virtual SVertexIterator* copy() const { + return new SVertexIterator(*this); + } + + private: + + SVertex* _vertex; + FEdge* _edge; + }; + +} // end of namespace FEdgeInternal + +// Iterator access (implementation) + +Interface0DIterator FEdge::verticesBegin() { + Interface0DIterator ret(new FEdgeInternal::SVertexIterator(_VertexA, this)); + return ret; +} + +Interface0DIterator FEdge::verticesEnd() { + Interface0DIterator ret(new FEdgeInternal::SVertexIterator(0, this)); + return ret; +} + +Interface0DIterator FEdge::pointsBegin(float t) { + return verticesBegin(); +} + +Interface0DIterator FEdge::pointsEnd(float t) { + return verticesEnd(); +} + +/*! Class defining a sharp FEdge. A Sharp FEdge + * corresponds to an initial edge of the input mesh. + * It can be a silhouette, a crease or a border. + * If it is a crease edge, then it is borded + * by two faces of the mesh. Face a lies on its right + * whereas Face b lies on its left. + * If it is a border edge, then it doesn't have any + * face on its right, and thus Face a = 0. + */ +class LIB_VIEW_MAP_EXPORT FEdgeSharp : public FEdge +{ +protected: + Vec3r _aNormal; // When following the edge, normal of the right face + Vec3r _bNormal; // When following the edge, normal of the left face + unsigned _aFrsMaterialIndex; + unsigned _bFrsMaterialIndex; + +public: + /*! Returns the string "FEdgeSharp" . */ + virtual string getExactTypeName() const { + return "FEdgeSharp"; + } + /*! Default constructor. */ + inline FEdgeSharp() : FEdge(){ + _aFrsMaterialIndex = _bFrsMaterialIndex = 0; + } + /*! Builds an FEdgeSharp going from vA to vB. */ + inline FEdgeSharp(SVertex *vA, SVertex *vB) : FEdge(vA, vB){ + _aFrsMaterialIndex = _bFrsMaterialIndex = 0; + } + /*! Copy constructor. */ + inline FEdgeSharp(FEdgeSharp& iBrother) : FEdge(iBrother){ + _aNormal = iBrother._aNormal; + _bNormal = iBrother._bNormal; + _aFrsMaterialIndex = iBrother._aFrsMaterialIndex; + _bFrsMaterialIndex = iBrother._bFrsMaterialIndex; + } + /*! Destructor. */ + virtual ~FEdgeSharp() {} + /*! Cloning method. */ + virtual FEdge* duplicate(){ + FEdge *clone = new FEdgeSharp(*this); + return clone; + } + /*! Returns the normal to the face lying on the + * right of the FEdge. If this FEdge is a border, + * it has no Face on its right and therefore, no normal. + */ + inline const Vec3r& normalA() {return _aNormal;} + /*! Returns the normal to the face lying on the + * left of the FEdge. + */ + inline const Vec3r& normalB() {return _bNormal;} + /*! Returns the index of the material of the face lying on the + * right of the FEdge. If this FEdge is a border, + * it has no Face on its right and therefore, no material. + */ + inline unsigned aFrsMaterialIndex() const {return _aFrsMaterialIndex;} + /*! Returns the material of the face lying on the + * right of the FEdge. If this FEdge is a border, + * it has no Face on its right and therefore, no material. + */ + const FrsMaterial& aFrsMaterial() const ; + /*! Returns the index of the material of the face lying on the + * left of the FEdge. + */ + inline unsigned bFrsMaterialIndex() const {return _bFrsMaterialIndex;} + /*! Returns the material of the face lying on the + * left of the FEdge. + */ + const FrsMaterial& bFrsMaterial() const ; + + /*! Sets the normal to the face lying on the right of the FEdge. */ + inline void setNormalA(const Vec3r& iNormal) {_aNormal = iNormal;} + /*! Sets the normal to the face lying on the left of the FEdge. */ + inline void setNormalB(const Vec3r& iNormal) {_bNormal = iNormal;} + /*! Sets the index of the material lying on the right of the FEdge.*/ + inline void setaFrsMaterialIndex(unsigned i) {_aFrsMaterialIndex = i;} + /*! Sets the index of the material lying on the left of the FEdge.*/ + inline void setbFrsMaterialIndex(unsigned i) {_bFrsMaterialIndex = i;} + +}; + +/*! Class defining a smooth edge. This kind of edge typically + * runs across a face of the input mesh. It can be + * a silhouette, a ridge or valley, a suggestive contour. + */ +class LIB_VIEW_MAP_EXPORT FEdgeSmooth : public FEdge +{ +protected: + Vec3r _Normal; + unsigned _FrsMaterialIndex; + // bool _hasVisibilityPoint; + // Vec3r _VisibilityPointA; // The edge on which the visibility will be computed represented + // Vec3r _VisibilityPointB; // using its 2 extremity points A and B + void * _Face; // In case of exact silhouette, Face is the WFace crossed by Fedge + // NON GERE PAR LE COPY CONSTRUCTEUR +public: + /*! Returns the string "FEdgeSmooth" . */ + virtual string getExactTypeName() const { + return "FEdgeSmooth"; + } + /*! Default constructor. */ + inline FEdgeSmooth() : FEdge(){ + _Face=0; + _FrsMaterialIndex = 0; + _isSmooth = true; + } + /*! Builds an FEdgeSmooth going from vA to vB. */ + inline FEdgeSmooth(SVertex *vA, SVertex *vB) : FEdge(vA, vB){ + _Face=0; + _FrsMaterialIndex = 0; + _isSmooth = true; + + } + /*! Copy constructor. */ + inline FEdgeSmooth(FEdgeSmooth& iBrother) : FEdge(iBrother){ + _Normal = iBrother._Normal; + _Face = iBrother._Face; + _FrsMaterialIndex = iBrother._FrsMaterialIndex; + _isSmooth = true; + } + /*! Destructor. */ + virtual ~FEdgeSmooth() {} + /*! Cloning method. */ + virtual FEdge* duplicate(){ + FEdge *clone = new FEdgeSmooth(*this); + return clone; + } + + inline void * face() const {return _Face;} + /*! Returns the normal to the Face it is running accross. */ + inline const Vec3r& normal() {return _Normal;} + /*! Returns the index of the material of the face it is running accross. */ + inline unsigned frs_materialIndex() const {return _FrsMaterialIndex;} + /*! Returns the material of the face it is running accross. */ + const FrsMaterial& frs_material() const ; + + inline void setFace(void * iFace) {_Face = iFace;} + /*! Sets the normal to the Face it is running accross. */ + inline void setNormal(const Vec3r& iNormal) {_Normal = iNormal;} + /*! Sets the index of the material of the face it is running accross. */ + inline void setFrsMaterialIndex(unsigned i) {_FrsMaterialIndex = i;} +}; + /**********************************/ + /* */ + /* */ + /* SShape */ + /* */ + /* */ + /**********************************/ + + +/*! Class to define a feature shape. It is the gathering + * of feature elements from an identified input shape + */ +class LIB_VIEW_MAP_EXPORT SShape +{ +private: + vector<FEdge*> _chains; // list of fedges that are chains starting points. + vector<SVertex*> _verticesList; // list of all vertices + vector<FEdge*> _edgesList; // list of all edges + Id _Id; + BBox<Vec3r> _BBox; + vector<FrsMaterial> _FrsMaterials; + + float _importance; + + ViewShape *_ViewShape; + +public: + /*! A field that can be used by the user to store any data. + * This field must be reseted afterwards using ResetUserData(). + */ + void* userdata; // added by E.T. + /*! Default constructor */ + inline SShape() + { + userdata = 0; + + _importance = 0.f; + _ViewShape = 0; + } + /*! Copy constructor */ + inline SShape(SShape& iBrother) + { + userdata = 0; + _Id = iBrother._Id; + _BBox = iBrother.bbox(); + _FrsMaterials = iBrother._FrsMaterials; + + _importance = iBrother._importance; + + _ViewShape = iBrother._ViewShape; + + + //--------- + // vertices + //--------- + vector<SVertex*>::iterator sv,svend; + vector<SVertex*>& verticesList = iBrother.getVertexList(); + for(sv=verticesList.begin(), svend=verticesList.end(); + sv!=svend; + sv++) + { + SVertex *newv = new SVertex(*(*sv)); + newv->setShape(this); + _verticesList.push_back(newv); + } + + //------ + // edges + //------ + vector<FEdge*>::iterator e,eend; + vector<FEdge*>& edgesList = iBrother.getEdgeList(); + for(e=edgesList.begin(),eend=edgesList.end(); + e!=eend; + e++) + { + FEdge *newe = (*e)->duplicate(); + _edgesList.push_back(newe); + } + + //------------------------- + // starting chain edges + //------------------------- + vector<FEdge*>::iterator fe,fend; + vector<FEdge*>& fedges = iBrother.getChains(); + for(fe=fedges.begin(),fend=fedges.end(); + fe!=fend; + fe++) + { + _chains.push_back((FEdge*)((*fe)->userdata)); + } + + + //------------------------- + // remap edges in vertices: + //------------------------- + for(sv=_verticesList.begin(),svend=_verticesList.end(); + sv!=svend; + sv++) + { + const vector<FEdge*>& fedgeList = (*sv)->fedges(); + vector<FEdge*> newfedgelist; + for(vector<FEdge*>::const_iterator fed=fedgeList.begin(),fedend=fedgeList.end(); + fed!=fedend; + fed++) + { + FEdge *current = *fed; + newfedgelist.push_back((FEdge*)current->userdata); + } + (*sv)->setFEdges(newfedgelist); + } + + //------------------------------------- + // remap vertices and nextedge in edges: + //------------------------------------- + for(e=_edgesList.begin(),eend=_edgesList.end(); + e!=eend; + e++) + { + (*e)->setVertexA((SVertex*)((*e)->vertexA()->userdata)); + (*e)->setVertexB((SVertex*)((*e)->vertexB()->userdata)); + (*e)->setNextEdge((FEdge*)((*e)->nextEdge()->userdata)); + (*e)->setPreviousEdge((FEdge*)((*e)->previousEdge()->userdata)); + } + + + // reset all brothers userdata to NULL: + //------------------------------------- + //--------- + // vertices + //--------- + for(sv=_verticesList.begin(),svend=_verticesList.end(); + sv!=svend; + sv++) + { + (*sv)->userdata = NULL; + } + + //------ + // edges + //------ + for(e=_edgesList.begin(),eend=_edgesList.end(); + e!=eend; + e++) + { + (*e)->userdata = NULL; + } + } + /*! Cloning method. */ + virtual SShape * duplicate() + { + SShape *clone = new SShape(*this); + return clone; + } + /*! Destructor. */ + virtual inline ~SShape() + { + vector<SVertex*>::iterator sv,svend; + vector<FEdge*>::iterator e,eend; + if(0 != _verticesList.size()) + { + for(sv=_verticesList.begin(),svend=_verticesList.end(); + sv!=svend; + sv++) + { + delete (*sv); + } + _verticesList.clear(); + } + + if(0 != _edgesList.size()) + { + for(e=_edgesList.begin(),eend=_edgesList.end(); + e!=eend; + e++) + { + delete (*e); + } + _edgesList.clear(); + } + + //! Clear the chains list + //----------------------- + if(0 != _chains.size()) + { + _chains.clear(); + } + } + + /*! Adds a FEdge to the list of FEdges. */ + inline void AddEdge(FEdge *iEdge) + { + _edgesList.push_back(iEdge); + } + + /*! Adds a SVertex to the list of SVertex of this Shape. + * The SShape attribute of the SVertex is also set to 'this'. + */ + inline void AddNewVertex(SVertex* iv) {iv->setShape(this);_verticesList.push_back(iv);} + inline void AddChain(FEdge *iEdge){ + _chains.push_back(iEdge); + } + + inline SVertex * CreateSVertex(const Vec3r& P3D, const Vec3r& P2D, const Id& id) + { + SVertex *Ia = new SVertex(P3D, id); + Ia->setPoint2D(P2D); + AddNewVertex(Ia); + return Ia; + } + /* splits an edge into several edges. + * The edge's vertices are passed rather than + * the edge itself. This way, all feature edges (SILHOUETTE, + * CREASE, BORDER) are splitted in the same time. + * The processed edges are flagged as done (using the userdata + * flag).One single new vertex is created whereas + * several splitted edges might created for the different + * kinds of edges. These new elements are added to the lists + * maintained by the shape. + * new chains are also created. + * ioA + * The first vertex for the edge that gets splitted + * ioB + * The second vertex for the edge that gets splitted + * iParameters + * A vector containing 2D real vectors indicating the parameters + * giving the intersections coordinates in 3D and in 2D. + * These intersections points must be sorted from B to A. + * Each parameter defines the intersection point I as I=A+T*AB. + * T<0 and T>1 are then incorrect insofar as they give intersections + * points that lie outside the segment. + * ioNewEdges + * The edges that are newly created (the initial edges are not + * included) are added to this list. + */ + inline void SplitEdge(FEdge *fe, const vector<Vec2r>& iParameters, vector<FEdge*>& ioNewEdges) + { + + SVertex *ioA = fe->vertexA(); + SVertex *ioB = fe->vertexB(); + Vec3r A = ioA->point3D(); + Vec3r B = ioB->point3D(); + Vec3r a = ioA->point2D(); + Vec3r b = ioB->point2D(); + SVertex *svA, *svB; + + Vec3r newpoint3d,newpoint2d; + vector<SVertex*> intersections; + real t,T; + for(vector<Vec2r>::const_iterator p=iParameters.begin(),pend=iParameters.end(); + p!=pend; + p++) + { + T=(*p)[0]; + t=(*p)[1]; + + if((t < 0) || (t > 1)) + cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - " << ioB->getId() << endl; + + // compute the 3D and 2D coordinates for the intersections points: + newpoint3d = Vec3r(A + T*(B-A)); + newpoint2d = Vec3r(a + t*(b-a)); + + // create new SVertex: + // (we keep B's id) + SVertex* newVertex = new SVertex(newpoint3d, ioB->getId()); + newVertex->setPoint2D(newpoint2d); + + // Add this vertex to the intersections list: + intersections.push_back(newVertex); + + // Add this vertex to this sshape: + AddNewVertex(newVertex); + } + + for(vector<SVertex*>::iterator sv=intersections.begin(),svend=intersections.end(); + sv!=svend; + sv++) + { + svA = fe->vertexA(); + svB = fe->vertexB(); + + // We split edge AB into AA' and A'B. A' and A'B are created. + // AB becomes (address speaking) AA'. B is updated. + //-------------------------------------------------- + // The edge AB becomes edge AA'. + (fe)->setVertexB((*sv)); + // a new edge, A'B is created. + FEdge *newEdge; + if(fe->isSmooth()){ + newEdge = new FEdgeSmooth((*sv), svB); + FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge); + FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe); + se->setFrsMaterialIndex(fes->frs_materialIndex()); + }else{ + newEdge = new FEdgeSharp((*sv), svB); + FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge); + FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(fe); + se->setaFrsMaterialIndex(fes->aFrsMaterialIndex()); + se->setbFrsMaterialIndex(fes->bFrsMaterialIndex()); + } + + newEdge->setNature((fe)->getNature()); + + + // to build a new chain: + AddChain(newEdge); + // add the new edge to the sshape edges list. + AddEdge(newEdge); + // add new edge to the list of new edges passed as argument: + ioNewEdges.push_back(newEdge); + + // update edge A'B for the next pointing edge + newEdge->setNextEdge((fe)->nextEdge()); + fe->nextEdge()->setPreviousEdge(newEdge); + Id id(fe->getId().getFirst(), fe->getId().getSecond()+1); + newEdge->setId(fe->getId()); + fe->setId(id); + + // update edge AA' for the next pointing edge + //ioEdge->setNextEdge(newEdge); + (fe)->setNextEdge(NULL); + + // update vertex pointing edges list: + // -- vertex B -- + svB->Replace((fe), newEdge); + // -- vertex A' -- + (*sv)->AddFEdge((fe)); + (*sv)->AddFEdge(newEdge); + } + + } + + /* splits an edge into 2 edges. The new vertex and edge are added + * to the sshape list of vertices and edges + * a new chain is also created. + * returns the new edge. + * ioEdge + * The edge that gets splitted + * newpoint + * x,y,z coordinates of the new point. + */ + inline FEdge* SplitEdgeIn2(FEdge* ioEdge, SVertex * ioNewVertex) + { + //soc unused - SVertex *A = ioEdge->vertexA(); + SVertex *B = ioEdge->vertexB(); + + + // We split edge AB into AA' and A'B. A' and A'B are created. + // AB becomes (address speaking) AA'. B is updated. + //-------------------------------------------------- + + // a new edge, A'B is created. + FEdge *newEdge; + if(ioEdge->isSmooth()){ + newEdge = new FEdgeSmooth(ioNewVertex, B); + FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge); + FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(ioEdge); + se->setFrsMaterialIndex(fes->frs_materialIndex()); + }else{ + newEdge = new FEdgeSharp(ioNewVertex, B); + FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge); + FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(ioEdge); + se->setaFrsMaterialIndex(fes->aFrsMaterialIndex()); + se->setbFrsMaterialIndex(fes->bFrsMaterialIndex()); + } + newEdge->setNature(ioEdge->getNature()); + + + if(ioEdge->nextEdge() != 0) + ioEdge->nextEdge()->setPreviousEdge(newEdge); + + // update edge A'B for the next pointing edge + newEdge->setNextEdge(ioEdge->nextEdge()); + // update edge A'B for the previous pointing edge + newEdge->setPreviousEdge(0); // because it is now a TVertex + Id id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond()+1); + newEdge->setId(ioEdge->getId()); + ioEdge->setId(id); + + // update edge AA' for the next pointing edge + ioEdge->setNextEdge(0); // because it is now a TVertex + + // update vertex pointing edges list: + // -- vertex B -- + B->Replace(ioEdge, newEdge); + // -- vertex A' -- + ioNewVertex->AddFEdge(ioEdge); + ioNewVertex->AddFEdge(newEdge); + + // to build a new chain: + AddChain(newEdge); + AddEdge(newEdge); // FIXME ?? + + // The edge AB becomes edge AA'. + ioEdge->setVertexB(ioNewVertex); + + if(ioEdge->isSmooth()){ + ((FEdgeSmooth*)newEdge)->setFace(((FEdgeSmooth*)ioEdge)->face()); + } + + return newEdge; + } + + /*! Sets the Bounding Box of the Shape */ + inline void setBBox(const BBox<Vec3r>& iBBox) {_BBox = iBBox;} + + /*! Compute the bbox of the sshape */ + inline void ComputeBBox() + { + if(0 == _verticesList.size()) + return; + + Vec3r firstVertex = _verticesList[0]->point3D(); + real XMax = firstVertex[0]; + real YMax = firstVertex[1]; + real ZMax = firstVertex[2]; + + real XMin = firstVertex[0]; + real YMin = firstVertex[1]; + real ZMin = firstVertex[2]; + + vector<SVertex*>::iterator v,vend; + // parse all the coordinates to find + // the Xmax, YMax, ZMax + for(v=_verticesList.begin(),vend=_verticesList.end(); + v!=vend; + v++) + { + Vec3r vertex = (*v)->point3D(); + // X + real x = vertex[0]; + if(x > XMax) + XMax = x; + if(x < XMin) + XMin = x; + + // Y + real y = vertex[1]; + if(y > YMax) + YMax = y; + if(y < YMin) + YMin = y; + + // Z + real z = vertex[2]; + if(z > ZMax) + ZMax = z; + if(z < ZMin) + ZMin = z; + } + + + setBBox(BBox<Vec3r>(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax))); + } + + inline void RemoveEdgeFromChain(FEdge *iEdge) + { + for(vector<FEdge*>::iterator fe=_chains.begin(), feend=_chains.end(); + fe!=feend; + fe++) + { + if(iEdge == (*fe)) + { + _chains.erase(fe); + break; + } + } + } + + inline void RemoveEdge(FEdge *iEdge) + { + for(vector<FEdge*>::iterator fe=_edgesList.begin(), feend=_edgesList.end(); + fe!=feend; + fe++) + { + if(iEdge == (*fe)) + { + _edgesList.erase(fe); + break; + } + } + } + + /* accessors */ + /*! Returns the list of SVertex of the Shape. */ + inline vector<SVertex*>& getVertexList() {return _verticesList;} // Get vertices list + /*! Returns the list of FEdges of the Shape. */ + inline vector<FEdge*>& getEdgeList() {return _edgesList;} // Get edges list + inline vector<FEdge*>& getChains() {return _chains;} + /*! Returns the bounding box of the shape. */ + inline const BBox<Vec3r>& bbox() {return _BBox;} + /*! Returns the ith material of the shape. */ + inline const FrsMaterial& frs_material(unsigned i) const {return _FrsMaterials[i];} + /*! Returns the list of materials of the Shape. */ + inline const vector<FrsMaterial>& frs_materials() const {return _FrsMaterials;} + inline ViewShape * viewShape() {return _ViewShape;} + inline float importance() const {return _importance;} + /*! Returns the Id of the Shape. */ + inline Id getId() const { return _Id; } + + /* Modififers */ + /*! Sets the Id of the shape.*/ + inline void setId(Id id) {_Id = id;} + /*! Sets the list of materials for the shape */ + inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials) {_FrsMaterials = iMaterials;} + inline void setViewShape(ViewShape *iShape) {_ViewShape = iShape;} + inline void setImportance(float importance){_importance = importance;} +}; + +#endif // SILHOUETTE_H diff --git a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp new file mode 100755 index 00000000000..f91318101a0 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.cpp @@ -0,0 +1,266 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "SilhouetteGeomEngine.h" +#include "Silhouette.h" +#include "../geometry/GeomUtils.h" + +using namespace std; + +Vec3r SilhouetteGeomEngine::_Viewpoint = Vec3r(0,0,0); +real SilhouetteGeomEngine::_translation[3] = {0,0,0}; +real SilhouetteGeomEngine::_modelViewMatrix[4][4] = {{1,0,0,0}, + {0,1,0,0}, + {0,0,1,0}, + {0,0,0,1}}; +real SilhouetteGeomEngine::_projectionMatrix[4][4] = {{1,0,0,0}, + {0,1,0,0}, + {0,0,1,0}, + {0,0,0,1}}; +real SilhouetteGeomEngine::_transform[4][4] = {{1,0,0,0}, + {0,1,0,0}, + {0,0,1,0}, + {0,0,0,1}}; +int SilhouetteGeomEngine::_viewport[4] = {1,1,1,1}; // the viewport +real SilhouetteGeomEngine::_Focal = 0.0; + +real SilhouetteGeomEngine::_glProjectionMatrix[4][4] = {{1,0,0,0}, + {0,1,0,0}, + {0,0,1,0}, + {0,0,0,1}}; +real SilhouetteGeomEngine::_glModelViewMatrix[4][4] = {{1,0,0,0}, + {0,1,0,0}, + {0,0,1,0}, + {0,0,0,1}}; +real SilhouetteGeomEngine::_znear = 0.0; +real SilhouetteGeomEngine::_zfar = 100.0; +bool SilhouetteGeomEngine::_isOrthographicProjection = false; + +SilhouetteGeomEngine * SilhouetteGeomEngine::_pInstance = 0; + +void SilhouetteGeomEngine::setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4], const int iViewport[4], real iFocal) +{ + unsigned int i,j; + _translation[0] = iModelViewMatrix[3][0]; + _translation[1] = iModelViewMatrix[3][1]; + _translation[2] = iModelViewMatrix[3][2]; + + for(i=0; i<4; i++){ + for(j=0; j<4; j++) + { + _modelViewMatrix[i][j] = iModelViewMatrix[j][i]; + _glModelViewMatrix[i][j] = iModelViewMatrix[i][j]; + } + } + + for(i=0; i<4; i++){ + for(j=0; j<4; j++) + { + _projectionMatrix[i][j] = iProjectionMatrix[j][i]; + _glProjectionMatrix[i][j] = iProjectionMatrix[i][j]; + } + } + + for(i=0; i<4; i++){ + for(j=0; j<4; j++) + { + _transform[i][j] = 0; + for(unsigned int k=0; k<4; k++) + _transform[i][j] += _projectionMatrix[i][k] * _modelViewMatrix[k][j]; + } + } + + for(i=0; i<4; i++){ + _viewport[i] = iViewport[i]; + } + _Focal = iFocal; + + _isOrthographicProjection = (iProjectionMatrix[3][3] != 0.0); +} + +void SilhouetteGeomEngine::setFrustum(real iZNear, real iZFar) +{ + _znear = iZNear; + _zfar = iZFar; +} + +void SilhouetteGeomEngine::retrieveViewport(int viewport[4]){ + memcpy(viewport, _viewport, 4*sizeof(int)); +} +//#define HUGE 1e9 + +void SilhouetteGeomEngine::ProjectSilhouette(vector<SVertex*>& ioVertices) +{ + Vec3r newPoint; + // real min=HUGE; + // real max=-HUGE; + vector<SVertex*>::iterator sv, svend; + + for(sv=ioVertices.begin(), svend=ioVertices.end(); + sv!=svend; + sv++) + { + GeomUtils::fromWorldToImage((*sv)->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport); + newPoint[2] = (-newPoint[2]-_znear)/(_zfar-_znear); // normalize Z between 0 and 1 + (*sv)->setPoint2D(newPoint); + //cerr << (*sv)->point2d().z() << " "; + // real d=(*sv)->point2d()[2]; + // if (d>max) max =d; + // if (d<min) min =d; + } + // for(sv=ioVertices.begin(), svend=ioVertices.end(); + // sv!=svend; + // sv++) + // { + // Vec3r P((*sv)->point2d()); + // (*sv)->setPoint2D(Vec3r(P[0], P[1], 1.0-(P[2]-min)/(max-min))); + // //cerr<<(*sv)->point2d()[2]<<" "; + // } +} + +void SilhouetteGeomEngine::ProjectSilhouette(SVertex* ioVertex) +{ + Vec3r newPoint; + // real min=HUGE; + // real max=-HUGE; + vector<SVertex*>::iterator sv, svend; + GeomUtils::fromWorldToImage(ioVertex->point3D(), newPoint, _modelViewMatrix, _projectionMatrix, _viewport); + newPoint[2] = (-newPoint[2]-_znear)/(_zfar-_znear); // normalize Z between 0 and 1 + ioVertex->setPoint2D(newPoint); +} + +real SilhouetteGeomEngine::ImageToWorldParameter(FEdge *fe, real t) +{ + if( _isOrthographicProjection ) + return t; + + // we need to compute for each parameter t the corresponding + // parameter T which gives the intersection in 3D. + real T; + + // suffix w for world, c for camera, r for retina, i for image + Vec3r Aw = (fe)->vertexA()->point3D(); + Vec3r Bw = (fe)->vertexB()->point3D(); + Vec3r Ac, Bc; + GeomUtils::fromWorldToCamera(Aw, Ac, _modelViewMatrix); + GeomUtils::fromWorldToCamera(Bw, Bc, _modelViewMatrix); + Vec3r ABc = Bc - Ac; +#if 0 + cout << "Ac " << Ac << endl; + cout << "Bc " << Bc << endl; + cout << "ABc " << ABc << endl; +#endif + Vec3r Ai = (fe)->vertexA()->point2D(); + Vec3r Bi = (fe)->vertexB()->point2D(); + Vec3r Ii = Ai + t * (Bi - Ai); // the intersection point in the 2D image space + Vec3r Ir, Ic; + GeomUtils::fromImageToRetina(Ii, Ir, _viewport); + + real alpha, beta, denom; + real m11 = _projectionMatrix[0][0]; + real m13 = _projectionMatrix[0][2]; + real m22 = _projectionMatrix[1][1]; + real m23 = _projectionMatrix[1][2]; + + if (fabs(ABc[0]) > 1e-6) { + + alpha = ABc[2] / ABc[0]; + beta = Ac[2] - alpha * Ac[0]; + denom = alpha * (Ir[0] + m13) + m11; + if (fabs(denom) < 1e-6) + goto iter; + Ic[0] = -beta * (Ir[0] + m13) / denom; +// Ic[1] = -(Ir[1] + m23) * (alpha * Ic[0] + beta) / m22; +// Ic[2] = alpha * (Ic[0] - Ac[0]) + Ac[2]; + T = (Ic[0] - Ac[0]) / ABc[0]; + + } else if (fabs(ABc[1]) > 1e-6) { + + alpha = ABc[2] / ABc[1]; + beta = Ac[2] - alpha * Ac[1]; + denom = alpha * (Ir[1] + m23) + m22; + if (fabs(denom) < 1e-6) + goto iter; + Ic[1] = -beta * (Ir[1] + m23) / denom; +// Ic[0] = -(Ir[0] + m13) * (alpha * Ic[1] + beta) / m11; +// Ic[2] = alpha * (Ic[1] - Ac[1]) + Ac[2]; + T = (Ic[1] - Ac[1]) / ABc[1]; + + } else { + +iter: bool x_coords, less_than; + if (fabs(Bi[0] - Ai[0]) > 1e-6) { + x_coords = true; + less_than = Ai[0] < Bi[0]; + } else { + x_coords = false; + less_than = Ai[1] < Bi[1]; + } + Vec3r Pc, Pr, Pi; + real T_sta = 0.0; + real T_end = 1.0; + real delta_x, delta_y, dist, dist_threshold = 1e-6; + int i, max_iters = 100; + for (i = 0; i < max_iters; i++) { + T = T_sta + 0.5 * (T_end - T_sta); + Pc = Ac + T * ABc; + GeomUtils::fromCameraToRetina(Pc, Pr, _projectionMatrix); + GeomUtils::fromRetinaToImage(Pr, Pi, _viewport); + delta_x = Ii[0] - Pi[0]; + delta_y = Ii[1] - Pi[1]; + dist = sqrt(delta_x * delta_x + delta_y * delta_y); + if (dist < dist_threshold) + break; + if (x_coords) { + if (less_than) { + if (Pi[0] < Ii[0]) { T_sta = T; } else { T_end = T; } + } else { + if (Pi[0] > Ii[0]) { T_sta = T; } else { T_end = T; } + } + } else { + if (less_than) { + if (Pi[1] < Ii[1]) { T_sta = T; } else { T_end = T; } + } else { + if (Pi[1] > Ii[1]) { T_sta = T; } else { T_end = T; } + } + } + } +#if 0 + printf("SilhouetteGeomEngine::ImageToWorldParameter(): #iters = %d, dist = %e\n", i, dist); +#endif + if (i == max_iters) + printf("SilhouetteGeomEngine::ImageToWorldParameter(): reached to max_iters (dist = %e)\n", dist); + } + + return T; +} + +Vec3r SilhouetteGeomEngine::WorldToImage(const Vec3r& M) + +{ + + Vec3r newPoint; + GeomUtils::fromWorldToImage(M, newPoint, _transform, _viewport); + newPoint[2] = (-newPoint[2]-_znear)/(_zfar-_znear); // normalize Z between 0 and 1 + return newPoint; + +} + diff --git a/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h new file mode 100755 index 00000000000..5bd89f8a162 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/SilhouetteGeomEngine.h @@ -0,0 +1,123 @@ +// +// Filename : SilhouetteGeomEngine.h +// Author(s) : Stephane Grabli +// Purpose : Class to perform all geometric operations dedicated +// to silhouette. That, for example, implies that +// this geom engine has as member data the viewpoint, +// transformations, projections... +// Date of creation : 03/09/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef SILHOUETTEGEOMENGINE_H +# define SILHOUETTEGEOMENGINE_H + +# include <vector> +# include "../system/FreestyleConfig.h" +# include "../geometry/Geom.h" + +using namespace Geometry; + +class SVertex; +class FEdge; + +class LIB_VIEW_MAP_EXPORT SilhouetteGeomEngine +{ +private: + static Vec3r _Viewpoint; // The viewpoint under which the silhouette has to be computed + static real _translation[3]; + static real _modelViewMatrix[4][4]; // the model view matrix (_modelViewMatrix[i][j] means element of line i and column j) + static real _projectionMatrix[4][4]; // the projection matrix (_projectionMatrix[i][j] means element of line i and column j) + static real _transform[4][4]; // the global transformation from world to screen (projection included) (_transform[i][j] means element of line i and column j) + static int _viewport[4]; // the viewport + static real _Focal; + + static real _znear; + static real _zfar; + + static real _glProjectionMatrix[4][4]; // GL style (column major) projection matrix + static real _glModelViewMatrix[4][4]; // GL style (column major) model view matrix + +static bool _isOrthographicProjection; + + + static SilhouetteGeomEngine *_pInstance; +public: + + /*! retrieves an instance on the singleton */ + static SilhouetteGeomEngine * getInstance() + { + if(0 == _pInstance) + { + _pInstance = new SilhouetteGeomEngine; + } + return _pInstance; + } + + /*! Sets the current viewpoint */ + static inline void setViewpoint(const Vec3r& ivp) {_Viewpoint = ivp;} + + /*! Sets the current transformation + * iModelViewMatrix + * The 4x4 model view matrix, in column major order (openGL like). + * iProjection matrix + * The 4x4 projection matrix, in column major order (openGL like). + * iViewport + * The viewport. 4 real array: origin.x, origin.y, width, length + * iFocal + * The focal length + */ + static void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4], const int iViewport[4], real iFocal) ; + + /*! Sets the current znear and zfar + */ + static void setFrustum(real iZNear, real iZFar) ; + + /* accessors */ + static void retrieveViewport(int viewport[4]); + + /*! Projects the silhouette in camera coordinates + * This method modifies the ioEdges passed as argument. + * ioVertices + * The vertices to project. It is modified during the + * operation. + */ + static void ProjectSilhouette(std::vector<SVertex*>& ioVertices); + static void ProjectSilhouette(SVertex* ioVertex); + + /*! transforms the parameter t defining a 2D intersection for edge fe in order to obtain + * the parameter giving the corresponding 3D intersection. + * Returns the 3D parameter + * fe + * The edge + * t + * The parameter for the 2D intersection. + */ + static real ImageToWorldParameter(FEdge *fe, real t); + + /*! From world to image */ + static Vec3r WorldToImage(const Vec3r& M); +}; + +#endif // SILHOUETTEGEOMENGINE_H diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp new file mode 100755 index 00000000000..13c6bd65312 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp @@ -0,0 +1,268 @@ +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "SteerableViewMap.h" +#include "../image/ImagePyramid.h" +#include "../image/Image.h" +#include "Silhouette.h" +#include <math.h> +#include "../geometry/Geom.h" +using namespace Geometry; + +//soc #include <qstring.h> +//soc #include <qimage.h> +#include <sstream> + +extern "C" { +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +#include "intern/IMB_png.h" +} + +SteerableViewMap::SteerableViewMap(unsigned int nbOrientations){ + _nbOrientations = nbOrientations; + _bound = cos(M_PI/(float)_nbOrientations); + for(unsigned i=0; i<_nbOrientations; ++i){ + _directions.push_back(Vec2d(cos((float)i*M_PI/(float)_nbOrientations), sin((float)i*M_PI/(float)_nbOrientations))); + } + Build(); +} + +void SteerableViewMap::Build(){ + _imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM + memset((_imagesPyramids),0,(_nbOrientations+1)*sizeof(ImagePyramid*)); +} + +SteerableViewMap::SteerableViewMap(const SteerableViewMap& iBrother){ + _nbOrientations = iBrother._nbOrientations; + unsigned i; + _bound = iBrother._bound; + _directions = iBrother._directions; + _mapping = iBrother._mapping; + _imagesPyramids = new ImagePyramid*[_nbOrientations+1]; // one more map to store the complete visible VM + for(i=0;i<_nbOrientations+1;++i) + _imagesPyramids[i] = new GaussianPyramid(*(dynamic_cast<GaussianPyramid*>(iBrother._imagesPyramids[i]))); +} + +SteerableViewMap::~SteerableViewMap(){ + Clear(); +} + +void SteerableViewMap::Clear(){ + unsigned i; + if(_imagesPyramids){ + for(i=0; i<=_nbOrientations; ++i){ + if(_imagesPyramids[i]) + delete (_imagesPyramids)[i]; + } + delete [] _imagesPyramids; + _imagesPyramids = 0; + } + if(!_mapping.empty()){ + for(map<unsigned int, double*>::iterator m=_mapping.begin(), mend=_mapping.end(); + m!=mend; + ++m){ + delete [] (*m).second; + } + _mapping.clear(); + } +} + +void SteerableViewMap::Reset(){ + Clear(); + Build(); +} + +double SteerableViewMap::ComputeWeight(const Vec2d& dir, unsigned i){ + double dotp = fabs(dir*_directions[i]); + if(dotp < _bound) + return 0; + if(dotp>1) + dotp = 1; + + return cos((float)_nbOrientations/2.0*acos(dotp)); +} + +double * SteerableViewMap::AddFEdge(FEdge *iFEdge){ + unsigned i; + unsigned id = iFEdge->getId().getFirst(); + map<unsigned int, double* >::iterator o = _mapping.find(id); + if(o!=_mapping.end()){ + return (*o).second; + } + double * res = new double[_nbOrientations]; + for(i=0; i<_nbOrientations; ++i){ + res[i] = 0; + } + Vec3r o2d3 = iFEdge->orientation2d(); + Vec2r o2d2(o2d3.x(), o2d3.y()); + real norm = o2d2.norm(); + if(norm < 1e-6){ + return res; + } + o2d2/=norm; + + for(i=0; i<_nbOrientations; ++i){ + res[i] = ComputeWeight(o2d2, i); + } + _mapping[id] = res; + return res; +} + +unsigned SteerableViewMap::getSVMNumber(const Vec2f& orient){ + Vec2f dir(orient); + //soc unsigned res = 0; + real norm = dir.norm(); + if(norm < 1e-6){ + return _nbOrientations+1; + } + dir/=norm; + double maxw = 0.f; + unsigned winner = _nbOrientations+1; + for(unsigned i=0; i<_nbOrientations; ++i){ + double w = ComputeWeight(dir, i); + if(w>maxw){ + maxw = w; + winner = i; + } + } + return winner; +} + + +unsigned SteerableViewMap::getSVMNumber(unsigned id){ + map<unsigned int, double* >::iterator o = _mapping.find(id); + if(o!=_mapping.end()){ + double* wvalues= (*o).second; + double maxw = 0.f; + unsigned winner = _nbOrientations+1; + for(unsigned i=0; i<_nbOrientations; ++i){ + double w = wvalues[i]; + if(w>maxw){ + maxw = w; + winner = i; + } + } + return winner; + } + return _nbOrientations+1; +} + +void SteerableViewMap::buildImagesPyramids(GrayImage **steerableBases, bool copy, unsigned iNbLevels, float iSigma){ + for(unsigned i=0; i<=_nbOrientations; ++i){ + ImagePyramid * svm = (_imagesPyramids)[i]; + if(svm) + delete svm; + if(copy) + svm = new GaussianPyramid(*(steerableBases[i]), iNbLevels, iSigma); + else + svm = new GaussianPyramid(steerableBases[i], iNbLevels, iSigma); + _imagesPyramids[i] = svm; + } +} + +float SteerableViewMap::readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y){ + ImagePyramid *pyramid = _imagesPyramids[iOrientation]; + if(pyramid==0){ + cout << "Warning: this steerable ViewMap level doesn't exist" << endl; + return 0; + } + if((x<0) || (x>=pyramid->width()) || (y<0) || (y>=pyramid->height())) + return 0; + //float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)*255.f; + float v = pyramid->pixel(x,pyramid->height()-1-y,iLevel)/32.f; // we encode both the directionality and the lines counting on 8 bits + // (because of frame buffer). Thus, we allow until 8 lines to pass through + // the same pixel, so that we can discretize the Pi/_nbOrientations angle into + // 32 slices. Therefore, for example, in the vertical direction, a vertical line + // will have the value 32 on each pixel it passes through. + return v; +} + +float SteerableViewMap::readCompleteViewMapPixel(int iLevel, int x, int y){ + return readSteerableViewMapPixel(_nbOrientations,iLevel,x,y); +} + +unsigned int SteerableViewMap::getNumberOfPyramidLevels() const{ + if(_imagesPyramids[0]) + return _imagesPyramids[0]->getNumberOfLevels(); + return 0; +} + +void SteerableViewMap::saveSteerableViewMap() const { + for(unsigned i=0; i<=_nbOrientations; ++i){ + if(_imagesPyramids[i] == 0){ + cerr << "SteerableViewMap warning: orientation " << i <<" of steerable View Map whas not been computed yet" << endl; + continue; + } + int ow = _imagesPyramids[i]->width(0); + int oh = _imagesPyramids[i]->height(0); + + //soc QString base("SteerableViewMap"); + string base("SteerableViewMap"); + stringstream filename; + + for(int j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ //soc + float coeff = 1;//1/255.f; //100*255;//*pow(2,j); + //soc QImage qtmp(ow, oh, QImage::Format_RGB32); + ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect, 0); + int rowbytes = ow*4; + char *pix; + + for(int y=0;y<oh;++y){ //soc + for(int x=0;x<ow;++x){ //soc + int c = (int)(coeff*_imagesPyramids[i]->pixel(x,y,j)); + if(c>255) + c=255; + //int c = (int)(_imagesPyramids[i]->pixel(x,y,j)); + + //soc qtmp.setPixel(x,y,qRgb(c,c,c)); + pix = (char*)ibuf->rect + y*rowbytes + x*4; + pix[0] = pix [1] = pix[2] = c; + } + } + + //soc qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG"); + filename << base; + filename << i << "-" << j << ".png"; + + imb_savepng(ibuf, const_cast<char *>(filename.str().c_str()), 0); + + } + // QString base("SteerableViewMap"); + // for(unsigned j=0; j<_imagesPyramids[i]->getNumberOfLevels(); ++j){ + // GrayImage * img = _imagesPyramids[i]->getLevel(j); + // int ow = img->width(); + // int oh = img->height(); + // float coeff = 1; //100*255;//*pow(2,j); + // QImage qtmp(ow, oh, 32); + // for(unsigned y=0;y<oh;++y){ + // for(unsigned x=0;x<ow;++x){ + // int c = (int)(coeff*img->pixel(x,y)); + // if(c>255) + // c=255; + // //int c = (int)(_imagesPyramids[i]->pixel(x,y,j)); + // qtmp.setPixel(x,y,qRgb(c,c,c)); + // } + // } + // qtmp.save(base+QString::number(i)+"-"+QString::number(j)+".png", "PNG"); + // } + // + } +} diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.h b/source/blender/freestyle/intern/view_map/SteerableViewMap.h new file mode 100755 index 00000000000..fe7c2493752 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.h @@ -0,0 +1,153 @@ +// +// Filename : SteerbaleViewMap.h +// Author(s) : Stephane Grabli +// Purpose : Convenient access to the steerable ViewMap +// to which any element of the ViewMap belongs to. +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef STEERABLEVIEWMAP_H +# define STEERABLEVIEWMAP_H + +#include <map> +#include "../system/FreestyleConfig.h" +#include "../geometry/Geom.h" +using namespace Geometry; + +using namespace std; + +class FEdge; +class ImagePyramid; +class GrayImage; +/*! This class checks for every FEdge in which steerable + * it belongs and stores the mapping allowing to retrieve + * this information from the FEdge Id + */ +class LIB_VIEW_MAP_EXPORT SteerableViewMap{ +protected: + map<unsigned int, double* > _mapping; // for each vector the list of nbOrientations weigths corresponding to its contributions to the nbOrientations directional maps + unsigned _nbOrientations; + ImagePyramid **_imagesPyramids; // the pyramids of images storing the different SVM + + // internal + double _bound; // cos(Pi/N) + vector<Vec2d> _directions; + +public: + SteerableViewMap(unsigned int nbOrientations = 4); + SteerableViewMap(const SteerableViewMap& iBrother); + virtual ~SteerableViewMap(); + + /*! Resets everything */ + virtual void Reset(); + + /*! Adds a FEdge to steerable VM. + * Returns the nbOrientations weigths corresponding to + * the FEdge contributions to the nbOrientations directional maps. + */ + double* AddFEdge(FEdge *iFEdge); + + /*! Compute the weight of direction dir for orientation iNOrientation */ + double ComputeWeight(const Vec2d& dir, unsigned iNOrientation); + + /*! Returns the number of the SVM to which a direction belongs + * to. + * \param dir + * The direction + */ + unsigned getSVMNumber(const Vec2f& dir); + + /*! Returns the number of the SVM to which a FEdge belongs + * most. + * \param id + * The First element of the Id struct of the FEdge + * we're intersted in. + */ + unsigned getSVMNumber(unsigned id); + + /*! Builds _nbOrientations+1 pyramids of images from the _nbOrientations+1 base images + * of the steerable viewmap. + * \param steerableBases + * The _nbOrientations+1 images constituing the basis for the steerable + * pyramid. + * \param copy + * If false, the data is not duplicated, and Canvas deals + * with the memory management of these _nbOrientations+1 images. If true, data + * is copied, and it's up to the caller to delete the images. + * \params iNbLevels + * The number of levels desired for each pyramid. + * If iNbLevels == 0, the complete pyramid is built. + * \param iSigma + * The sigma that will be used for the gaussian blur + */ + void buildImagesPyramids(GrayImage **steerableBases, bool copy = false, unsigned iNbLevels=4, float iSigma = 1.f); + + /*! Reads a pixel value in one of the VewMap density steerable pyramids. + * Returns a value between 0 and 1. + * \param iOrientation + * the number telling which orientation we need to check. + * There are _nbOrientations+1 oriented ViewMaps: + * 0 -> the ViewMap containing every horizontal lines + * 1 -> the ViewMap containing every lines whose orientation is around PI/4 + * 2 -> the ViewMap containing every vertical lines + * 3 -> the ViewMap containing every lines whose orientation is around 3PI/4 + * 4 -> the complete ViewMap + * \param iLevel + * The level of the pyramid we want to read + * \param x + * The abscissa of the desired pixel specified in level0 coordinate + * system. The origin is the lower left corner. + * \param y + * The ordinate of the desired pixel specified in level0 coordinate + * system. The origin is the lower left corner. + */ + float readSteerableViewMapPixel(unsigned iOrientation, int iLevel, int x, int y); + + /*! Reads a pixel in the one of the level of the + * pyramid containing the images of the complete + * ViewMap. + * Returns a value between 0 and 1. + * Equivalent to : readSteerableViewMapPixel(nbOrientations, x,y) + */ + float readCompleteViewMapPixel(int iLevel, int x, int y); + + /*! Returns the number of levels in the pyramids */ + unsigned int getNumberOfPyramidLevels() const; + + /*! Returns the number of orientations */ + unsigned int getNumberOfOrientations() const{ + return _nbOrientations; + } + + /*! for debug purposes */ + void saveSteerableViewMap() const ; + +protected: + void Clear(); + void Build(); + + +}; + +#endif // STEERABLEVIEWMAP_H diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp new file mode 100755 index 00000000000..5f7b313aaf6 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp @@ -0,0 +1,666 @@ +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "ViewEdgeXBuilder.h" +#include "../winged_edge/WXEdge.h" +#include "ViewMap.h" +#include "SilhouetteGeomEngine.h" +#include <list> + +using namespace std; + +void ViewEdgeXBuilder::Init(ViewShape *oVShape){ + if(0 == oVShape) + return; + + // for design conveniance, we store the current SShape. + _pCurrentSShape = oVShape->sshape(); + if(0 == _pCurrentSShape) + return; + + _pCurrentVShape = oVShape; + + // Reset previous data + //-------------------- + if(!_SVertexMap.empty()) + _SVertexMap.clear(); +} + +void ViewEdgeXBuilder::BuildViewEdges( WXShape *iWShape, ViewShape *oVShape, + vector<ViewEdge*>& ioVEdges, + vector<ViewVertex*>& ioVVertices, + vector<FEdge*>& ioFEdges, + vector<SVertex*>& ioSVertices){ + // Reinit structures + Init(oVShape); + + ViewEdge *vedge ; + // Let us build the smooth stuff + //---------------------------------------- + // We parse all faces to find the ones + // that contain smooth edges + vector<WFace*>& wfaces = iWShape->GetFaceList(); + vector<WFace*>::iterator wf, wfend; + WXFace *wxf; + for(wf=wfaces.begin(), wfend=wfaces.end(); + wf!=wfend; + wf++){ + wxf = dynamic_cast<WXFace*>(*wf); + if(false == ((wxf))->hasSmoothEdges()) // does it contain at least one smooth edge ? + continue; + // parse all smooth layers: + vector<WXFaceLayer*>& smoothLayers = wxf->getSmoothLayers(); + for(vector<WXFaceLayer*>::iterator sl = smoothLayers.begin(), slend=smoothLayers.end(); + sl!=slend; + ++sl){ + if(!(*sl)->hasSmoothEdge()) + continue; + if(stopSmoothViewEdge((*sl))) // has it been parsed already ? + continue; + // here we know that we're dealing with a face layer that has not been + // processed yet and that contains a smooth edge. + vedge = BuildSmoothViewEdge(OWXFaceLayer(*sl, true)); + } + } + + // Now let's build sharp view edges: + //---------------------------------- + // Reset all userdata for WXEdge structure + //---------------------------------------- + //iWShape->ResetUserData(); + + WXEdge * wxe; + vector<WEdge*>& wedges = iWShape->getEdgeList(); + // + //------------------------------ + for(vector<WEdge*>::iterator we=wedges.begin(),weend=wedges.end(); + we!=weend; + we++){ + wxe = dynamic_cast<WXEdge*>(*we); + if(Nature::NO_FEATURE == wxe->nature()) + continue; + + if(!stopSharpViewEdge(wxe)){ + bool b=true; + if(wxe->order() == -1) + b = false; + BuildSharpViewEdge(OWXEdge(wxe,b)); + } + } + + // Reset all userdata for WXEdge structure + //---------------------------------------- + iWShape->ResetUserData(); + + // Add all these new edges to the scene's feature edges list: + //----------------------------------------------------------- + vector<FEdge*>& newedges = _pCurrentSShape->getEdgeList(); + vector<SVertex*>& newVertices = _pCurrentSShape->getVertexList(); + vector<ViewVertex*>& newVVertices = _pCurrentVShape->vertices(); + vector<ViewEdge*>& newVEdges = _pCurrentVShape->edges(); + + // inserts in ioFEdges, at its end, all the edges of newedges + ioFEdges.insert(ioFEdges.end(), newedges.begin(), newedges.end()); + ioSVertices.insert(ioSVertices.end(), newVertices.begin(), newVertices.end()); + ioVVertices.insert(ioVVertices.end(), newVVertices.begin(), newVVertices.end()); + ioVEdges.insert(ioVEdges.end(), newVEdges.begin(), newVEdges.end()); + +} + +ViewEdge * ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer){ + // Find first edge: + OWXFaceLayer first = iFaceLayer; + OWXFaceLayer currentFace = first; + + // bidirectional chaining. + // first direction + list<OWXFaceLayer> facesChain; + unsigned size = 0; + while(!stopSmoothViewEdge(currentFace.fl)){ + facesChain.push_back(currentFace); + ++size; + currentFace.fl->userdata = (void*)1; // processed + // Find the next edge! + currentFace = FindNextFaceLayer(currentFace); + } + OWXFaceLayer end = facesChain.back(); + // second direction + currentFace = FindPreviousFaceLayer(first); + while(!stopSmoothViewEdge(currentFace.fl)){ + facesChain.push_front(currentFace); + ++size; + currentFace.fl->userdata = (void*)1; // processed + // Find the previous edge! + currentFace = FindPreviousFaceLayer(currentFace); + } + first = facesChain.front(); + + if(iFaceLayer.fl->nature() & Nature::RIDGE){ + if(size<4){ + return 0; + } + } + + // Start a new chain edges + ViewEdge * newVEdge = new ViewEdge; + newVEdge->setId(_currentViewId); + ++_currentViewId; + + _pCurrentVShape->AddEdge(newVEdge); + + + // build FEdges + FEdge * feprevious = 0; + FEdge * fefirst = 0; + FEdge * fe = 0; + for(list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend=facesChain.end(); + fl!=flend; + ++fl){ + fe = BuildSmoothFEdge(feprevious, (*fl)); + fe->setViewEdge(newVEdge); + if(!fefirst) + fefirst = fe; + feprevious = fe; + } + // Store the chain starting edge: + _pCurrentSShape->AddChain(fefirst); + newVEdge->setNature(iFaceLayer.fl->nature()); + newVEdge->setFEdgeA(fefirst); + newVEdge->setFEdgeB(fe); + + // is it a closed loop ? + if((first == end) && (size != 1)){ + fefirst->setPreviousEdge(fe); + fe->setNextEdge(fefirst); + newVEdge->setA(0); + newVEdge->setB(0); + }else{ + ViewVertex *vva = MakeViewVertex(fefirst->vertexA()); + ViewVertex *vvb = MakeViewVertex(fe->vertexB()); + + ((NonTVertex*)vva)->AddOutgoingViewEdge(newVEdge); + ((NonTVertex*)vvb)->AddIncomingViewEdge(newVEdge); + + newVEdge->setA(vva); + newVEdge->setB(vvb); + } + + return newVEdge; +} + +ViewEdge * ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge) { + // Start a new sharp chain edges + ViewEdge * newVEdge = new ViewEdge; + newVEdge->setId(_currentViewId); + ++_currentViewId; + unsigned size=0; + + _pCurrentVShape->AddEdge(newVEdge); + + // Find first edge: + OWXEdge firstWEdge = iWEdge; + OWXEdge previousWEdge = firstWEdge; + OWXEdge currentWEdge = firstWEdge; + list<OWXEdge> edgesChain; + // bidirectional chaining + // first direction: + while(!stopSharpViewEdge(currentWEdge.e)){ + edgesChain.push_back(currentWEdge); + ++size; + currentWEdge.e->userdata = (void*)1; // processed + // Find the next edge! + currentWEdge = FindNextWEdge(currentWEdge); + } + OWXEdge endWEdge = edgesChain.back(); + // second direction + currentWEdge = FindPreviousWEdge(firstWEdge); + while(!stopSharpViewEdge(currentWEdge.e)){ + edgesChain.push_front(currentWEdge); + ++size; + currentWEdge.e->userdata = (void*)1; // processed + // Find the previous edge! + currentWEdge = FindPreviousWEdge(currentWEdge); + } + firstWEdge = edgesChain.front(); + + // build FEdges + FEdge * feprevious = 0; + FEdge * fefirst = 0; + FEdge * fe = 0; + for(list<OWXEdge>::iterator we = edgesChain.begin(), weend=edgesChain.end(); + we!=weend; + ++we){ + fe = BuildSharpFEdge(feprevious, (*we)); + fe->setViewEdge(newVEdge); + if(!fefirst) + fefirst = fe; + feprevious = fe; + } + // Store the chain starting edge: + _pCurrentSShape->AddChain(fefirst); + newVEdge->setNature(iWEdge.e->nature()); + newVEdge->setFEdgeA(fefirst); + newVEdge->setFEdgeB(fe); + + // is it a closed loop ? + if((firstWEdge == endWEdge) && (size!=1)){ + fefirst->setPreviousEdge(fe); + fe->setNextEdge(fefirst); + newVEdge->setA(0); + newVEdge->setB(0); + }else{ + ViewVertex *vva = MakeViewVertex(fefirst->vertexA()); + ViewVertex *vvb = MakeViewVertex(fe->vertexB()); + + ((NonTVertex*)vva)->AddOutgoingViewEdge(newVEdge); + ((NonTVertex*)vvb)->AddIncomingViewEdge(newVEdge); + + newVEdge->setA(vva); + newVEdge->setB(vvb); + } + + return newVEdge; +} + +OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer& iFaceLayer){ + WXFace *nextFace = 0; + WOEdge * woeend; + real tend; + if(iFaceLayer.order){ + woeend = iFaceLayer.fl->getSmoothEdge()->woeb(); + tend = iFaceLayer.fl->getSmoothEdge()->tb(); + }else{ + woeend = iFaceLayer.fl->getSmoothEdge()->woea(); + tend = iFaceLayer.fl->getSmoothEdge()->ta(); + } + // special case of EDGE_VERTEX config: + if((tend == 0.0) || (tend == 1.0)){ + WVertex *nextVertex; + if(tend == 0.0) + nextVertex = woeend->GetaVertex(); + else + nextVertex = woeend->GetbVertex(); + if(nextVertex->isBoundary()) // if it's a non-manifold vertex -> ignore + return OWXFaceLayer(0,true); + bool found = false; + WVertex::face_iterator f=nextVertex->faces_begin(); + WVertex::face_iterator fend=nextVertex->faces_end(); + while((!found) && (f!=fend)){ + nextFace = dynamic_cast<WXFace*>(*f); + if((0 != nextFace) && (nextFace!=iFaceLayer.fl->getFace())){ + vector<WXFaceLayer*> sameNatureLayers; + nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers); + if(sameNatureLayers.size() == 1) {// don't know + // maybe should test whether this face has + // also a vertex_edge configuration + WXFaceLayer * winner = sameNatureLayers[0]; + if(woeend == winner->getSmoothEdge()->woea()->twin()) + return OWXFaceLayer(winner,true); + else + return OWXFaceLayer(winner,false); + } + } + ++f; + } + }else{ + nextFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woeend)); + if(0 == nextFace) + return OWXFaceLayer(0,true); + // if the next face layer has either no smooth edge or + // no smooth edge of same nature, no next face + if(!nextFace->hasSmoothEdges()) + return OWXFaceLayer(0,true); + vector<WXFaceLayer*> sameNatureLayers; + nextFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers); + if((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) // don't know how to deal with several edges of same nature on a single face + return OWXFaceLayer(0,true); + else{ + WXFaceLayer * winner = sameNatureLayers[0]; + if(woeend == winner->getSmoothEdge()->woea()->twin()) + return OWXFaceLayer(winner,true); + else + return OWXFaceLayer(winner,false); + } + } + return OWXFaceLayer(0,true); +} + +OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer) { + WXFace *previousFace = 0; + WOEdge * woebegin; + real tend; + if(iFaceLayer.order){ + woebegin = iFaceLayer.fl->getSmoothEdge()->woea(); + tend = iFaceLayer.fl->getSmoothEdge()->ta(); + }else{ + woebegin = iFaceLayer.fl->getSmoothEdge()->woeb(); + tend = iFaceLayer.fl->getSmoothEdge()->tb(); + } + + // special case of EDGE_VERTEX config: + if((tend == 0.0) || (tend == 1.0)){ + WVertex *previousVertex; + if(tend == 0.0) + previousVertex = woebegin->GetaVertex(); + else + previousVertex = woebegin->GetbVertex(); + if(previousVertex->isBoundary()) // if it's a non-manifold vertex -> ignore + return OWXFaceLayer(0,true); + bool found = false; + WVertex::face_iterator f=previousVertex->faces_begin(); + WVertex::face_iterator fend=previousVertex->faces_end(); + while((!found) && (f!=fend)){ + previousFace = dynamic_cast<WXFace*>(*f); + if((0 != previousFace) && (previousFace!=iFaceLayer.fl->getFace())){ + vector<WXFaceLayer*> sameNatureLayers; + previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers); + if(sameNatureLayers.size() == 1) {// don't know + // maybe should test whether this face has + // also a vertex_edge configuration + WXFaceLayer * winner = sameNatureLayers[0]; + if(woebegin == winner->getSmoothEdge()->woeb()->twin()) + return OWXFaceLayer(winner,true); + else + return OWXFaceLayer(winner,false); + } + } + ++f; + } + }else{ + previousFace = dynamic_cast<WXFace*>(iFaceLayer.fl->getFace()->GetBordingFace(woebegin)); + if(0 == previousFace) + return OWXFaceLayer(0,true); + + // if the next face layer has either no smooth edge or + // no smooth edge of same nature, no next face + if(!previousFace->hasSmoothEdges()) + return OWXFaceLayer(0,true); + vector<WXFaceLayer*> sameNatureLayers; + previousFace->retrieveSmoothEdgesLayers(iFaceLayer.fl->nature(), sameNatureLayers); + if((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) // don't know how to deal with several edges of same nature on a single face + return OWXFaceLayer(0,true); + else{ + WXFaceLayer * winner = sameNatureLayers[0]; + if(woebegin == winner->getSmoothEdge()->woeb()->twin()) + return OWXFaceLayer(winner,true); + else + return OWXFaceLayer(winner,false); + } + } + return OWXFaceLayer(0,true); +} + +FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl){ + SVertex *va, *vb; + FEdgeSmooth *fe; + // retrieve exact silhouette data + WXSmoothEdge *se = ifl.fl->getSmoothEdge(); + + Vec3r normal; + // Make the 2 Svertices + if(feprevious == 0){ // that means that we don't have any vertex already built for that face + real ta = se->ta(); + Vec3r A1(se->woea()->GetaVertex()->GetVertex()); + Vec3r A2(se->woea()->GetbVertex()->GetVertex()); + Vec3r A(A1+ta*(A2-A1)); + + va = MakeSVertex(A); + // Set normal: + Vec3r NA1(ifl.fl->getFace()->GetVertexNormal(se->woea()->GetaVertex())); + Vec3r NA2(ifl.fl->getFace()->GetVertexNormal(se->woea()->GetbVertex())); + Vec3r na((1 - ta) * NA1 + ta * NA2); + na.normalize(); + va->AddNormal(na); + normal = na; + + // Set CurvatureInfo + CurvatureInfo* curvature_info_a = new CurvatureInfo(*(dynamic_cast<WXVertex*>(se->woea()->GetaVertex())->curvatures()), + *(dynamic_cast<WXVertex*>(se->woea()->GetbVertex())->curvatures()), + ta); + va->setCurvatureInfo(curvature_info_a); + } + else + va = feprevious->vertexB(); + + real tb = se->tb(); + Vec3r B1(se->woeb()->GetaVertex()->GetVertex()); + Vec3r B2(se->woeb()->GetbVertex()->GetVertex()); + Vec3r B(B1+tb*(B2-B1)); + + vb = MakeSVertex(B); + // Set normal: + Vec3r NB1(ifl.fl->getFace()->GetVertexNormal(se->woeb()->GetaVertex())); + Vec3r NB2(ifl.fl->getFace()->GetVertexNormal(se->woeb()->GetbVertex())); + Vec3r nb((1 - tb) * NB1 + tb * NB2); + nb.normalize(); + normal += nb; + vb->AddNormal(nb); + + // Set CurvatureInfo + CurvatureInfo* curvature_info_b = new CurvatureInfo(*(dynamic_cast<WXVertex*>(se->woeb()->GetaVertex())->curvatures()), + *(dynamic_cast<WXVertex*>(se->woeb()->GetbVertex())->curvatures()), + tb); + vb->setCurvatureInfo(curvature_info_b); + + // if the order is false we must swap va and vb + if(!ifl.order){ + SVertex *tmp = va; + va = vb; + vb = tmp; + } + + // Creates the corresponding feature edge + fe = new FEdgeSmooth(va, vb); + fe->setNature(ifl.fl->nature()); + fe->setId(_currentFId); + fe->setFrsMaterialIndex(ifl.fl->getFace()->frs_materialIndex()); + fe->setFace(ifl.fl->getFace()); + fe->setNormal(normal); + fe->setPreviousEdge(feprevious); + if(feprevious) + feprevious->setNextEdge(fe); + _pCurrentSShape->AddEdge(fe); + va->AddFEdge(fe); + vb->AddFEdge(fe); + + ++_currentFId; + ifl.fl->userdata = fe; + return fe; +} + +bool ViewEdgeXBuilder::stopSmoothViewEdge(WXFaceLayer *iFaceLayer){ + if(0 == iFaceLayer) + return true; + if(iFaceLayer->userdata == 0) + return false; + return true; +} + +OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge& iEdge){ + if(Nature::NO_FEATURE == iEdge.e->nature()) + return OWXEdge(0, true); + + WVertex *v; + if(true == iEdge.order) + v = iEdge.e->GetbVertex(); + else + v = iEdge.e->GetaVertex(); + + if(((WXVertex*)v)->isFeature()) + return 0; + + + vector<WEdge*>& vEdges = (v)->GetEdges(); + for(vector<WEdge*>::iterator ve=vEdges.begin(),veend=vEdges.end(); + ve!=veend; + ve++){ + WXEdge *wxe = dynamic_cast<WXEdge*>(*ve); + if(wxe == iEdge.e) + continue; // same edge as the one processed + + if(wxe->nature() != iEdge.e->nature()) + continue; + + if(wxe->GetaVertex() == v){ + // That means that the face necesarily lies on the edge left. + // So the vertex order is OK. + return OWXEdge(wxe, true); + }else{ + // That means that the face necesarily lies on the edge left. + // So the vertex order is OK. + return OWXEdge(wxe, false); + } + } + // we did not find: + return OWXEdge(0, true); +} + +OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge& iEdge){ + if(Nature::NO_FEATURE == iEdge.e->nature()) + return OWXEdge(0, true); + + WVertex *v; + if(true == iEdge.order) + v = iEdge.e->GetaVertex(); + else + v = iEdge.e->GetbVertex(); + + if(((WXVertex*)v)->isFeature()) + return 0; + + + vector<WEdge*>& vEdges = (v)->GetEdges(); + for(vector<WEdge*>::iterator ve=vEdges.begin(),veend=vEdges.end(); + ve!=veend; + ve++){ + WXEdge *wxe = dynamic_cast<WXEdge*>(*ve); + if(wxe == iEdge.e) + continue; // same edge as the one processed + + if(wxe->nature() != iEdge.e->nature()) + continue; + + if(wxe->GetbVertex() == v){ + return OWXEdge(wxe, true); + }else{ + return OWXEdge(wxe, false); + } + } + // we did not find: + return OWXEdge(0, true); +} + +FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe){ + SVertex *va, *vb; + FEdgeSharp *fe; + WXVertex *wxVA, *wxVB; + if(iwe.order){ + wxVA = (WXVertex*)iwe.e->GetaVertex(); + wxVB = (WXVertex*)iwe.e->GetbVertex(); + }else{ + wxVA = (WXVertex*)iwe.e->GetbVertex(); + wxVB = (WXVertex*)iwe.e->GetaVertex(); + } + // Make the 2 SVertex + va = MakeSVertex(wxVA->GetVertex()); + vb = MakeSVertex(wxVB->GetVertex()); + + // get the faces normals and the material indices + Vec3r normalA, normalB; + unsigned matA(0), matB(0); + if(iwe.order){ + normalB = (iwe.e->GetbFace()->GetNormal()); + matB = (iwe.e->GetbFace()->frs_materialIndex()); + if(!(iwe.e->nature() & Nature::BORDER)) { + normalA = (iwe.e->GetaFace()->GetNormal()); + matA = (iwe.e->GetaFace()->frs_materialIndex()); + } + }else{ + normalA = (iwe.e->GetbFace()->GetNormal()); + matA = (iwe.e->GetbFace()->frs_materialIndex()); + if(!(iwe.e->nature() & Nature::BORDER)) { + normalB = (iwe.e->GetaFace()->GetNormal()); + matB = (iwe.e->GetaFace()->frs_materialIndex()); + } + } + // Creates the corresponding feature edge + // Creates the corresponding feature edge + fe = new FEdgeSharp(va, vb); + fe->setNature(iwe.e->nature()); + fe->setId(_currentFId); + fe->setaFrsMaterialIndex(matA); + fe->setbFrsMaterialIndex(matB); + fe->setNormalA(normalA); + fe->setNormalB(normalB); + fe->setPreviousEdge(feprevious); + if(feprevious) + feprevious->setNextEdge(fe); + _pCurrentSShape->AddEdge(fe); + va->AddFEdge(fe); + vb->AddFEdge(fe); + //Add normals: + va->AddNormal(normalA); + va->AddNormal(normalB); + vb->AddNormal(normalA); + vb->AddNormal(normalB); + + ++_currentFId; + iwe.e->userdata = fe; + return fe; +} + +bool ViewEdgeXBuilder::stopSharpViewEdge(WXEdge *iEdge){ + if(0 == iEdge) + return true; + if(iEdge->userdata == 0) + return false; + return true; +} + +SVertex * ViewEdgeXBuilder::MakeSVertex(Vec3r& iPoint){ + SVertex *va; + // Check whether the vertices are already in the table: + // fisrt vertex + // ------------- + SVertexMap::const_iterator found = _SVertexMap.find(iPoint); + if (found != _SVertexMap.end()) { + va = (*found).second; + }else{ + va = new SVertex(iPoint, _currentSVertexId); + SilhouetteGeomEngine::ProjectSilhouette(va); + ++_currentSVertexId; + // Add the svertex to the SShape svertex list: + _pCurrentSShape->AddNewVertex(va); + // Add the svertex in the table using its id: + _SVertexMap[iPoint] = va; + } + return va; +} + +ViewVertex * ViewEdgeXBuilder::MakeViewVertex(SVertex *iSVertex){ + ViewVertex *vva = iSVertex->viewvertex(); + if(vva != 0) + return vva; + vva = new NonTVertex(iSVertex); + // Add the view vertex to the ViewShape svertex list: + _pCurrentVShape->AddVertex(vva); + return vva; +} + diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h new file mode 100755 index 00000000000..28a5d7d9dd4 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.h @@ -0,0 +1,215 @@ +// +// Filename : ViewEdgeXBuilder.h +// Author(s) : Stephane Grabli +// Purpose : Class to build view edges and the underlying chains +// of feature edges... +// Date of creation : 27/10/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef VIEWEDGEXBUILDER_H +# define VIEWEDGEXBUILDER_H + +# include <map> +# include <utility> +# include <vector> + +// soc +// # if defined(__GNUC__) && (__GNUC__ >= 3) +// //hash_map is not part of the C++ standard anymore; hash_map.h has been kept though for backward compatibility +// # include <hash_map.h> +// # else +// # include <hash_map> +// # endif + +# include "../system/FreestyleConfig.h" +# include "../geometry/Geom.h" +# include "Interface1D.h" + +using namespace Geometry; +using namespace std; + +class SVertex; +/*! Defines a hash table used for searching the SVertex */ +struct SVertexHasher { +#define _MUL 950706376UL +#define _MOD 2147483647UL + inline size_t operator() (const Vec3r& p) const { + size_t res = ((unsigned long) (p[0] * _MUL)) % _MOD; + res = ((res + (unsigned long) (p[1]) * _MUL)) % _MOD; + return ((res +(unsigned long) (p[2]) * _MUL)) % _MOD; + } +}; + +// Key_compare predicate for hash_map. In particular, return false if equal. +struct epsilonEquals{ + bool operator()(const Vec3r& v1, const Vec3r& v2) const{ + real norm = (v1-v2).norm(); + return (norm<1e-06); + } +}; + + +// typedef hash_map<Vec3r, SVertex*, SVertexHasher, epsilonEquals> SVertexMap; +typedef map<Vec3r , SVertex*> SVertexMap; + +class WXFaceLayer; +/*! class to describe an oriented smooth edge */ +class OWXFaceLayer{ +public: + WXFaceLayer * fl; + bool order; + + OWXFaceLayer() {fl=0;order=true;} + OWXFaceLayer(WXFaceLayer *ifl, bool iOrder=true){fl = ifl;order=iOrder;} + OWXFaceLayer& operator=(const OWXFaceLayer& iBrother){ + fl = iBrother.fl; + order = iBrother.order; + return *this; + } + bool operator==(const OWXFaceLayer& b){ + return ((fl == b.fl) && (order == b.order)); + } + bool operator!=(const OWXFaceLayer& b){ + return !(*this==b); + } +}; + +class WXEdge; +/*! class to describe an oriented sharp edge */ +class OWXEdge{ +public: + WXEdge * e; + bool order; + + OWXEdge() {e=0;order=true;} + OWXEdge(WXEdge *ie, bool iOrder=true){e = ie;order=iOrder;} + OWXEdge& operator=(const OWXEdge& iBrother){ + e = iBrother.e; + order = iBrother.order; + return *this; + } + bool operator==(const OWXEdge& b){ + return ((e == b.e) && (order == b.order)); + } + bool operator!=(const OWXEdge& b){ + return !(*this==b); + } +}; + +class WOEdge; +class WXEdge; +class WXShape; +class SVertex; +class FEdge; +class ViewVertex; +class ViewEdge; +class ViewShape; +class LIB_VIEW_MAP_EXPORT ViewEdgeXBuilder +{ +protected: + int _currentViewId; // Id for view edges + int _currentFId; // Id for FEdges + int _currentSVertexId; // Id for SVertex +public: + + inline ViewEdgeXBuilder() + {_currentViewId = 1;_currentFId=0;_currentSVertexId=0;} + virtual ~ViewEdgeXBuilder(){} + + /*! Builds a view shape from a WXShape in which the feature edges + * are flagged + * Builds chains of feature edges (so ViewEdges) from a WXShape + * iWShape + * The Winged Edge structure in which all silhouette edges + * and vertices are flagged. + * oViewShape + * The Silhouette Shape in which the chains must be added. + * ioVEdges + * The list of new ViewEdges. + * ioVVertices + * THe new ViewVertices + * ioFEdges + * A list in which all new FEdges are added + * ioSVertices + * A list of SVertex where all created SVertex are added. + */ + virtual void BuildViewEdges(WXShape *iWShape, ViewShape *oVShape, + std::vector<ViewEdge*>& ioVEdges, + std::vector<ViewVertex*>& ioVVertices, + std::vector<FEdge*>& ioFEdges, + std::vector<SVertex*>& ioSVertices) ; + + /*! Builds a smooth view edge, starting the face iFace.*/ + ViewEdge * BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer); + + /*! Makes a sharp viewedge + */ + ViewEdge * BuildSharpViewEdge(const OWXEdge& iWEdge) ; + + +public: + /*! accessors */ + inline int currentViewId() const { return _currentViewId; } + inline int currentFId() const { return _currentFId; } + inline int currentSVertexId() const { return _currentSVertexId; } + /*! modifiers */ + inline void setCurrentViewId(int id) { _currentViewId = id; } + inline void setCurrentFId(int id) { _currentFId = id; } + inline void setCurrentSVertexId(int id) { _currentSVertexId = id; } + +protected: + /*! Init the view edges building */ + virtual void Init(ViewShape *oVShape) ; + + // SMOOTH // + /*! checks whether a face has already been processed or not */ + bool stopSmoothViewEdge(WXFaceLayer *iFaceLayer); + OWXFaceLayer FindNextFaceLayer(const OWXFaceLayer& iFaceLayer); + OWXFaceLayer FindPreviousFaceLayer(const OWXFaceLayer& iFaceLayer); + FEdge * BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer& ifl); + + // SHARP // + /*! checks whether a WEdge has already been processed or not */ + bool stopSharpViewEdge(WXEdge *iFace); + OWXEdge FindNextWEdge(const OWXEdge& iEdge); + OWXEdge FindPreviousWEdge(const OWXEdge& iEdge); + FEdge * BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe); + + // GENERAL // + /*! Instanciate a SVertex if it hasn't been already created */ + SVertex * MakeSVertex(Vec3r& iPoint); + /*! instanciate a ViewVertex from a SVertex, if it doesn't exist yet */ + ViewVertex * MakeViewVertex(SVertex *iSVertex); + + //oldtmp values + // IdHashTable _hashtable; + // VVIdHashTable _multivertexHashTable; + SVertexMap _SVertexMap; + SShape *_pCurrentSShape; + ViewShape * _pCurrentVShape; +}; + +#endif + diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp new file mode 100755 index 00000000000..87624669204 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp @@ -0,0 +1,703 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "ViewMap.h" +#include "../geometry/GeomUtils.h" +#include <float.h> +#include "ViewMapIterators.h" +#include "ViewMapAdvancedIterators.h" + + /**********************************/ + /* */ + /* */ + /* ViewMap */ + /* */ + /* */ + /**********************************/ + +ViewMap * ViewMap::_pInstance = 0; + +ViewMap::~ViewMap() +{ + // The view vertices must be deleted here as some of them + // are shared between two shapes: + for(vector<ViewVertex*>::iterator vv=_VVertices.begin(), vvend=_VVertices.end(); + vv!=vvend; + vv++) + { + delete (*vv); + } + _VVertices.clear(); + + for(vector<ViewShape*>::iterator vs=_VShapes.begin(),vsend=_VShapes.end(); + vs!=vsend; + vs++) + { + delete (*vs); + } + _VShapes.clear(); + + _FEdges.clear(); + _SVertices.clear(); + _VEdges.clear(); +} + +ViewShape * ViewMap::viewShape(unsigned id) +{ + int index = _shapeIdToIndex[id]; + return _VShapes[ index ]; +} +void ViewMap::AddViewShape(ViewShape *iVShape) { + _shapeIdToIndex[iVShape->getId().getFirst()] = _VShapes.size(); + _VShapes.push_back(iVShape); +} +const FEdge * ViewMap::getClosestFEdge(real x, real y) const +{ + // find the closest of this candidates: + real minDist = DBL_MAX; + FEdge * winner = 0; + for(fedges_container::const_iterator fe=_FEdges.begin(),feend=_FEdges.end(); + fe!=feend; + fe++) + { + Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]); + Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]); + real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x,y),A, B); + if(dist < minDist) + { + minDist = dist; + winner = (*fe); + } + + } + if(winner==0) + return 0; + + return winner; +} + +const ViewEdge * ViewMap::getClosestViewEdge(real x, real y) const +{ + // find the closest of this candidates: + real minDist = DBL_MAX; + FEdge * winner = 0; + for(fedges_container::const_iterator fe=_FEdges.begin(),feend=_FEdges.end(); + fe!=feend; + fe++) + { + Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]); + Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]); + real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x,y),A, B); + if(dist < minDist) + { + minDist = dist; + winner = (*fe); + } + + } + if(winner==0) + return 0; + + return winner->viewedge(); +} + + +TVertex* ViewMap::CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFEdgeA, + const Vec3r& iB3D, const Vec3r& iB2D, FEdge *iFEdgeB, + const Id& id) +{ + ViewShape *vshapeA = iFEdgeA->viewedge()->viewShape(); + SShape *shapeA = iFEdgeA->shape(); + ViewShape *vshapeB = iFEdgeB->viewedge()->viewShape(); + SShape *shapeB = iFEdgeB->shape(); + + SVertex * Ia = shapeA->CreateSVertex(iA3D, iA2D, iFEdgeA->vertexA()->getId()); + SVertex * Ib = shapeB->CreateSVertex(iB3D, iB2D, iFEdgeB->vertexA()->getId()); + + // depending on which of these 2 svertices is the nearest from the + // viewpoint, we're going to build the TVertex by giving them in + // an order or another (the first one must be the nearest) + real dista = Ia->point2D()[2]; + real distb = Ib->point2D()[2]; + + TVertex * tvertex; + if(dista < distb) + tvertex = new TVertex(Ia, Ib); + else + tvertex = new TVertex(Ib,Ia); + + tvertex->setId(id); + + // add these vertices to the view map + AddViewVertex(tvertex); + AddSVertex(Ia); + AddSVertex(Ib); + + // and this T Vertex to the view shapes: + vshapeA->AddVertex(tvertex); + vshapeB->AddVertex(tvertex); + + return tvertex; +} + +ViewVertex * ViewMap::InsertViewVertex(SVertex *iVertex, + vector<ViewEdge*>& newViewEdges){ + NonTVertex *vva = dynamic_cast<NonTVertex*>(iVertex->viewvertex()); + if(vva != 0) + return vva; + // beacuse it is not already a ViewVertex, this SVertex must have only + // 2 FEdges. The incoming one still belongs to ioEdge, the outgoing one + // now belongs to newVEdge + const vector<FEdge*>& fedges = iVertex->fedges(); + if(fedges.size()!=2){ + cerr << "ViewMap warning: Can't split the ViewEdge" << endl; + return 0; + } + FEdge * fend(0), * fbegin(0); + for(vector<FEdge*>::const_iterator fe=fedges.begin(), feend=fedges.end(); + fe!=feend; + ++fe){ + if((*fe)->vertexB() == iVertex){ + fend = (*fe); + } + if((*fe)->vertexA() == iVertex){ + fbegin = (*fe); + } + if((fbegin!=0) && (fend!=0)) + break; + } + ViewEdge *ioEdge = fbegin->viewedge(); + ViewShape * vshape = ioEdge->viewShape(); + vva = new NonTVertex(iVertex); + // if the ViewEdge is a closed loop, we don't create + // a new VEdge + if(ioEdge->A() == 0){ + // closed loop + ioEdge->setA(vva); + ioEdge->setB(vva); + // update sshape + vshape->sshape()->RemoveEdgeFromChain(ioEdge->fedgeA()); + vshape->sshape()->RemoveEdgeFromChain(ioEdge->fedgeB()); + + ioEdge->setFEdgeA(fbegin); + ioEdge->setFEdgeB(fend); + + // Update FEdges + fend->setNextEdge(0); + fbegin->setPreviousEdge(0); + + // update new View Vertex: + vva->AddOutgoingViewEdge(ioEdge); + vva->AddIncomingViewEdge(ioEdge); + + vshape->sshape()->AddChain(ioEdge->fedgeA()); + vshape->sshape()->AddChain(ioEdge->fedgeB()); + }else{ + // Create new ViewEdge + ViewEdge * newVEdge = new ViewEdge(vva, ioEdge->B(), fbegin, ioEdge->fedgeB(), vshape); + newVEdge->setId(Id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond()+1)); + newVEdge->setNature(ioEdge->getNature()); + //newVEdge->UpdateFEdges(); // done in the ViewEdge constructor + // Update old ViewEdge + ioEdge->setB(vva); + ioEdge->setFEdgeB(fend); + + // Update FEdges + fend->setNextEdge(0); + fbegin->setPreviousEdge(0); + + // update new View Vertex: + vva->AddOutgoingViewEdge(newVEdge); + vva->AddIncomingViewEdge(ioEdge); + // update ViewShape + //vshape->AddEdge(newVEdge); + // update SShape + vshape->sshape()->AddChain(fbegin); + // update ViewMap + //_VEdges.push_back(newVEdge); + newViewEdges.push_back(newVEdge); + } + + // update ViewShape + vshape->AddVertex(vva); + + // update ViewMap + _VVertices.push_back(vva); + + return vva; +} + +//FEdge * ViewMap::Connect(FEdge *ioEdge, SVertex *ioVertex, vector<ViewEdge*>& oNewVEdges){ +// SShape * sshape = ioEdge->shape(); +// FEdge *newFEdge = sshape->SplitEdgeIn2(ioEdge, ioVertex); +// AddFEdge(newFEdge); +// InsertViewVertex(ioVertex, oNewVEdges); +// return newFEdge; +//} + + /**********************************/ + /* */ + /* */ + /* TVertex */ + /* */ + /* */ + /**********************************/ + +// is dve1 before dve2 ? (does it have a smaller angle ?) +bool ViewEdgeComp(ViewVertex::directedViewEdge& dve1, ViewVertex::directedViewEdge& dve2){ + FEdge *fe1; + if(dve1.second) + fe1 = dve1.first->fedgeB(); + else + fe1 = dve1.first->fedgeA(); + FEdge *fe2; + if(dve2.second) + fe2 = dve2.first->fedgeB(); + else + fe2 = dve2.first->fedgeA(); + + Vec3r V1 = fe1->orientation2d(); + Vec2r v1(V1.x(), V1.y());v1.normalize(); + Vec3r V2 = fe2->orientation2d(); + Vec2r v2(V2.x(), V2.y());v2.normalize(); + if(v1.y() > 0){ + if(v2.y() < 0) + return true; + else + return (v1.x() > v2.x()); + }else{ + if(v2.y() > 0) + return false; + else + return (v1.x() < v2.x()); + } + return false; +} +void TVertex::setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming) { + if (!iFrontEdgeA) { + cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeA()" << endl; + return; + } + _FrontEdgeA = directedViewEdge(iFrontEdgeA, incoming); + if(!_sortedEdges.empty()){ + edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end(); + while((dve!=dveend) && ViewEdgeComp(**dve, _FrontEdgeA)){ + ++dve; + } + _sortedEdges.insert( dve, &_FrontEdgeA); + } + else + _sortedEdges.push_back(&_FrontEdgeA); +} +void TVertex::setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming) { + if (!iFrontEdgeB) { + cerr << "Warning: null pointer passed as argument of TVertex::setFrontEdgeB()" << endl; + return; + } + _FrontEdgeB = directedViewEdge(iFrontEdgeB, incoming); + if(!_sortedEdges.empty()){ + edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end(); + while((dve!=dveend) && ViewEdgeComp(**dve, _FrontEdgeB)){ + ++dve; + } + _sortedEdges.insert(dve, &_FrontEdgeB); + } + else + _sortedEdges.push_back(&_FrontEdgeB); +} +void TVertex::setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming) { + if (!iBackEdgeA) { + cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeA()" << endl; + return; + } + _BackEdgeA = directedViewEdge(iBackEdgeA, incoming); + if(!_sortedEdges.empty()){ + edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end(); + while((dve!=dveend) && ViewEdgeComp(**dve, _BackEdgeA)){ + ++dve; + } + _sortedEdges.insert(dve, &_BackEdgeA); + } + else + _sortedEdges.push_back(&_BackEdgeA); +} +void TVertex::setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming) { + if (!iBackEdgeB) { + cerr << "Warning: null pointer passed as argument of TVertex::setBackEdgeB()" << endl; + return; + } + _BackEdgeB = directedViewEdge(iBackEdgeB, incoming); + if(!_sortedEdges.empty()){ + edge_pointers_container::iterator dve = _sortedEdges.begin(), dveend = _sortedEdges.end(); + while((dve!=dveend) && ViewEdgeComp(**dve, _BackEdgeB)){ + ++dve; + } + _sortedEdges.insert(dve, &_BackEdgeB); + } + else + _sortedEdges.push_back(&_BackEdgeB); +} +void TVertex::Replace(ViewEdge *iOld, ViewEdge *iNew) +{ + // theoritically, we only replace edges for which this + // view vertex is the B vertex + if((iOld == _FrontEdgeA.first) && (_FrontEdgeA.first->B() == this)) + { + _FrontEdgeA.first = iNew; + return; + } + if((iOld == _FrontEdgeB.first) && (_FrontEdgeB.first->B() == this)) + { + _FrontEdgeB.first = iNew; + return; + } + if((iOld == _BackEdgeA.first) && (_BackEdgeA.first->B() == this)) + { + _BackEdgeA.first = iNew; + return; + } + if((iOld == _BackEdgeB.first) && (_BackEdgeB.first->B() == this)) + { + _BackEdgeB.first = iNew; + return; + } +} + +/*! iterators access */ +ViewVertex::edge_iterator TVertex::edges_begin() +{ + //return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA); + return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); +} +ViewVertex::const_edge_iterator TVertex::edges_begin() const +{ + //return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, _FrontEdgeA); + return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); +} +ViewVertex::edge_iterator TVertex::edges_end() +{ + //return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, directedViewEdge(0,true)); + return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end()); +} +ViewVertex::const_edge_iterator TVertex::edges_end() const +{ + //return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, directedViewEdge(0, true)); + return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end()); +} +ViewVertex::edge_iterator TVertex::edges_iterator(ViewEdge *iEdge) +{ + for(edge_pointers_container::iterator it=_sortedEdges.begin(), itend=_sortedEdges.end(); + it!=itend; + it++) + { + if((*it)->first == iEdge) + return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it); + } + return edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); + + // directedViewEdge dEdge; + // if(_FrontEdgeA.first == iEdge) + // dEdge = _FrontEdgeA; + // else if(_FrontEdgeB.first == iEdge) + // dEdge = _FrontEdgeB; + // else if(_BackEdgeA.first == iEdge) + // dEdge = _BackEdgeA; + // else if(_BackEdgeB.first == iEdge) + // dEdge = _BackEdgeB; + // return edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge); +} +ViewVertex::const_edge_iterator TVertex::edges_iterator(ViewEdge *iEdge) const +{ + for(edge_pointers_container::const_iterator it=_sortedEdges.begin(), itend=_sortedEdges.end(); + it!=itend; + it++) + { + if((*it)->first == iEdge) + return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), it); + } + return const_edge_iterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); + + // directedViewEdge dEdge; + // if(_FrontEdgeA.first == iEdge) + // dEdge = _FrontEdgeA; + // else if(_FrontEdgeB.first == iEdge) + // dEdge = _FrontEdgeB; + // else if(_BackEdgeA.first == iEdge) + // dEdge = _BackEdgeA; + // else if(_BackEdgeB.first == iEdge) + // dEdge = _BackEdgeB; + // return const_edge_iterator(_FrontEdgeA, _FrontEdgeB, _BackEdgeA, _BackEdgeB, dEdge); +} + +ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesBegin() { + return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); +} +ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesEnd() { + return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.end()); +} +ViewVertexInternal::orientedViewEdgeIterator TVertex::edgesIterator(ViewEdge *iEdge) { + for(edge_pointers_container::iterator it=_sortedEdges.begin(), itend=_sortedEdges.end(); + it!=itend; + it++) + { + if((*it)->first == iEdge) + return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), it); + } + return ViewVertexInternal::orientedViewEdgeIterator(_sortedEdges.begin(), _sortedEdges.end(), _sortedEdges.begin()); +} + /**********************************/ + /* */ + /* */ + /* NonTVertex */ + /* */ + /* */ + /**********************************/ + +void NonTVertex::AddOutgoingViewEdge(ViewEdge * iVEdge){ + // let's keep the viewedges ordered in CCW order + // in the 2D image plan + directedViewEdge idve(iVEdge, false); + if(!_ViewEdges.empty()){ + edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end(); + while((dve!=dveend) && ViewEdgeComp(*dve, idve)){ + ++dve; + } + _ViewEdges.insert(dve, idve); + } + else + _ViewEdges.push_back(idve); +} + +void NonTVertex::AddIncomingViewEdge(ViewEdge * iVEdge){ + // let's keep the viewedges ordered in CCW order + // in the 2D image plan + directedViewEdge idve(iVEdge, true); + if(!_ViewEdges.empty()){ + edges_container::iterator dve = _ViewEdges.begin(), dveend = _ViewEdges.end(); + while((dve!=dveend) && ViewEdgeComp(*dve, idve)){ + ++dve; + } + _ViewEdges.insert(dve, idve); + } + else + _ViewEdges.push_back(idve); +} + +/*! iterators access */ +ViewVertex::edge_iterator NonTVertex::edges_begin() +{ + return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin()); +} +ViewVertex::const_edge_iterator NonTVertex::edges_begin() const +{ + return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin()); +} +ViewVertex::edge_iterator NonTVertex::edges_end() +{ + return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end()); +} +ViewVertex::const_edge_iterator NonTVertex::edges_end() const +{ + return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end()); +} +ViewVertex::edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge) +{ + for(edges_container::iterator it=_ViewEdges.begin(), itend=_ViewEdges.end(); + it!=itend; + it++) + { + if((it)->first == iEdge) + return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it); + } + return edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin()); +} +ViewVertex::const_edge_iterator NonTVertex::edges_iterator(ViewEdge *iEdge) const +{ + for(edges_container::const_iterator it=_ViewEdges.begin(), itend=_ViewEdges.end(); + it!=itend; + it++) + { + if((it)->first == iEdge) + return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), it); + } + return const_edge_iterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin()); +} + +ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesBegin() { + return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin()); +} +ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesEnd() { + return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.end()); +} +ViewVertexInternal::orientedViewEdgeIterator NonTVertex::edgesIterator(ViewEdge *iEdge) { + for(edges_container::iterator it=_ViewEdges.begin(), itend=_ViewEdges.end(); + it!=itend; + it++) + { + if((it)->first == iEdge) + return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), it); + } + return ViewVertexInternal::orientedViewEdgeIterator(_ViewEdges.begin(), _ViewEdges.end(), _ViewEdges.begin()); +} + /**********************************/ + /* */ + /* */ + /* ViewEdge */ + /* */ + /* */ + /**********************************/ + +real ViewEdge::getLength2D() const +{ + float length = 0.f; + ViewEdge::const_fedge_iterator itlast = fedge_iterator_last(); + ViewEdge::const_fedge_iterator it = fedge_iterator_begin(), itend=fedge_iterator_end(); + Vec2r seg; + do{ + seg = Vec2r((*it)->orientation2d()[0], (*it)->orientation2d()[1]); + length += seg.norm(); + ++it; + }while((it!=itend) && (it!=itlast)); + return length; +} + + +//! view edge iterator +ViewEdge::edge_iterator ViewEdge::ViewEdge_iterator() {return edge_iterator(this);} +ViewEdge::const_edge_iterator ViewEdge::ViewEdge_iterator() const {return const_edge_iterator((ViewEdge*)this);} +//! feature edge iterator +ViewEdge::fedge_iterator ViewEdge::fedge_iterator_begin() {return fedge_iterator(this->_FEdgeA, this->_FEdgeB);} +ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_begin() const {return const_fedge_iterator(this->_FEdgeA, this->_FEdgeB);} +ViewEdge::fedge_iterator ViewEdge::fedge_iterator_last() {return fedge_iterator(this->_FEdgeB, this->_FEdgeB);} +ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_last() const {return const_fedge_iterator(this->_FEdgeB, this->_FEdgeB);} +ViewEdge::fedge_iterator ViewEdge::fedge_iterator_end() {return fedge_iterator(0, this->_FEdgeB);} +ViewEdge::const_fedge_iterator ViewEdge::fedge_iterator_end() const {return const_fedge_iterator(0, this->_FEdgeB);} +//! embedding vertex iterator +ViewEdge::const_vertex_iterator ViewEdge::vertices_begin() const {return const_vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);} +ViewEdge::vertex_iterator ViewEdge::vertices_begin() {return vertex_iterator(this->_FEdgeA->vertexA(), 0, _FEdgeA);} +ViewEdge::const_vertex_iterator ViewEdge::vertices_last() const {return const_vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);} +ViewEdge::vertex_iterator ViewEdge::vertices_last() {return vertex_iterator(this->_FEdgeB->vertexB(), _FEdgeB, 0);} +ViewEdge::const_vertex_iterator ViewEdge::vertices_end() const {return const_vertex_iterator(0, _FEdgeB, 0);} +ViewEdge::vertex_iterator ViewEdge::vertices_end() {return vertex_iterator(0, _FEdgeB, 0);} + + +Interface0DIterator ViewEdge::verticesBegin() { + Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(this->_FEdgeA->vertexA(), this->_FEdgeA->vertexA(), 0, _FEdgeA, 0.f)); + return ret; +} + +Interface0DIterator ViewEdge::verticesEnd() { + Interface0DIterator ret(new ViewEdgeInternal::SVertexIterator(0, this->_FEdgeA->vertexA(), _FEdgeB, 0, getLength2D())); + return ret; +} + +Interface0DIterator ViewEdge::pointsBegin(float t) { + return verticesBegin(); +} + +Interface0DIterator ViewEdge::pointsEnd(float t) { + return verticesEnd(); +} + + + + /**********************************/ + /* */ + /* */ + /* ViewShape */ + /* */ + /* */ + /**********************************/ + + +ViewShape::~ViewShape() +{ + _Vertices.clear(); + + if(!(_Edges.empty())) + { + for(vector<ViewEdge*>::iterator e=_Edges.begin(), eend=_Edges.end(); + e!=eend; + e++) + { + delete (*e); + } + _Edges.clear(); + } + + if(0 != _SShape) + { + delete _SShape; + _SShape = 0; + } +} + +void ViewShape::RemoveEdge(ViewEdge * iViewEdge) +{ + FEdge * fedge = iViewEdge->fedgeA(); + for(vector<ViewEdge*>::iterator ve=_Edges.begin(),veend=_Edges.end(); + ve!=veend; + ve++) + { + if(iViewEdge == (*ve)) + { + _Edges.erase(ve); + _SShape->RemoveEdge(fedge); + break; + } + } +} + +void ViewShape::RemoveVertex(ViewVertex * iViewVertex) +{ + for(vector<ViewVertex*>::iterator vv=_Vertices.begin(), vvend=_Vertices.end(); + vv!=vvend; + vv++) + { + if(iViewVertex == (*vv)) + { + _Vertices.erase(vv); + break; + } + } +} + + /**********************************/ + /* */ + /* */ + /* ViewEdge */ + /* */ + /* */ + /**********************************/ + + +void ViewEdge::UpdateFEdges() +{ + FEdge *currentEdge = _FEdgeA; + do + { + currentEdge->setViewEdge(this); + currentEdge = currentEdge->nextEdge(); + }while((currentEdge != NULL) && (currentEdge!= _FEdgeB)); + // last one + _FEdgeB->setViewEdge(this); + +} diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h new file mode 100755 index 00000000000..3f6be25312a --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewMap.h @@ -0,0 +1,1492 @@ +// +// Filename : ViewMap.h +// Author(s) : Stephane Grabli +// Purpose : Classes to define a View Map (ViewVertex, ViewEdge, etc.) +// Date of creation : 03/09/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef VIEWMAP_H +# define VIEWMAP_H + +# include "../system/BaseIterator.h" +# include "../system/FreestyleConfig.h" +# include "../geometry/GeomUtils.h" +# include "Interface0D.h" +# include "Interface1D.h" +# include "Silhouette.h" // defines the embedding +# include <map> + + /**********************************/ + /* */ + /* */ + /* ViewMap */ + /* */ + /* */ + /**********************************/ + + +/* Density + Mean area depth value + distance to a point + */ + +class ViewVertex; +class ViewEdge; +class ViewShape; +class TVertex; + +/*! Class defining the ViewMap.*/ +class LIB_VIEW_MAP_EXPORT ViewMap +{ +public: + + typedef vector<ViewEdge*> viewedges_container; + typedef vector<ViewVertex*> viewvertices_container; + typedef vector<ViewShape*> viewshapes_container; + typedef vector<SVertex*> svertices_container; + typedef vector<FEdge*> fedges_container; + typedef map<int,int> id_to_index_map; + +private: + + static ViewMap *_pInstance; + viewshapes_container _VShapes; // view shapes + viewedges_container _VEdges; // view edges + viewvertices_container _VVertices; // view vertices + fedges_container _FEdges; // feature edges (embedded edges) + svertices_container _SVertices; // embedded vertices + BBox<Vec3r> _scene3DBBox; + id_to_index_map _shapeIdToIndex; // Mapping between the WShape or VShape id to the VShape index in the + // _VShapes vector. Used in the method viewShape(int id) to access a shape from its id. + +public: + + /*! A field that can be used by the user to store any data. + * This field must be reseted afterwards using ResetUserData(). + */ + void* userdata; + + /*! Default constructor. */ + ViewMap() { + _pInstance = this; + userdata = 0; + } + /*! Destructor. */ + virtual ~ViewMap(); + + /*! Gets the viewedge the nearest to the + * 2D position specified as argument + */ + const ViewEdge * getClosestViewEdge(real x, real y) const ; + + /*! Gets the Fedge the nearest to the + * 2D position specified as argument + */ + const FEdge * getClosestFEdge(real x, real y) const ; + + /* accessors */ + /*! The ViewMap is a singleton class. This static method + * returns the instance of the ViewMap. + */ + static inline ViewMap * getInstance() {return _pInstance;} + /* Returns the list of ViewShapes of the scene. */ + inline viewshapes_container& ViewShapes() {return _VShapes;} + /* Returns the list of ViewEdges of the scene. */ + inline viewedges_container& ViewEdges() {return _VEdges;} + /* Returns the list of ViewVertices of the scene. */ + inline viewvertices_container& ViewVertices() {return _VVertices;} + /* Returns the list of FEdges of the scene. */ + inline fedges_container& FEdges() {return _FEdges;} + /* Returns the list of SVertices of the scene. */ + inline svertices_container& SVertices() {return _SVertices;} + /* Returns an iterator pointing onto the first ViewEdge of the list. */ + inline viewedges_container::iterator viewedges_begin() {return _VEdges.begin();} + inline viewedges_container::iterator viewedges_end() {return _VEdges.end();} + inline int viewedges_size() {return _VEdges.size();} + ViewShape * viewShape(unsigned index); + id_to_index_map& shapeIdToIndexMap() {return _shapeIdToIndex;} + + /*! Returns the scene 3D bounding box. */ + inline BBox<Vec3r> getScene3dBBox() const {return _scene3DBBox;} + + /* modifiers */ + void AddViewShape(ViewShape *iVShape); + inline void AddViewEdge(ViewEdge *iVEdge) {_VEdges.push_back(iVEdge);} + inline void AddViewVertex(ViewVertex *iVVertex) {_VVertices.push_back(iVVertex);} + inline void AddFEdge(FEdge *iFEdge) {_FEdges.push_back(iFEdge);} + inline void AddSVertex(SVertex *iSVertex) {_SVertices.push_back(iSVertex);} + /*! Sets the scene 3D bounding box. */ + inline void setScene3dBBox(const BBox<Vec3r>& bbox) {_scene3DBBox=bbox;} + + /* Creates a T vertex in the view map. + * A T vertex is the intersection between 2 + * FEdges (before these ones are splitted). + * The TVertex is a 2D intersection but it + * corresponds to a 3D point on each of the 2 FEdges. + * iA3D + * The 3D coordinates of the point corresponding + * to the intersection on the first edge. + * iA2D + * The x,y,z 2D coordinates of the projection + * of iA3D + * iFEdgeA + * The first FEdge + * iB3D + * The 3D coordinates of the point corresponding + * to the intersection on the second edge. + * iB2D + * The x,y,z 2D coordinates of the projection + * of iB3D + * iFEdgeB + * The second FEdge + * id + * The id that must be given to that TVertex + */ + TVertex* CreateTVertex(const Vec3r& iA3D, const Vec3r& iA2D, FEdge *iFEdgeA, + const Vec3r& iB3D, const Vec3r& iB2D, FEdge *iFEdgeB, + const Id& id); + + /* Updates the structures to take into account the fact + * that a SVertex must now be considered as a ViewVertex + * iVertex + * The SVertex on top of which the ViewVertex is built (it is necessarily + * a NonTVertex because it is a SVertex) + * newViewEdges + * The new ViewEdges that must be add to the ViewMap + */ + ViewVertex * InsertViewVertex(SVertex *iVertex, vector<ViewEdge*>& newViewEdges); + + /* connects a FEdge to the graph trough a SVertex */ + //FEdge * Connect(FEdge *ioEdge, SVertex *ioVertex); +}; + + /**********************************/ + /* */ + /* */ + /* ViewVertex */ + /* */ + /* */ + /**********************************/ + +class ViewEdge; +class SShape; + +namespace ViewVertexInternal { + class edge_const_traits; + class edge_nonconst_traits; + template<class Traits> class edge_iterator_base ; + class orientedViewEdgeIterator; +} // end of namespace ViewEdgeInternal +/*! Class to define a view vertex + * A view vertex is a feature vertex corresponding + * to a point of the image graph, where the characteristics of an + * edge might change (nature, visibility, ...). + * A ViewVertex can be of two kinds: a TVertex when + * it corresponds to the intersection between two + * ViewEdges or a NonTVertex when it corresponds to a + * vertex of the initial input mesh (it is the case + * for vertices such as corners for example). + * Thus, this class can be specialized into two classes, + * the TVertex class and the NonTVertex class. + */ +class LIB_VIEW_MAP_EXPORT ViewVertex : public Interface0D +{ +public: // Implementation of Interface0D + + /*! Returns the string "ViewVertex" .*/ + virtual string getExactTypeName() const { + return "ViewVertex"; + } + +public: + friend class ViewShape; + typedef pair<ViewEdge*, bool> directedViewEdge; // if bool = true, the ViewEdge is incoming + + typedef vector<directedViewEdge> edges_container; + + typedef ViewVertexInternal::edge_iterator_base<ViewVertexInternal::edge_nonconst_traits> edge_iterator; + typedef ViewVertexInternal::edge_iterator_base<ViewVertexInternal::edge_const_traits> const_edge_iterator; + +private: + + Nature::VertexNature _Nature; + +public: + /*! A field that can be used by the user to store any data. + * This field must be reseted afterwards using ResetUserData(). + */ + void * userdata; + /*! Default constructor.*/ + inline ViewVertex() {userdata = 0;_Nature = Nature::VIEW_VERTEX; } + inline ViewVertex(Nature::VertexNature nature) { + userdata = 0; + _Nature = Nature::VIEW_VERTEX | nature; + } + +protected: + /*! Copy constructor. */ + inline ViewVertex(ViewVertex& iBrother) + { + _Nature = iBrother._Nature; + iBrother.userdata = this; + userdata = 0; + } + /*! Cloning method. */ + virtual ViewVertex * duplicate() = 0; + +public: + /*! Destructor. */ + virtual ~ViewVertex() {} + + /* accessors */ + /*! Returns the nature of the vertex .*/ + virtual Nature::VertexNature getNature() const { + return _Nature; + } + + /* modifiers */ + /*! Sets the nature of the vertex. */ + inline void setNature(Nature::VertexNature iNature) {_Nature = iNature;} + + /* Replaces old edge by new edge */ + virtual void Replace(ViewEdge *, ViewEdge *) {} + +public: + + /* iterators access */ + // allows iteration on the edges that comes from/goes to + // this vertex in CCW order (order defined in 2D in the image plan) + virtual edge_iterator edges_begin() = 0; + virtual const_edge_iterator edges_begin() const = 0; + virtual edge_iterator edges_end() = 0; + virtual const_edge_iterator edges_end() const = 0; + virtual edge_iterator edges_iterator(ViewEdge *iEdge) = 0; + virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const = 0; + + + // Iterator access + /*! Returns an iterator over the ViewEdges that goes to or comes from + * this ViewVertex pointing to the first ViewEdge of the list. + * The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges + * and to get the orientation for each ViewEdge (incoming/outgoing). + */ + virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() = 0; + + /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, + * pointing after the last ViewEdge. + */ + virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() = 0; + + /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge + * given as argument. + */ + virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) = 0; + +}; + + /**********************************/ + /* */ + /* */ + /* TVertex */ + /* */ + /* */ + /**********************************/ + +/*! class to define a T vertex, i.e. an intersection between + * two edges. + * It points towards 2 SVertex and 4 View edges. + * Among these ViewEdges, 2 are front and 2 are back. + * Basically the front edge hides part of the back edge. + * So, among the back edges, 1 is of invisibility n + * and the other of visibility n+1 + */ +class LIB_VIEW_MAP_EXPORT TVertex : public ViewVertex +{ +public: + typedef vector<directedViewEdge*> edge_pointers_container; +public: // Implementation of Interface0D + + /*! Returns the string "TVertex" .*/ + virtual string getExactTypeName() const { + return "TVertex"; + } + + // Data access methods + /* Returns the 3D x coordinate of the vertex . + * Ambiguous in this case. + */ + virtual real getX() const { + cerr << "Warning: getX() undefined for this point" << endl; + return _FrontSVertex->point3D().x(); + } + + virtual real getY() const { + cerr << "Warning: getX() undefined for this point" << endl; + return _FrontSVertex->point3D().y(); + } + + virtual real getZ() const { + cerr << "Warning: getX() undefined for this point" << endl; + return _FrontSVertex->point3D().z(); + } + + /*! Returns the 3D point. */ + virtual Vec3f getPoint3D() const { + cerr << "Warning: getPoint3D() undefined for this point" << endl; + return _FrontSVertex->getPoint3D(); + } + + /*! Returns the projected 3D x coordinate of the vertex .*/ + virtual real getProjectedX() const { + return _FrontSVertex->point2D().x(); + } + + /*! Returns the projected 3D y coordinate of the vertex .*/ + virtual real getProjectedY() const { + return _FrontSVertex->point2D().y(); + } + + virtual real getProjectedZ() const { + return _FrontSVertex->point2D().z(); + } + + /*! Returns the 2D point. */ + virtual Vec2f getPoint2D() const { + return _FrontSVertex->getPoint2D(); + } + + /*! Returns the Id of the TVertex .*/ + virtual Id getId() const { + return _Id; + } + + /*! Cast the Interface0D in SVertex if it can be. */ + // it can't + /*! Cast the Interface0D in ViewVertex if it can be. */ + virtual ViewVertex * castToViewVertex(){ + return this; + } + + /*! Cast the Interface0D in TVertex if it can be. */ + virtual TVertex * castToTVertex(){ + return this; + } + +private: + SVertex *_FrontSVertex; + SVertex *_BackSVertex; + directedViewEdge _FrontEdgeA; + directedViewEdge _FrontEdgeB; + directedViewEdge _BackEdgeA; + directedViewEdge _BackEdgeB; + Id _Id; // id to identify t vertices . these id will be negative in order not to be mixed with NonTVertex ids. + edge_pointers_container _sortedEdges; // the list of the four ViewEdges, ordered in CCW order (in the image plan) + + +public: + /*! Default constructor.*/ + inline TVertex() : ViewVertex(Nature::T_VERTEX) + { + _FrontSVertex = 0; + _BackSVertex = 0; + _FrontEdgeA.first = 0; + _FrontEdgeB.first = 0; + _BackEdgeA.first = 0; + _BackEdgeB.first = 0; + + } + + inline TVertex(SVertex *svFront, SVertex *svBack) + : ViewVertex(Nature::T_VERTEX) + { + _FrontSVertex = svFront; + _BackSVertex = svBack; + _FrontEdgeA.first = 0; + _FrontEdgeB.first = 0; + _BackEdgeA.first = 0; + _BackEdgeB.first = 0; + svFront->setViewVertex(this); + svBack->setViewVertex(this); + } + +protected: + /*! Copy constructor. */ + inline TVertex(TVertex& iBrother) + : ViewVertex(iBrother) + { + _FrontSVertex = iBrother._FrontSVertex; + _BackSVertex = iBrother._BackSVertex; + _FrontEdgeA = iBrother._FrontEdgeA; + _FrontEdgeB = iBrother._FrontEdgeB; + _BackEdgeA = iBrother._BackEdgeA; + _BackEdgeB = iBrother._BackEdgeB; + _sortedEdges = iBrother._sortedEdges; + } + + /*! Cloning method. */ + virtual ViewVertex * duplicate() + { + TVertex *clone = new TVertex(*this); + return clone; + } + +public: + /* accessors */ + /*! Returns the SVertex that is closer to the viewpoint. */ + inline SVertex *frontSVertex() {return _FrontSVertex;} + /*! Returns the SVertex that is further away from the viewpoint. */ + inline SVertex *backSVertex() {return _BackSVertex;} + inline directedViewEdge& frontEdgeA() {return _FrontEdgeA;} + inline directedViewEdge& frontEdgeB() {return _FrontEdgeB;} + inline directedViewEdge& backEdgeA() {return _BackEdgeA;} + inline directedViewEdge& backEdgeB() {return _BackEdgeB;} + + /* modifiers */ + /*! Sets the SVertex that is closer to the viewpoint. */ + inline void setFrontSVertex(SVertex *iFrontSVertex) {_FrontSVertex = iFrontSVertex;_FrontSVertex->setViewVertex(this);} + /*! Sets the SVertex that is further away from the viewpoint. */ + inline void setBackSVertex(SVertex *iBackSVertex) {_BackSVertex = iBackSVertex;_BackSVertex->setViewVertex(this);} + void setFrontEdgeA(ViewEdge *iFrontEdgeA, bool incoming=true); + void setFrontEdgeB(ViewEdge *iFrontEdgeB, bool incoming=true) ; + void setBackEdgeA(ViewEdge *iBackEdgeA, bool incoming=true); + void setBackEdgeB(ViewEdge *iBackEdgeB, bool incoming=true) ; + /*! Sets the Id. */ + inline void setId(const Id& iId) {_Id = iId;} + + /*! Returns the SVertex (among the 2) belonging to the FEdge iFEdge */ + inline SVertex * getSVertex(FEdge *iFEdge) + { + const vector<FEdge*>& vfEdges = _FrontSVertex->fedges(); + vector<FEdge*>::const_iterator fe,fend; + for(fe=vfEdges.begin(),fend=vfEdges.end(); + fe!=fend; + fe++) + { + if((*fe) == iFEdge) + return _FrontSVertex; + } + + const vector<FEdge*>& vbEdges = _BackSVertex->fedges(); + for(fe=vbEdges.begin(),fend=vbEdges.end(); + fe!=fend; + fe++) + { + if((*fe) == iFEdge) + return _BackSVertex; + } + return 0; + } + + virtual void Replace(ViewEdge *iOld, ViewEdge *iNew); + + /*! returns the mate edge of iEdgeA. + * For example, if iEdgeA is frontEdgeA, + * then frontEdgeB is returned. If iEdgeA is + * frontEdgeB then frontEdgeA is returned. + * Same for back edges + */ + virtual ViewEdge * mate(ViewEdge* iEdgeA) + { + if(iEdgeA == _FrontEdgeA.first) + return _FrontEdgeB.first; + if(iEdgeA == _FrontEdgeB.first) + return _FrontEdgeA.first; + if(iEdgeA == _BackEdgeA.first) + return _BackEdgeB.first; + if(iEdgeA == _BackEdgeB.first) + return _BackEdgeA.first; + return 0; + } + + /* iterators access */ + virtual edge_iterator edges_begin(); + virtual const_edge_iterator edges_begin() const; + virtual edge_iterator edges_end(); + virtual const_edge_iterator edges_end() const; + virtual edge_iterator edges_iterator(ViewEdge *iEdge); + virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const; + + /*! Returns an iterator over the ViewEdges that goes to or comes from + * this ViewVertex pointing to the first ViewEdge of the list. + * The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges + * and to get the orientation for each ViewEdge (incoming/outgoing). + */ + virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() ; + /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, + * pointing after the last ViewEdge. + */ + virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() ; + /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge + * given as argument. + */ + virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) ; +}; + + + /**********************************/ + /* */ + /* */ + /* NonTVertex */ + /* */ + /* */ + /**********************************/ + + +// (non T vertex) +/*! View vertex for corners, cusps, etc... + * Associated to a single SVertex. + * Can be associated to 2 or several view edges + */ +class LIB_VIEW_MAP_EXPORT NonTVertex : public ViewVertex +{ +public: + typedef vector<directedViewEdge> edges_container; + +public: // Implementation of Interface0D + + /*! Returns the string "ViewVertex" .*/ + virtual string getExactTypeName() const { + return "NonTVertex"; + } + + // Data access methods + /*! Returns the 3D x coordinate of the vertex .*/ + virtual real getX() const { + return _SVertex->point3D().x(); + } + /*! Returns the 3D y coordinate of the vertex .*/ + virtual real getY() const { + return _SVertex->point3D().y(); + } + + /*! Returns the 3D z coordinate of the vertex .*/ + virtual real getZ() const { + return _SVertex->point3D().z(); + } + + /*! Returns the 3D point. */ + virtual Vec3f getPoint3D() const { + return _SVertex->getPoint3D(); + } + + /*! Returns the projected 3D x coordinate of the vertex .*/ + virtual real getProjectedX() const { + return _SVertex->point2D().x(); + } + + /*! Returns the projected 3D y coordinate of the vertex .*/ + virtual real getProjectedY() const { + return _SVertex->point2D().y(); + } + + /*! Returns the projected 3D z coordinate of the vertex .*/ + virtual real getProjectedZ() const { + return _SVertex->point2D().z(); + } + + /*! Returns the 2D point. */ + virtual Vec2f getPoint2D() const { + return _SVertex->getPoint2D(); + } + + /*! Returns the Id of the vertex .*/ + virtual Id getId() const { + return _SVertex->getId(); + } + + /*! Cast the Interface0D in SVertex if it can be. */ + virtual SVertex * castToSVertex(){ + return _SVertex; + } + + /*! Cast the Interface0D in ViewVertex if it can be. */ + virtual ViewVertex * castToViewVertex(){ + return this; + } + + /*! Cast the Interface0D in NonTVertex if it can be. */ + virtual NonTVertex * castToNonTVertex(){ + return this; + } + +private: + SVertex *_SVertex; + edges_container _ViewEdges; +public: + /*! Default constructor.*/ + inline NonTVertex() : ViewVertex(Nature::NON_T_VERTEX) { _SVertex = 0; } + /*! Builds a NonTVertex from a SVertex. */ + inline NonTVertex(SVertex* iSVertex) : ViewVertex(Nature::NON_T_VERTEX) + { + _SVertex = iSVertex; + _SVertex->setViewVertex(this); + } +protected: + /*! Copy constructor. */ + inline NonTVertex(NonTVertex& iBrother) + : ViewVertex(iBrother) + { + _SVertex = iBrother._SVertex; + _SVertex->setViewVertex(this); + _ViewEdges = iBrother._ViewEdges; + } + /*! Cloning method. */ + virtual ViewVertex * duplicate() + { + NonTVertex *clone = new NonTVertex(*this); + return clone; + } +public: + /*! destructor. */ + virtual ~NonTVertex() {} + + /* accessors */ + /*! Returns the SVertex on top of which this NonTVertex is built. */ + inline SVertex * svertex() {return _SVertex;} + inline edges_container& viewedges() {return _ViewEdges;} + + /* modifiers */ + /*! Sets the SVertex on top of which this NonTVertex is built. */ + inline void setSVertex(SVertex *iSVertex) {_SVertex = iSVertex;_SVertex->setViewVertex(this);} + inline void setViewEdges(const vector<directedViewEdge>& iViewEdges) {_ViewEdges = iViewEdges;} + void AddIncomingViewEdge(ViewEdge * iVEdge) ; + void AddOutgoingViewEdge(ViewEdge * iVEdge) ; + inline void AddViewEdge(ViewEdge * iVEdge, bool incoming=true) { + if(incoming) + AddIncomingViewEdge(iVEdge); + else + AddOutgoingViewEdge(iVEdge); + } + /* Replaces old edge by new edge */ + virtual void Replace(ViewEdge *iOld, ViewEdge *iNew) + { + + edges_container::iterator insertedve; + for(edges_container::iterator ve=_ViewEdges.begin(),vend=_ViewEdges.end(); + ve!=vend; + ve++) + { + if((ve)->first == iOld) + { + insertedve = _ViewEdges.insert(ve, directedViewEdge(iNew, ve->second));// inserts e2 before ve. + // returns an iterator pointing toward e2. ve is invalidated. + // we want to remove e1, but we can't use ve anymore: + insertedve++; // insertedve points now to e1 + _ViewEdges.erase(insertedve); + return; + } + } + } + + + /* iterators access */ + virtual edge_iterator edges_begin(); + virtual const_edge_iterator edges_begin() const; + virtual edge_iterator edges_end(); + virtual const_edge_iterator edges_end() const; + virtual edge_iterator edges_iterator(ViewEdge *iEdge); + virtual const_edge_iterator edges_iterator(ViewEdge *iEdge) const; + + /*! Returns an iterator over the ViewEdges that goes to or comes from + * this ViewVertex pointing to the first ViewEdge of the list. + * The orientedViewEdgeIterator allows to iterate in CCW order over these ViewEdges + * and to get the orientation for each ViewEdge (incoming/outgoing). + */ + virtual ViewVertexInternal::orientedViewEdgeIterator edgesBegin() ; + /*! Returns an orientedViewEdgeIterator over the ViewEdges around this ViewVertex, + * pointing after the last ViewEdge. + */ + virtual ViewVertexInternal::orientedViewEdgeIterator edgesEnd() ; + /*! Returns an orientedViewEdgeIterator pointing to the ViewEdge + * given as argument. + */ + virtual ViewVertexInternal::orientedViewEdgeIterator edgesIterator(ViewEdge *iEdge) ; +}; + + /**********************************/ + /* */ + /* */ + /* ViewEdge */ + /* */ + /* */ + /**********************************/ + +/* Geometry(normals...) + Nature of edges + 2D spaces (1or2, material, z...) + Parent Shape + 3D Shading, material + Importance + Occluders + */ +class ViewShape; + +namespace ViewEdgeInternal { + template<class Traits> class edge_iterator_base ; + template<class Traits> class fedge_iterator_base ; + template<class Traits> class vertex_iterator_base ; +} // end of namespace ViewEdgeInternal + +/*! Class defining a ViewEdge. A ViewEdge in an edge + * of the image graph. it connnects two ViewVertex. + * It is made by connecting a set of FEdges. + */ +class LIB_VIEW_MAP_EXPORT ViewEdge : public Interface1D +{ +public: // Implementation of Interface0D + + /*! Returns the string "ViewEdge" .*/ + virtual string getExactTypeName() const { + return "ViewEdge"; + } + + // Data access methods + /*! Returns the Id of the vertex .*/ + virtual Id getId() const { + return _Id; + } + + /*! Returns the nature of the ViewEdge. */ + virtual Nature::EdgeNature getNature() const { + return _Nature; + } + +public: + + typedef SVertex vertex_type; + friend class ViewShape; + // for ViewEdge iterator + typedef ViewEdgeInternal::edge_iterator_base<Nonconst_traits<ViewEdge*> > edge_iterator; + typedef ViewEdgeInternal::edge_iterator_base<Const_traits<ViewEdge*> > const_edge_iterator; + // for fedge iterator + typedef ViewEdgeInternal::fedge_iterator_base<Nonconst_traits<FEdge*> > fedge_iterator; + typedef ViewEdgeInternal::fedge_iterator_base<Const_traits<FEdge*> > const_fedge_iterator; + // for svertex iterator + typedef ViewEdgeInternal::vertex_iterator_base<Nonconst_traits<SVertex*> > vertex_iterator; + typedef ViewEdgeInternal::vertex_iterator_base<Const_traits<SVertex*> > const_vertex_iterator; +private: + + ViewVertex * __A; // edge starting vertex + ViewVertex * __B; // edge ending vertex + Nature::EdgeNature _Nature; // nature of view edge + ViewShape *_Shape; // shape to which the view edge belongs + FEdge * _FEdgeA; // first edge of the embedded fedges chain + FEdge * _FEdgeB; // last edge of the embedded fedges chain + Id _Id; + unsigned _ChainingTimeStamp; + ViewShape *_aShape; // The silhouette view edge separates 2 2D spaces. The one on the left is + // necessarly the Shape _Shape (the one to which this edge belongs to) + // and _aShape is the one on its right // NON GERE PAR LE COPY CONSTRUCTEUR + int _qi; + vector<ViewShape*> _Occluders; + + // tmp + Id * _splittingId; + +public: + /*! A field that can be used by the user to store any data. + * This field must be reseted afterwards using ResetUserData(). + */ + void * userdata; + /*! Default constructor.*/ + inline ViewEdge() { + __A=0; + __B=0; + _FEdgeA = 0; + _FEdgeB = 0; + _ChainingTimeStamp = 0; + _qi = 0; + _aShape=0; + userdata = 0; + _splittingId = 0; + } + inline ViewEdge(ViewVertex* iA, ViewVertex *iB) + { + __A = iA; + __B = iB; + _FEdgeA = 0; + _FEdgeB = 0; + _Shape = 0; + _ChainingTimeStamp = 0; + _aShape = 0; + _qi = 0; + userdata = 0; + _splittingId = 0; + } + inline ViewEdge(ViewVertex* iA, ViewVertex *iB, FEdge *iFEdgeA) + { + __A = iA; + __B = iB; + _FEdgeA = iFEdgeA; + _FEdgeB = 0; + _Shape = 0; + _ChainingTimeStamp = 0; + _aShape = 0; + _qi = 0; + userdata = 0; + _splittingId = 0; + } + inline ViewEdge(ViewVertex* iA, ViewVertex *iB, FEdge *iFEdgeA, FEdge *iFEdgeB, ViewShape *iShape) + { + __A = iA; + __B = iB; + _FEdgeA = iFEdgeA; + _FEdgeB = iFEdgeB; + _Shape = iShape; + _ChainingTimeStamp = 0; + _aShape = 0; + _qi = 0; + userdata = 0; + _splittingId = 0; + UpdateFEdges(); // tells every FEdge between iFEdgeA and iFEdgeB that this is theit ViewEdge + } + +//soc protected: + + /*! Copy constructor. */ + inline ViewEdge(ViewEdge& iBrother) + { + __A = iBrother.__A; + __B = iBrother.__B; + _FEdgeA = iBrother._FEdgeA; + _FEdgeB = iBrother._FEdgeB; + _Nature = iBrother._Nature; + _Shape = 0; + _Id = iBrother._Id; + _ChainingTimeStamp = iBrother._ChainingTimeStamp; + _aShape = iBrother._aShape; + _qi = iBrother._qi; + _splittingId = 0; + iBrother.userdata = this; + userdata = 0; + } + /*! Cloning method. */ + virtual ViewEdge * duplicate() + { + ViewEdge *clone = new ViewEdge(*this); + return clone; + } + +public: + /*! Destructor. */ + virtual ~ViewEdge() + { + // if(0 != _aFace) + // { + // delete _aFace; + // _aFace = 0; + // } + // only the last splitted deletes this id + if(_splittingId){ + if(*_splittingId == _Id) + delete _splittingId; + } + } + + /* accessors */ + /*! Returns the first ViewVertex. */ + inline ViewVertex* A() {return __A;} + /*! Returns the second ViewVertex. */ + inline ViewVertex* B() {return __B;} + /*! Returns the first FEdge that constitues this ViewEdge. */ + inline FEdge* fedgeA() {return _FEdgeA;} + /*! Returns the last FEdge that constitues this ViewEdge. */ + inline FEdge* fedgeB() {return _FEdgeB;} + /*! Returns the ViewShape to which this ViewEdge belongs to .*/ + inline ViewShape * viewShape() {return _Shape;} + /*! Returns the shape that is occluded by the ViewShape + * to which this ViewEdge belongs to. If no object is occluded, + * 0 is returned. + * \return The occluded ViewShape. + */ + inline ViewShape * aShape() {return _aShape;} + /*! Tells whether this ViewEdge forms a closed loop + * or not. + */ + inline bool isClosed() + { + if(__B == 0) + return true; + return false; + } + /*! Returns the time stamp of this ViewEdge. */ + inline unsigned getChainingTimeStamp() {return _ChainingTimeStamp;} + inline const ViewShape * aShape() const {return _aShape;} + inline const ViewShape * bShape() const {return _Shape;} + inline vector<ViewShape*>& occluders() {return _Occluders;} + inline Id * splittingId() {return _splittingId;} + + /* modifiers */ + /*! Sets the first ViewVertex of the ViewEdge. */ + inline void setA(ViewVertex* iA) { __A = iA; } + /*! Sets the last ViewVertex of the ViewEdge. */ + inline void setB(ViewVertex* iB) { __B = iB; } + /*! Sets the nature of the ViewEdge. */ + inline void setNature(Nature::EdgeNature iNature) { _Nature = iNature; } + /*! Sets the first FEdge of the ViewEdge. */ + inline void setFEdgeA(FEdge* iFEdge) { _FEdgeA = iFEdge; } + /*! Sets the last FEdge of the ViewEdge. */ + inline void setFEdgeB(FEdge* iFEdge) { _FEdgeB = iFEdge; } + /*! Sets the ViewShape to which this ViewEdge belongs to.*/ + inline void setShape(ViewShape *iVShape) + { + _Shape = iVShape; + } + /*! Sets the ViewEdge id. */ + inline void setId(const Id& id) {_Id = id;} + /*! Sets Viewedge to this for all embedded fedges */ + void UpdateFEdges(); + /*! Sets the occluded ViewShape */ + inline void setaShape(ViewShape * iShape) {_aShape = iShape;} + /*! Sets the quantitative invisibility value. */ + inline void setQI(int qi) {_qi = qi;} + /*! Sets the time stamp value. */ + inline void setChainingTimeStamp(unsigned ts) {_ChainingTimeStamp = ts;} + inline void AddOccluder(ViewShape *iShape) {_Occluders.push_back(iShape);} + inline void setSplittingId(Id * id) {_splittingId = id;} + + /* stroke interface definition */ + inline bool intersect_2d_area(const Vec2r& iMin, const Vec2r& iMax) const + { + // parse edges to check if one of them is intersection the region: + FEdge * current = _FEdgeA; + do + { + if(GeomUtils::intersect2dSeg2dArea(iMin,iMax, + Vec2r(current->vertexA()->point2D()[0],current->vertexA()->point2D()[1]), + Vec2r(current->vertexB()->point2D()[0],current->vertexB()->point2D()[1]))) + + return true; + current = current->nextEdge(); + }while((current != 0) && (current != _FEdgeA)); + + return false; + } + inline bool include_in_2d_area(const Vec2r& iMin, const Vec2r& iMax) const + { + // parse edges to check if all of them are intersection the region: + FEdge * current = _FEdgeA; + + do + { + if(!GeomUtils::include2dSeg2dArea(iMin,iMax, + Vec2r(current->vertexA()->point2D()[0],current->vertexA()->point2D()[1]), + Vec2r(current->vertexB()->point2D()[0],current->vertexB()->point2D()[1]))) + return false; + current = current->nextEdge(); + }while((current != 0) && (current != _FEdgeA)); + + return true; + } + + /* Information access interface */ + + //inline Nature::EdgeNature viewedge_nature() const {return getNature();} + //float viewedge_length() const ; + /*! Returns the 2D length of the Viewedge. */ + real getLength2D() const; + //inline Material material() const {return _FEdgeA->vertexA()->shape()->material();} + inline int qi() const {return _qi;} + inline occluder_container::const_iterator occluders_begin() const {return _Occluders.begin();} + inline occluder_container::const_iterator occluders_end() const {return _Occluders.end();} + inline int occluders_size() const {return _Occluders.size();} + inline bool occluders_empty() const {return _Occluders.empty();} + inline const Polygon3r& occludee() const {return (_FEdgeA->aFace());} + inline const SShape * occluded_shape() const ; + inline const bool occludee_empty() const {if(_aShape == 0) return true; return false;} + //inline real z_discontinuity(int iCombination = 0) const ; + inline Id shape_id() const {return _FEdgeA->vertexA()->shape()->getId();} + inline const SShape * shape() const {return _FEdgeA->vertexA()->shape();} + inline float shape_importance() const {return _FEdgeA->shape_importance();} + + /* iterators access */ + // view edge iterator + edge_iterator ViewEdge_iterator(); + const_edge_iterator ViewEdge_iterator() const; + // feature edge iterator + fedge_iterator fedge_iterator_begin(); + const_fedge_iterator fedge_iterator_begin() const; + fedge_iterator fedge_iterator_last(); + const_fedge_iterator fedge_iterator_last() const; + fedge_iterator fedge_iterator_end(); + const_fedge_iterator fedge_iterator_end() const; + // embedding vertex iterator + const_vertex_iterator vertices_begin() const; + vertex_iterator vertices_begin(); + const_vertex_iterator vertices_last() const; + vertex_iterator vertices_last(); + const_vertex_iterator vertices_end() const; + vertex_iterator vertices_end(); + + // Iterator access (Interface1D) + /*! Returns an Interface0DIterator to iterate over + * the SVertex constituing the embedding of this ViewEdge. + * The returned Interface0DIterator points to the first + * SVertex of the ViewEdge. + */ + virtual Interface0DIterator verticesBegin(); + /*! Returns an Interface0DIterator to iterate over + * the SVertex constituing the embedding of this ViewEdge. + * The returned Interface0DIterator points after the last + * SVertex of the ViewEdge. + */ + virtual Interface0DIterator verticesEnd(); + + /*! Returns an Interface0DIterator to iterate over + * the points of this ViewEdge at a given resolution. + * The returned Interface0DIterator points on the first + * Point of the ViewEdge. + * \param t + * the sampling value. + */ + virtual Interface0DIterator pointsBegin(float t=0.f); + /*! Returns an Interface0DIterator to iterate over + * the points of this ViewEdge at a given resolution. + * The returned Interface0DIterator points after the last + * Point of the ViewEdge. + * \param t + * the sampling value. + */ + virtual Interface0DIterator pointsEnd(float t=0.f); +}; + + + + /**********************************/ + /* */ + /* */ + /* ViewShape */ + /* */ + /* */ + /**********************************/ + +/*! Class gathering the elements of the ViewMap (ViewVertex, ViewEdge) + * that are issued from the same input shape. + */ +class LIB_VIEW_MAP_EXPORT ViewShape +{ +private: + vector<ViewVertex*> _Vertices; + vector<ViewEdge*> _Edges; + SShape * _SShape; + + +public: + /*! A field that can be used by the user to store any data. + * This field must be reseted afterwards using ResetUserData(). + */ + void* userdata; + /*! Default constructor.*/ + inline ViewShape() { userdata = 0; _SShape = 0;} + /*! Builds a ViewShape from a SShape. */ + inline ViewShape(SShape *iSShape) {userdata = 0; _SShape = iSShape;}//_SShape->setViewShape(this);} + /*! Copy constructor. */ + inline ViewShape(ViewShape& iBrother) + { + userdata = 0; + vector<ViewVertex*>::iterator vv,vvend; + vector<ViewEdge*>::iterator ve, veend; + + _SShape = iBrother._SShape; + + vector<ViewVertex*>& vvertices = iBrother.vertices(); + // duplicate vertices + for(vv=vvertices.begin(), vvend=vvertices.end(); + vv!=vvend; + vv++) + { + ViewVertex * newVertex = (*vv)->duplicate(); + AddVertex(newVertex); + } + + vector<ViewEdge*>& vvedges = iBrother.edges(); + // duplicate edges + for(ve=vvedges.begin(), veend=vvedges.end(); + ve!=veend; + ve++) + { + ViewEdge * newEdge = (*ve)->duplicate(); + AddEdge(newEdge); // here the shape is set as the edge's shape + } + + //------------------------- + // remap edges in vertices: + //------------------------- + for(vv=_Vertices.begin(), vvend=_Vertices.end(); + vv!=vvend; + vv++) + { + switch((*vv)->getNature()) + { + case Nature::T_VERTEX: + { + TVertex *v = (TVertex*)(*vv); + ViewEdge *veFrontA = (ViewEdge*)(v)->frontEdgeA().first->userdata; + ViewEdge *veFrontB = (ViewEdge*)(v)->frontEdgeB().first->userdata; + ViewEdge *veBackA = (ViewEdge*)(v)->backEdgeA().first->userdata; + ViewEdge *veBackB = (ViewEdge*)(v)->backEdgeB().first->userdata; + + v->setFrontEdgeA(veFrontA, v->frontEdgeA().second); + v->setFrontEdgeB(veFrontB, v->frontEdgeB().second); + v->setBackEdgeA(veBackA, v->backEdgeA().second); + v->setBackEdgeB(veBackB, v->backEdgeB().second); + } + break; + case Nature::NON_T_VERTEX: + { + NonTVertex * v = (NonTVertex*)(*vv); + vector<ViewVertex::directedViewEdge>& vedges = (v)->viewedges(); + vector<ViewVertex::directedViewEdge> newEdges; + for(vector<ViewVertex::directedViewEdge>::iterator ve=vedges.begin(), veend=vedges.end(); + ve!=veend; + ve++) + { + ViewEdge *current = (ViewEdge*)((ve)->first)->userdata; + newEdges.push_back(ViewVertex::directedViewEdge(current, ve->second)); + } + (v)->setViewEdges(newEdges); + } + break; + default: + ; + } + } + + //------------------------------------- + // remap vertices in edges: + //------------------------------------- + for(ve=_Edges.begin(),veend=_Edges.end(); + ve!=veend; + ve++) + { + (*ve)->setA((ViewVertex*)((*ve)->A()->userdata)); + (*ve)->setB((ViewVertex*)((*ve)->B()->userdata)); + //--------------------------------------- + // Update all embedded FEdges + //--------------------------------------- + (*ve)->UpdateFEdges(); + } + + + // reset all brothers userdata to NULL: + //------------------------------------- + //--------- + // vertices + //--------- + for(vv=vvertices.begin(),vvend=vvertices.end(); + vv!=vvend; + vv++) + { + (*vv)->userdata = NULL; + } + + //------ + // edges + //------ + for(ve=vvedges.begin(),veend=vvedges.end(); + ve!=veend; + ve++) + { + (*ve)->userdata = NULL; + } + } + + /*! Cloning method. */ + virtual ViewShape * duplicate() + { + ViewShape *clone = new ViewShape(*this); + return clone; + } + + /*! Destructor. */ + virtual ~ViewShape(); + + /* splits a view edge into several view edges. + * fe + * The FEdge that gets splitted + * iViewVertices + * The view vertices corresponding to the different intersections for the edge fe. + * This list need to be sorted such as the first view vertex is the + * farther away from fe->vertexA. + * ioNewEdges + * The feature edges that are newly created (the initial edges are not + * included) are added to this list. + * ioNewViewEdges + * The view edges that are newly created (the initial edges are not + * included) are added to this list. + */ + inline void SplitEdge(FEdge *fe, + const vector<TVertex*>& iViewVertices, + vector<FEdge*>& ioNewEdges, + vector<ViewEdge*>& ioNewViewEdges); + /* accessors */ + /*! Returns the SShape on top of which this ViewShape is built. */ + inline SShape * sshape() {return _SShape;} + /*! Returns the SShape on top of which this ViewShape is built. */ + inline const SShape * sshape() const {return _SShape;} + /*! Returns the list of ViewVertex contained in this ViewShape. */ + inline vector<ViewVertex*>& vertices() {return _Vertices;} + /*! Returns the list of ViewEdge contained in this ViewShape. */ + inline vector<ViewEdge*>& edges() {return _Edges;} + /*! Returns the ViewShape id. */ + inline Id getId() const {return _SShape->getId();} + + /* modifiers */ + /*! Sets the SShape on top of which the ViewShape is built. */ + inline void setSShape(SShape* iSShape) {_SShape = iSShape;} + /*! Sets the list of ViewVertex contained in this ViewShape. */ + inline void setVertices(const vector<ViewVertex*>& iVertices) {_Vertices = iVertices;} + /*! Sets the list of ViewEdge contained in this ViewShape. */ + inline void setEdges(const vector<ViewEdge*>& iEdges) {_Edges = iEdges;} + /*! Adds a ViewVertex to the list. */ + inline void AddVertex(ViewVertex *iVertex) + { + _Vertices.push_back(iVertex); + //_SShape->AddNewVertex(iVertex->svertex()); + } + /*! Adds a ViewEdge to the list */ + inline void AddEdge(ViewEdge *iEdge) + { + _Edges.push_back(iEdge); + iEdge->setShape(this); + //_SShape->AddNewEdge(iEdge->fedge()); + } + + /* removes the view edge iViewEdge in the + * View Shape and the associated FEdge chain entry + * in the underlying SShape + */ + void RemoveEdge(ViewEdge * iViewEdge); + + /* removes the view vertex iViewVertex in the + * View Shape. + */ + void RemoveVertex(ViewVertex * iViewVertex); +}; + + + +/* + + ############################################# + ############################################# + ############################################# + ###### ###### + ###### I M P L E M E N T A T I O N ###### + ###### ###### + ############################################# + ############################################# + ############################################# + +*/ +/* for inline functions */ + +void ViewShape::SplitEdge(FEdge *fe, + const vector<TVertex*>& iViewVertices, + vector<FEdge*>& ioNewEdges, + vector<ViewEdge*>& ioNewViewEdges) +{ + ViewEdge *vEdge = fe->viewedge(); + + + // We first need to sort the view vertices from farther to closer to fe->vertexA + + SVertex *sv, *sv2; + ViewVertex *vva, *vvb; + vector<TVertex*>::const_iterator vv, vvend; + for(vv=iViewVertices.begin(), vvend = iViewVertices.end(); + vv!=vvend; + vv++) + { + // Add the viewvertices to the ViewShape + AddVertex((*vv)); + + // retrieve the correct SVertex from the view vertex + //-------------------------------------------------- + sv = (*vv)->frontSVertex(); + sv2 = (*vv)->backSVertex(); + + if(sv->shape() != sv2->shape()) + { + if(sv->shape() != _SShape) + sv = sv2; + } + else + { + // if the shape is the same we can safely differ + // the two vertices using their ids: + if(sv->getId() != fe->vertexA()->getId()) + sv = sv2; + } + + vva = vEdge->A(); + vvb = vEdge->B(); + + // We split Fedge AB into AA' and A'B. A' and A'B are created. + // AB becomes (address speaking) AA'. B is updated. + //-------------------------------------------------- + SShape * shape = fe->shape(); + + // a new edge, A'B is created. + FEdge *newEdge = shape->SplitEdgeIn2(fe, sv); + + ioNewEdges.push_back(newEdge); + ViewEdge *newVEdge; + + if((vva == 0) || (vvb == 0)) // that means we're dealing with a closed viewedge (loop) + { + // remove the chain that was starting by the fedge A of vEdge (which is different from fe !!!!) + shape->RemoveEdgeFromChain(vEdge->fedgeA()); + // we set + vEdge->setA(*vv); + vEdge->setB(*vv); + vEdge->setFEdgeA(newEdge); + //FEdge *previousEdge = newEdge->previousEdge(); + vEdge->setFEdgeB(fe); + newVEdge = vEdge; + vEdge->fedgeA()->setViewEdge(newVEdge); + } + else + { + + // while we create the view edge, it updates the "ViewEdge" pointer + // of every underlying FEdges to this. + newVEdge = new ViewEdge((*vv),vvb);//, newEdge, vEdge->fedgeB()); + newVEdge->setNature((fe)->getNature()); + newVEdge->setFEdgeA(newEdge); + //newVEdge->setFEdgeB(fe); + // If our original viewedge is made of one FEdge, + // then + if((vEdge->fedgeA() == vEdge->fedgeB()) || (fe == vEdge->fedgeB())) + newVEdge->setFEdgeB(newEdge); + else + newVEdge->setFEdgeB(vEdge->fedgeB()); //MODIF + + Id * newId = vEdge->splittingId(); + if(newId == 0){ + newId = new Id(vEdge->getId()); + vEdge->setSplittingId(newId); + } + newId->setSecond(newId->getSecond()+1); + newVEdge->setId(*newId); + newVEdge->setSplittingId(newId); + // Id id(vEdge->getId().getFirst(), vEdge->getId().getSecond()+1); + // newVEdge->setId(vEdge->getId()); + // vEdge->setId(id); + + AddEdge(newVEdge); // here this shape is set as the edge's shape + + // add new edge to the list of new edges passed as argument: + ioNewViewEdges.push_back(newVEdge); + + + + if(0 != vvb) + vvb->Replace((vEdge), newVEdge); + + // we split the view edge: + vEdge->setB((*vv)); + vEdge->setFEdgeB(fe); //MODIF + + // Update fedges so that they point to the new viewedge: + newVEdge->UpdateFEdges(); + + } + // check whether this vertex is a front vertex or a back + // one + + if(sv == (*vv)->frontSVertex()) + { + // -- View Vertex A' -- + (*vv)->setFrontEdgeA(vEdge, true); + (*vv)->setFrontEdgeB(newVEdge, false); + } + else + { + // -- View Vertex A' -- + (*vv)->setBackEdgeA(vEdge, true); + (*vv)->setBackEdgeB(newVEdge, false); + } + } +} + + /**********************************/ + /* */ + /* */ + /* ViewEdge */ + /* */ + /* */ + /**********************************/ + + +// inline Vec3r ViewEdge::orientation2d(int iCombination) const +// { +// return edge_orientation2d_function<ViewEdge>(*this, iCombination); +// } + +// inline Vec3r ViewEdge::orientation3d(int iCombination) const +// { +// return edge_orientation3d_function<ViewEdge>(*this, iCombination); +// } + +// inline real ViewEdge::z_discontinuity(int iCombination) const +// { +// return z_discontinuity_edge_function<ViewEdge>(*this, iCombination); +// } + +// inline float ViewEdge::local_average_depth(int iCombination ) const +// { +// return local_average_depth_edge_function<ViewEdge>(*this, iCombination); +// } + +// inline float ViewEdge::local_depth_variance(int iCombination) const +// { +// return local_depth_variance_edge_function<ViewEdge>(*this, iCombination); +// } + +// inline real ViewEdge::local_average_density(float sigma, int iCombination) const +// { +// return density_edge_function<ViewEdge>(*this, iCombination); +// } + +inline const SShape * ViewEdge::occluded_shape() const +{ + if(0 == _aShape) + return 0; + return _aShape->sshape(); +} + +// inline Vec3r ViewEdge::curvature2d_as_vector(int iCombination) const +// { +// return curvature2d_as_vector_edge_function<ViewEdge>(*this, iCombination); +// } + +// inline real ViewEdge::curvature2d_as_angle(int iCombination) const +// { +// return curvature2d_as_angle_edge_function<ViewEdge>(*this, iCombination); +// } + + +#endif // VIEWMAP_H diff --git a/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h b/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h new file mode 100755 index 00000000000..31abefbfb97 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewMapAdvancedIterators.h @@ -0,0 +1,691 @@ +// +// Filename : ViewMapAdvancedIterators.h +// Author(s) : Stephane Grabli +// Purpose : Iterators used to iterate over the various elements of the ViewMap +// These iterators can't be exported to python. +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef VIEWMAPADVANCEDITERATORS_H +# define VIEWMAPADVANCEDITERATORS_H + +#include "ViewMap.h" +#include "../system/Iterator.h" //soc + + /**********************************/ + /* */ + /* */ + /* ViewMap */ + /* */ + /* */ + /**********************************/ + + /**********************************/ + /* */ + /* */ + /* ViewVertex */ + /* */ + /* */ + /**********************************/ + +namespace ViewVertexInternal{ + + class edge_const_traits : public Const_traits< ::ViewVertex::directedViewEdge> { + public: + typedef vector< ::ViewVertex::directedViewEdge> edges_container; + typedef edges_container::const_iterator edges_container_iterator ; + typedef vector< ::ViewVertex::directedViewEdge*> edge_pointers_container; + typedef edge_pointers_container::const_iterator edge_pointers_container_iterator ; + }; + class edge_nonconst_traits : public Nonconst_traits< ::ViewVertex::directedViewEdge> { + public: + typedef vector< ::ViewVertex::directedViewEdge> edges_container; + typedef edges_container::iterator edges_container_iterator ; + typedef vector< ::ViewVertex::directedViewEdge*> edge_pointers_container; + typedef edge_pointers_container::iterator edge_pointers_container_iterator ; + }; + +template<class Traits> + class edge_iterator_base : public IteratorBase<Traits,InputIteratorTag_Traits> + { + public: + typedef typename Traits::value_type value_type; + typedef typename Traits::difference_type difference_type; + typedef typename Traits::pointer pointer; + typedef typename Traits::reference reference; + typedef edge_iterator_base<Traits> Self; + typedef typename Traits::edges_container_iterator edges_container_iterator; + typedef typename Traits::edge_pointers_container_iterator edge_pointers_container_iterator; + typedef edge_iterator_base<edge_nonconst_traits> iterator; + typedef edge_iterator_base<edge_const_traits> const_iterator; + public: + friend class ViewVertex; + friend class TVertex; + friend class NonTVertex; + friend class ViewEdge; + friend class edge_iterator; + protected: + Nature::VertexNature _Nature; // the nature of the underlying vertex + // T vertex attributes + edge_pointers_container_iterator _tbegin; + edge_pointers_container_iterator _tend; + edge_pointers_container_iterator _tvertex_iter; + + // mutable value_type _tvertex_iter; + // value_type _feA; + // value_type _feB; + // value_type _beA; + // value_type _beB; + + // Non TVertex attributes + edges_container_iterator _begin; + edges_container_iterator _end; + edges_container_iterator _nontvertex_iter; + + typedef IteratorBase<Traits,InputIteratorTag_Traits> parent_class; + + public: + inline edge_iterator_base() : parent_class() {} + inline edge_iterator_base(Nature::VertexNature iNature) + : parent_class() + {_Nature = iNature;} + edge_iterator_base(const edge_iterator_base<edge_nonconst_traits>& iBrother) + : parent_class(iBrother) + { + _Nature = iBrother._Nature; + if(_Nature & Nature::T_VERTEX) + { + // _feA = iBrother._feA; + // _feB = iBrother._feB; + // _beA = iBrother._beA; + // _beB = iBrother._beB; + // _tvertex_iter = iBrother._tvertex_iter; + _tbegin = iBrother._tbegin; + _tend = iBrother._tend; + _tvertex_iter = iBrother._tvertex_iter; + } + else + { + _begin = iBrother._begin; + _end = iBrother._end; + _nontvertex_iter = iBrother._nontvertex_iter; + } + } + edge_iterator_base(const edge_iterator_base<edge_const_traits>& iBrother) + : parent_class(iBrother) + { + _Nature = iBrother._Nature; + if(_Nature & Nature::T_VERTEX) + { + // _feA = iBrother._feA; + // _feB = iBrother._feB; + // _beA = iBrother._beA; + // _beB = iBrother._beB; + // _tvertex_iter = iBrother._tvertex_iter; + _tbegin = iBrother._tbegin; + _tend = iBrother._tend; + _tvertex_iter = iBrother._tvertex_iter; + } + else + { + _begin = iBrother._begin; + _end = iBrother._end; + _nontvertex_iter = iBrother._nontvertex_iter; + } + } + virtual ~edge_iterator_base() {} + //protected://FIXME + public: + // inline edge_iterator_base(value_type ifeA, + // value_type ifeB, + // value_type ibeA, + // value_type ibeB, + // value_type iter) + // : parent_class() + // { + // _Nature = Nature::T_VERTEX; + // _feA = ifeA; + // _feB = ifeB; + // _beA = ibeA; + // _beB = ibeB; + // _tvertex_iter = iter; + // } + inline edge_iterator_base(edge_pointers_container_iterator begin, + edge_pointers_container_iterator end, + edge_pointers_container_iterator iter) + : parent_class() + { + _Nature = Nature::T_VERTEX; + _tbegin = begin; + _tend = end; + _tvertex_iter = iter; + } + inline edge_iterator_base(edges_container_iterator begin, + edges_container_iterator end, + edges_container_iterator iter) + : parent_class() + { + _Nature = Nature::NON_T_VERTEX; + _begin = begin; + _end = end; + _nontvertex_iter = iter; + } + + public: + + + virtual bool begin() const + { + if(_Nature & Nature::T_VERTEX) + return (_tvertex_iter == _tbegin); + //return (_tvertex_iter == _feA); + else + return (_nontvertex_iter == _begin); + } + virtual bool end() const + { + if(_Nature & Nature::T_VERTEX) + //return (_tvertex_iter.first == 0); + return (_tvertex_iter == _tend); + else + return (_nontvertex_iter == _end); + } + + // operators + virtual Self& operator++() // operator corresponding to ++i + { + increment(); + return *this; + } + virtual Self operator++(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + increment(); // dans un temporaire. + return tmp; + } + + // comparibility + virtual bool operator!=(const Self& b) const + { + if(_Nature & Nature::T_VERTEX) + return (_tvertex_iter != b._tvertex_iter); + else + return (_nontvertex_iter != b._nontvertex_iter); + } + + virtual bool operator==(const Self& b) const + {return !(*this != b);} + + // dereferencing + virtual reference operator*() const + { + if(_Nature & Nature::T_VERTEX) + //return _tvertex_iter; + return **_tvertex_iter; + else + return (*_nontvertex_iter); + } + virtual pointer operator->() const { return &(operator*());} + + protected: + inline void increment() + { + if(_Nature & Nature::T_VERTEX) + { + value_type tmp = (**_tvertex_iter); + ++_tvertex_iter; + value_type tmp2 = (**_tvertex_iter); + if(tmp2.first == tmp.first) + ++_tvertex_iter; + // // Hack to deal with cusp. the result of a cusp + // // is a TVertex having two identical viewedges. + // // In order to iterate properly, we chose to + // // to skip these last ones. + // if(_feB.first == _beA.first) + // { + // if(_feA.first == _beB.first) + // { + // _tvertex_iter.first = 0; + // return; + // } + // + // if(_tvertex_iter.first == _feA.first) + // _tvertex_iter.first = _beB.first; + // else if(_tvertex_iter.first == _beB.first) + // _tvertex_iter.first = 0; + // else + // _tvertex_iter.first = _feA.first; + // return; + // } + // if(_feA.first == _beB.first) + // { + // if(_feB.first == _beA.first) + // { + // _tvertex_iter.first = 0; + // return; + // } + // + // if(_tvertex_iter.first == _feB.first) + // _tvertex_iter.first = _beA.first; + // else if(_tvertex_iter.first == _beA.first) + // _tvertex_iter.first = 0; + // else + // _tvertex_iter.first = _feB.first; + // return; + // } + // // End of hack + // + // if(_tvertex_iter.first == _feA.first){ + // // we return bea or beb + // + // + // // choose one of them + // + // _tvertex_iter.first = _feB.first; + // return; + // } + // if(_tvertex_iter.first == _feB.first) + // { + // _tvertex_iter.first = _beA.first; + // return; + // } + // if(_tvertex_iter.first == _beA.first) + // { + // _tvertex_iter.first = _beB.first; + // return; + // } + // if(_tvertex_iter.first == _beB.first) + // { + // _tvertex_iter.first = 0; + // return; + // } + } + else + ++_nontvertex_iter; + } + }; + + } + /**********************************/ + /* */ + /* */ + /* ViewEdge */ + /* */ + /* */ + /**********************************/ + +namespace ViewEdgeInternal { + + /*!----------------------*/ + /*! Iterators definition */ + /*!----------------------*/ + template<class Traits> + class edge_iterator_base : public IteratorBase<Traits,BidirectionalIteratorTag_Traits> + { + public: + typedef typename Traits::value_type value_type; + typedef typename Traits::difference_type difference_type; + typedef typename Traits::pointer pointer; + typedef typename Traits::reference reference; + typedef edge_iterator_base<Traits> Self; + public: + mutable value_type _ViewEdge; + //friend class edge_iterator_base<Nonconst_traits<ViewEdge*> >; + //friend class edge_iterator_base<Const_traits<ViewEdge*> >; + value_type _first; + bool _orientation; + typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class; + + public: + friend class ViewEdge; + inline edge_iterator_base() + : parent_class() + {_orientation=true;_first=0;} + + inline edge_iterator_base(const edge_iterator_base<Nonconst_traits< ::ViewEdge*> >& iBrother) + : parent_class() + { + _ViewEdge = iBrother._ViewEdge; + _first = iBrother._first; + _orientation = iBrother._orientation; + } + + inline edge_iterator_base(const edge_iterator_base<Const_traits< ::ViewEdge*> >& iBrother) + : parent_class() + { + _ViewEdge = iBrother._ViewEdge; + _first = iBrother._first; + _orientation = iBrother._orientation; + } + + //protected://FIXME + public: + inline edge_iterator_base(value_type iEdge, bool orientation = true) + : parent_class() + { + _ViewEdge = iEdge; + _first = iEdge; + _orientation = orientation; + } + + + public: + virtual Self* clone() const + { + return new edge_iterator_base(*this); + } + virtual ~edge_iterator_base() {} + + public: + + virtual bool orientation() {return _orientation;} + virtual void set_edge(value_type iVE) {_ViewEdge=iVE;} + virtual void set_orientation(bool iOrientation) {_orientation = iOrientation;} + virtual void change_orientation() {_orientation = !_orientation;} + + // operators + inline Self& operator++() // operator corresponding to ++i + { + //++_ViewEdge->getTimeStamp(); + increment(); + return *this; + } + inline Self operator++(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + //++_ViewEdge->getTimeStamp(); + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + increment(); // dans un temporaire. + return tmp; + } + inline Self& operator--() // operator corresponding to ++i + { + //++_ViewEdge->getTimeStamp(); + decrement(); + return *this; + } + inline Self operator--(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + //++_ViewEdge->getTimeStamp(); + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + decrement(); // dans un temporaire. + return tmp; + } + + // comparibility + virtual bool operator!=(const Self& b) const + { + return (_ViewEdge != b._ViewEdge); + } + virtual bool operator==(const Self& b) const + { + return !(*this != b); + } + + // dereferencing + virtual reference operator*() const {return (_ViewEdge);} + virtual pointer operator->() const { return &(operator*());} + + public: + virtual bool begin() const {return _ViewEdge==_first ? true : false;} + virtual bool end() const {return _ViewEdge==0 ? true : false;} + + protected: + virtual void increment() {} + virtual void decrement() {} + }; + + template<class Traits> + class fedge_iterator_base : public IteratorBase<Traits,BidirectionalIteratorTag_Traits> + { + public: + typedef typename Traits::value_type value_type; + typedef typename Traits::difference_type difference_type; + typedef typename Traits::pointer pointer; + typedef typename Traits::reference reference; + typedef fedge_iterator_base<Traits> Self; + public: + typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class; + mutable value_type _FEdge; + value_type _first; + value_type _FEdgeB; // last fedge of the view edge + + public: + friend class ::ViewEdge; + friend class fedge_iterator; + inline fedge_iterator_base() + : parent_class() + {} + inline fedge_iterator_base(const fedge_iterator_base<Nonconst_traits<FEdge*> >& iBrother) + : parent_class() + { + _FEdge = iBrother._FEdge; + _first = iBrother._first; + _FEdgeB = iBrother._FEdgeB; + } + inline fedge_iterator_base(const fedge_iterator_base<Const_traits<FEdge*> >& iBrother) + : parent_class() + { + _FEdge = iBrother._FEdge; + _first = iBrother._first; + _FEdgeB = iBrother._FEdgeB; + } + //protected://FIXME + public: + inline fedge_iterator_base(value_type iEdge, value_type iFEdgeB) + : parent_class() + { + _FEdge = iEdge; + _first = iEdge; + _FEdgeB = iFEdgeB; + } + + public: + virtual ~fedge_iterator_base() {} + // operators + inline Self& operator++() // operator corresponding to ++i + { + increment(); + return *this; + } + inline Self operator++(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + increment(); // dans un temporaire. + return tmp; + } + inline Self& operator--() // operator corresponding to ++i + { + decrement(); + return *this; + } + inline Self operator--(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + decrement(); // dans un temporaire. + return tmp; + } + + // comparibility + virtual bool operator!=(const Self& b) const + { + return (_FEdge != b._FEdge); + } + virtual bool operator==(const Self& b) const + { + return !(*this != b); + } + + // dereferencing + virtual reference operator*() const {return (_FEdge);} + virtual pointer operator->() const { return &(operator*());} + + + public: + virtual bool begin() const {return _FEdge==_first ? true : false;} + virtual bool end() const {return _FEdge==0 ? true : false;} + protected: + virtual void increment() + { + _FEdge = _FEdge->nextEdge(); // we don't change or + } + + virtual void decrement() + { + if(0 == _FEdge) + { + _FEdge = _FEdgeB; + return; + } + _FEdge = _FEdge->previousEdge(); // we don't change or + } + }; + + template<class Traits> + class vertex_iterator_base : public IteratorBase<Traits,BidirectionalIteratorTag_Traits> + { + public: + typedef typename Traits::value_type value_type; + typedef typename Traits::difference_type difference_type; + typedef typename Traits::pointer pointer; + typedef typename Traits::reference reference; + typedef vertex_iterator_base<Traits> Self; + protected: + typedef IteratorBase<Traits,BidirectionalIteratorTag_Traits> parent_class; + public: + mutable value_type _SVertex; + FEdge *_NextFEdge; + FEdge *_PreviousFEdge; + public: + friend class ViewEdge; + friend class vertex_iterator; + inline vertex_iterator_base() + : parent_class() + {} + inline vertex_iterator_base(const vertex_iterator_base<Const_traits<SVertex*> >& iBrother) + : parent_class() + { + _SVertex = iBrother._SVertex; + _NextFEdge = iBrother._NextFEdge; + _PreviousFEdge = iBrother._PreviousFEdge; + } + inline vertex_iterator_base(const vertex_iterator_base<Nonconst_traits<SVertex*> >& iBrother) + : parent_class() + { + _SVertex = iBrother._SVertex; + _NextFEdge = iBrother._NextFEdge; + _PreviousFEdge = iBrother._PreviousFEdge; + } + + //protected://FIXME + public: + + inline vertex_iterator_base(value_type iVertex, FEdge *iPreviousFEdge, FEdge *iNextFEdge) + : parent_class() + { + _SVertex = iVertex; + _NextFEdge = iNextFEdge; + _PreviousFEdge = iPreviousFEdge; + } + + public: + virtual ~vertex_iterator_base() {} + + virtual bool begin() const {return _PreviousFEdge==0? true : false;} + virtual bool end() const {return _SVertex==0 ? true : false;} + + // operators + inline Self& operator++() // operator corresponding to ++i + { + increment(); + return *this; + } + inline Self operator++(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + increment(); // dans un temporaire. + return tmp; + } + inline Self& operator--() // operator corresponding to ++i + { + decrement(); + return *this; + } + inline Self operator--(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + Self tmp = *this; // C'est pour cela qu'on stocke la valeur + decrement(); // dans un temporaire. + return tmp; + } + + // comparibility + virtual bool operator!=(const Self& b) const + { + return (_SVertex != b._SVertex); + } + virtual bool operator==(const Self& b) const + { + return !(*this != b); + } + + // dereferencing + virtual reference operator*() const {return (_SVertex);} + virtual pointer operator->() const { return &(operator*());} + + protected: + virtual void increment() + { + if(0 == _NextFEdge) + { + _SVertex = 0; + return; + } + + _SVertex = _NextFEdge->vertexB(); + _PreviousFEdge = _NextFEdge; + _NextFEdge = _NextFEdge->nextEdge(); + + } + virtual void decrement() + { + // if(0 == _SVertex) + // { + // _SVertex = _PreviousFEdge->vertexB(); + // return; + // } + if(0 == _PreviousFEdge) + { + _SVertex = 0; + return; + } + _SVertex = _PreviousFEdge->vertexA(); + _NextFEdge = _PreviousFEdge; + _PreviousFEdge = _PreviousFEdge->previousEdge(); + } + }; + + +} // end of namespace ViewEdgeInternal + +#endif // VIEWMAPADVANCEDITERATORS_H diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp new file mode 100755 index 00000000000..96635517747 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp @@ -0,0 +1,1064 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <algorithm> +#include "ViewMapBuilder.h" + +using namespace std; + +ViewMap* ViewMapBuilder::BuildViewMap(WingedEdge& we, visibility_algo iAlgo, real epsilon) { + _ViewMap = new ViewMap; + _currentId = 1; + _currentFId = 0; + _currentSVertexId = 0; + + // Builds initial view edges + computeInitialViewEdges(we); + + // Detects cusps + computeCusps(_ViewMap); + + // Compute intersections + ComputeIntersections(_ViewMap, sweep_line, epsilon); + + // Compute visibility + ComputeEdgesVisibility(_ViewMap, iAlgo, _Grid, epsilon); + + return _ViewMap; +} + +void ViewMapBuilder::computeInitialViewEdges(WingedEdge& we) +{ + vector<WShape*> wshapes = we.getWShapes(); + SShape* psShape; + + for (vector<WShape*>::const_iterator it = wshapes.begin(); + it != wshapes.end(); + it++) { + // create the embedding + psShape = new SShape; + psShape->setId((*it)->GetId()); + psShape->setFrsMaterials((*it)->frs_materials()); // FIXME + + // create the view shape + ViewShape * vshape = new ViewShape(psShape); + // add this view shape to the view map: + _ViewMap->AddViewShape(vshape); + + _pViewEdgeBuilder->setCurrentViewId(_currentId); // we want to number the view edges in a unique way for the while scene. + _pViewEdgeBuilder->setCurrentFId(_currentFId); // we want to number the feature edges in a unique way for the while scene. + _pViewEdgeBuilder->setCurrentSVertexId(_currentFId); // we want to number the SVertex in a unique way for the while scene. + _pViewEdgeBuilder->BuildViewEdges(dynamic_cast<WXShape*>(*it), vshape, + _ViewMap->ViewEdges(), + _ViewMap->ViewVertices(), + _ViewMap->FEdges(), + _ViewMap->SVertices()); + + _currentId = _pViewEdgeBuilder->currentViewId()+1; + _currentFId = _pViewEdgeBuilder->currentFId()+1; + _currentSVertexId = _pViewEdgeBuilder->currentSVertexId()+1; + + psShape->ComputeBBox(); + } +} + +void ViewMapBuilder::computeCusps(ViewMap *ioViewMap){ + vector<ViewVertex*> newVVertices; + vector<ViewEdge*> newVEdges; + ViewMap::viewedges_container& vedges = ioViewMap->ViewEdges(); + ViewMap::viewedges_container::iterator ve=vedges.begin(), veend=vedges.end(); + for(; + ve!=veend; + ++ve){ + if((!((*ve)->getNature() & Nature::SILHOUETTE)) || (!((*ve)->fedgeA()->isSmooth()))) + continue; + FEdge *fe = (*ve)->fedgeA(); + FEdge * fefirst = fe; + bool first = true; + bool positive = true; + do{ + FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe); + Vec3r A((fes)->vertexA()->point3d()); + Vec3r B((fes)->vertexB()->point3d()); + Vec3r AB(B-A); + AB.normalize(); + Vec3r m((A+B)/2.0); + Vec3r crossP(AB^(fes)->normal()); + crossP.normalize(); + Vec3r viewvector; + if (_orthographicProjection) { + viewvector = Vec3r(0.0, 0.0, m.z()-_viewpoint.z()); + } else { + viewvector = Vec3r(m-_viewpoint); + } + viewvector.normalize(); + if(first){ + if(((crossP)*(viewvector)) > 0) + positive = true; + else + positive = false; + first = false; + } + // If we're in a positive part, we need + // a stronger negative value to change + NonTVertex *cusp = 0; + if(positive){ + if(((crossP)*(viewvector)) < -0.1){ + // state changes + positive = false; + // creates and insert cusp + cusp = dynamic_cast<NonTVertex*>(ioViewMap->InsertViewVertex(fes->vertexA(), newVEdges)); + if(cusp!=0) + cusp->setNature(cusp->getNature()|Nature::CUSP); + } + + }else{ + // If we're in a negative part, we need + // a stronger negative value to change + if(((crossP)*(viewvector)) > 0.1){ + positive = true; + cusp = dynamic_cast<NonTVertex*>(ioViewMap->InsertViewVertex(fes->vertexA(), newVEdges)); + if(cusp!=0) + cusp->setNature(cusp->getNature()|Nature::CUSP); + } + } + fe = fe->nextEdge(); + }while((fe!=0) && (fe!=fefirst)); + } + for(ve=newVEdges.begin(), veend=newVEdges.end(); + ve!=veend; + ++ve){ + (*ve)->viewShape()->AddEdge(*ve); + vedges.push_back(*ve); + } +} +void ViewMapBuilder::ComputeEdgesVisibility(ViewMap *ioViewMap, visibility_algo iAlgo, Grid *iGrid, real epsilon) +{ + if((iAlgo == ray_casting || + iAlgo == ray_casting_fast || + iAlgo == ray_casting_very_fast) && (NULL == iGrid)) + { + cerr << "Error: can't cast ray, no grid defined" << endl; + return; + } + + switch(iAlgo) + { + case ray_casting: + ComputeRayCastingVisibility(ioViewMap, iGrid, epsilon); + break; + case ray_casting_fast: + ComputeFastRayCastingVisibility(ioViewMap, iGrid, epsilon); + break; + case ray_casting_very_fast: + ComputeVeryFastRayCastingVisibility(ioViewMap, iGrid, epsilon); + break; + default: + break; + } +} + +static const unsigned gProgressBarMaxSteps = 10; +static const unsigned gProgressBarMinSize = 2000; + +void ViewMapBuilder::ComputeRayCastingVisibility(ViewMap *ioViewMap, Grid* iGrid, real epsilon) +{ + vector<ViewEdge*>& vedges = ioViewMap->ViewEdges(); + bool progressBarDisplay = false; + unsigned progressBarStep = 0; + unsigned vEdgesSize = vedges.size(); + unsigned fEdgesSize = ioViewMap->FEdges().size(); + + if(_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) { + unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize); + progressBarStep = vEdgesSize / progressBarSteps; + _pProgressBar->reset(); + _pProgressBar->setLabelText("Computing Ray casting Visibility"); + _pProgressBar->setTotalSteps(progressBarSteps); + _pProgressBar->setProgress(0); + progressBarDisplay = true; + } + + unsigned counter = progressBarStep; + FEdge * fe, *festart; + int nSamples = 0; + vector<Polygon3r*> aFaces; + Polygon3r *aFace = 0; + unsigned tmpQI = 0; + unsigned qiClasses[256]; + unsigned maxIndex, maxCard; + unsigned qiMajority; + static unsigned timestamp = 1; + for(vector<ViewEdge*>::iterator ve=vedges.begin(), veend=vedges.end(); + ve!=veend; + ve++) + { + festart = (*ve)->fedgeA(); + fe = (*ve)->fedgeA(); + qiMajority = 1; + do { + qiMajority++; + fe = fe->nextEdge(); + } while (fe && fe != festart); + qiMajority >>= 1; + + tmpQI = 0; + maxIndex = 0; + maxCard = 0; + nSamples = 0; + fe = (*ve)->fedgeA(); + memset(qiClasses, 0, 256 * sizeof(*qiClasses)); + set<ViewShape*> occluders; + do + { + if((maxCard < qiMajority)) { + tmpQI = ComputeRayCastingVisibility(fe, iGrid, epsilon, occluders, &aFace, timestamp++); + + if(tmpQI >= 256) + cerr << "Warning: too many occluding levels" << endl; + + if (++qiClasses[tmpQI] > maxCard) { + maxCard = qiClasses[tmpQI]; + maxIndex = tmpQI; + } + } + else + FindOccludee(fe, iGrid, epsilon, &aFace, timestamp++); + + if(aFace) { + fe->setaFace(*aFace); + aFaces.push_back(aFace); + fe->setOccludeeEmpty(false); + } + else + fe->setOccludeeEmpty(true); + + ++nSamples; + fe = fe->nextEdge(); + } + while((maxCard < qiMajority) && (0!=fe) && (fe!=festart)); + + // ViewEdge + // qi -- + (*ve)->setQI(maxIndex); + // occluders -- + for(set<ViewShape*>::iterator o=occluders.begin(), oend=occluders.end(); + o!=oend; + ++o) + (*ve)->AddOccluder((*o)); + // occludee -- + if(!aFaces.empty()) + { + if(aFaces.size() <= (float)nSamples/2.f) + { + (*ve)->setaShape(0); + } + else + { + vector<Polygon3r*>::iterator p = aFaces.begin(); + WFace * wface = (WFace*)((*p)->userdata); + ViewShape *vshape = ioViewMap->viewShape(wface->GetVertex(0)->shape()->GetId()); + ++p; + (*ve)->setaShape(vshape); + } + } + + if(progressBarDisplay) { + counter--; + if (counter <= 0) { + counter = progressBarStep; + _pProgressBar->setProgress(_pProgressBar->getProgress() + 1); + } + } + aFaces.clear(); + } +} + +void ViewMapBuilder::ComputeFastRayCastingVisibility(ViewMap *ioViewMap, Grid* iGrid, real epsilon) +{ + vector<ViewEdge*>& vedges = ioViewMap->ViewEdges(); + bool progressBarDisplay = false; + unsigned progressBarStep = 0; + unsigned vEdgesSize = vedges.size(); + unsigned fEdgesSize = ioViewMap->FEdges().size(); + + if(_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) { + unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize); + progressBarStep = vEdgesSize / progressBarSteps; + _pProgressBar->reset(); + _pProgressBar->setLabelText("Computing Ray casting Visibility"); + _pProgressBar->setTotalSteps(progressBarSteps); + _pProgressBar->setProgress(0); + progressBarDisplay = true; + } + + unsigned counter = progressBarStep; + FEdge * fe, *festart; + unsigned nSamples = 0; + vector<Polygon3r*> aFaces; + Polygon3r *aFace = 0; + unsigned tmpQI = 0; + unsigned qiClasses[256]; + unsigned maxIndex, maxCard; + unsigned qiMajority; + static unsigned timestamp = 1; + bool even_test; + for(vector<ViewEdge*>::iterator ve=vedges.begin(), veend=vedges.end(); + ve!=veend; + ve++) + { + festart = (*ve)->fedgeA(); + fe = (*ve)->fedgeA(); + qiMajority = 1; + do { + qiMajority++; + fe = fe->nextEdge(); + } while (fe && fe != festart); + if (qiMajority >= 4) + qiMajority >>= 2; + else + qiMajority = 1; + + set<ViewShape*> occluders; + + even_test = true; + maxIndex = 0; + maxCard = 0; + nSamples = 0; + memset(qiClasses, 0, 256 * sizeof(*qiClasses)); + fe = (*ve)->fedgeA(); + do + { + if (even_test) + { + if((maxCard < qiMajority)) { + tmpQI = ComputeRayCastingVisibility(fe, iGrid, epsilon, occluders, &aFace, timestamp++); + + if(tmpQI >= 256) + cerr << "Warning: too many occluding levels" << endl; + + if (++qiClasses[tmpQI] > maxCard) { + maxCard = qiClasses[tmpQI]; + maxIndex = tmpQI; + } + } + else + FindOccludee(fe, iGrid, epsilon, &aFace, timestamp++); + + if(aFace) + { + fe->setaFace(*aFace); + aFaces.push_back(aFace); + } + ++nSamples; + even_test = false; + } + else + even_test = true; + fe = fe->nextEdge(); + } while ((maxCard < qiMajority) && (0!=fe) && (fe!=festart)); + + (*ve)->setQI(maxIndex); + + if(!aFaces.empty()) + { + if(aFaces.size() < nSamples / 2) + { + (*ve)->setaShape(0); + } + else + { + vector<Polygon3r*>::iterator p = aFaces.begin(); + WFace * wface = (WFace*)((*p)->userdata); + ViewShape *vshape = ioViewMap->viewShape(wface->GetVertex(0)->shape()->GetId()); + ++p; + // for(; + // p!=pend; + // ++p) + // { + // WFace *f = (WFace*)((*p)->userdata); + // ViewShape *vs = ioViewMap->viewShape(f->GetVertex(0)->shape()->GetId()); + // if(vs != vshape) + // { + // sameShape = false; + // break; + // } + // } + // if(sameShape) + (*ve)->setaShape(vshape); + } + } + + //(*ve)->setaFace(aFace); + + if(progressBarDisplay) { + counter--; + if (counter <= 0) { + counter = progressBarStep; + _pProgressBar->setProgress(_pProgressBar->getProgress() + 1); + } + } + aFaces.clear(); + } +} + +void ViewMapBuilder::ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, Grid* iGrid, real epsilon) +{ + vector<ViewEdge*>& vedges = ioViewMap->ViewEdges(); + bool progressBarDisplay = false; + unsigned progressBarStep = 0; + unsigned vEdgesSize = vedges.size(); + unsigned fEdgesSize = ioViewMap->FEdges().size(); + + if(_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) { + unsigned progressBarSteps = min(gProgressBarMaxSteps, vEdgesSize); + progressBarStep = vEdgesSize / progressBarSteps; + _pProgressBar->reset(); + _pProgressBar->setLabelText("Computing Ray casting Visibility"); + _pProgressBar->setTotalSteps(progressBarSteps); + _pProgressBar->setProgress(0); + progressBarDisplay = true; + } + + unsigned counter = progressBarStep; + FEdge* fe; + unsigned qi = 0; + Polygon3r *aFace = 0; + static unsigned timestamp = 1; + for(vector<ViewEdge*>::iterator ve=vedges.begin(), veend=vedges.end(); + ve!=veend; + ve++) + { + set<ViewShape*> occluders; + + fe = (*ve)->fedgeA(); + qi = ComputeRayCastingVisibility(fe, iGrid, epsilon, occluders, &aFace, timestamp++); + if(aFace) + { + fe->setaFace(*aFace); + WFace * wface = (WFace*)(aFace->userdata); + ViewShape *vshape = ioViewMap->viewShape(wface->GetVertex(0)->shape()->GetId()); + (*ve)->setaShape(vshape); + } + else + { + (*ve)->setaShape(0); + } + + (*ve)->setQI(qi); + + if(progressBarDisplay) { + counter--; + if (counter <= 0) { + counter = progressBarStep; + _pProgressBar->setProgress(_pProgressBar->getProgress() + 1); + } + } + } +} + + +void ViewMapBuilder::FindOccludee(FEdge *fe, Grid* iGrid, real epsilon, Polygon3r** oaPolygon, unsigned timestamp, + Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices) +{ + WFace *face = 0; + if(fe->isSmooth()){ + FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe); + face = (WFace*)fes->face(); + } + OccludersSet occluders; + WFace * oface; + bool skipFace; + + WVertex::incoming_edge_iterator ie; + OccludersSet::iterator p, pend; + + *oaPolygon = 0; + if(((fe)->getNature() & Nature::SILHOUETTE) || ((fe)->getNature() & Nature::BORDER)) + { + occluders.clear(); + // we cast a ray from A in the same direction but looking behind + Vec3r v(-u[0],-u[1],-u[2]); + iGrid->castInfiniteRay(A, v, occluders, timestamp); + + bool noIntersection = true; + real mint=FLT_MAX; + // we met some occluders, let us fill the aShape field + // with the first intersected occluder + for(p=occluders.begin(),pend=occluders.end(); + p!=pend; + p++) + { + // check whether the edge and the polygon plane are coincident: + //------------------------------------------------------------- + //first let us compute the plane equation. + oface = (WFace*)(*p)->userdata; + Vec3r v1(((*p)->getVertices())[0]); + Vec3r normal((*p)->getNormal()); + real d = -(v1 * normal); + real t,t_u,t_v; + + if(0 != face) + { + skipFace = false; + + if(face == oface) + continue; + + if(faceVertices.empty()) + continue; + + for(vector<WVertex*>::iterator fv=faceVertices.begin(), fvend=faceVertices.end(); + fv!=fvend; + ++fv) + { + if((*fv)->isBoundary()) + continue; + WVertex::incoming_edge_iterator iebegin=(*fv)->incoming_edges_begin(); + WVertex::incoming_edge_iterator ieend=(*fv)->incoming_edges_end(); + for(ie=iebegin;ie!=ieend; ++ie) + { + if((*ie) == 0) + continue; + + WFace * sface = (*ie)->GetbFace(); + if(sface == oface) + { + skipFace = true; + break; + } + } + if(skipFace) + break; + } + if(skipFace) + continue; + } + else + { + if(GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, normal, d, t, epsilon)) + continue; + } + if((*p)->rayIntersect(A, v, t,t_u,t_v)) + { + if (fabs(v * normal) > 0.0001) + if ((t>0.0)) // && (t<1.0)) + { + if (t<mint) + { + *oaPolygon = (*p); + mint = t; + noIntersection = false; + fe->setOccludeeIntersection(Vec3r(A+t*v)); + } + } + } + } + + if(noIntersection) + *oaPolygon = 0; + } +} + +void ViewMapBuilder::FindOccludee(FEdge *fe, Grid* iGrid, real epsilon, Polygon3r** oaPolygon, unsigned timestamp) +{ + OccludersSet occluders; + + Vec3r A; + Vec3r edge; + Vec3r origin; + A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D())/2.0); + edge = Vec3r((fe)->vertexB()->point3D()-(fe)->vertexA()->point3D()); + origin = Vec3r((fe)->vertexA()->point3D()); + Vec3r u; + if (_orthographicProjection) { + u = Vec3r(0.0, 0.0, _viewpoint.z()-A.z()); + } else { + u = Vec3r(_viewpoint-A); + } + u.normalize(); + if(A < iGrid->getOrigin()) + cerr << "Warning: point is out of the grid for fedge " << fe->getId().getFirst() << "-" << fe->getId().getSecond() << endl; + + vector<WVertex*> faceVertices; + + WFace *face = 0; + if(fe->isSmooth()){ + FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe); + face = (WFace*)fes->face(); + } + if(0 != face) + face->RetrieveVertexList(faceVertices); + + return FindOccludee(fe,iGrid, epsilon, oaPolygon, timestamp, + u, A, origin, edge, faceVertices); +} + +int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe, Grid* iGrid, real epsilon, set<ViewShape*>& oOccluders, + Polygon3r** oaPolygon, unsigned timestamp) +{ + OccludersSet occluders; + int qi = 0; + + Vec3r center; + Vec3r edge; + Vec3r origin; + + center = fe->center3d(); + edge = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D()); + origin = Vec3r(fe->vertexA()->point3D()); + // + // // Is the edge outside the view frustum ? + Vec3r gridOrigin(iGrid->getOrigin()); + Vec3r gridExtremity(iGrid->getOrigin()+iGrid->gridSize()); + + if( (center.x() < gridOrigin.x()) || (center.y() < gridOrigin.y()) || (center.z() < gridOrigin.z()) + ||(center.x() > gridExtremity.x()) || (center.y() > gridExtremity.y()) || (center.z() > gridExtremity.z())){ + cerr << "Warning: point is out of the grid for fedge " << fe->getId() << endl; + //return 0; + } + + + // Vec3r A(fe->vertexA()->point2d()); + // Vec3r B(fe->vertexB()->point2d()); + // int viewport[4]; + // SilhouetteGeomEngine::retrieveViewport(viewport); + // if( (A.x() < viewport[0]) || (A.x() > viewport[2]) || (A.y() < viewport[1]) || (A.y() > viewport[3]) + // ||(B.x() < viewport[0]) || (B.x() > viewport[2]) || (B.y() < viewport[1]) || (B.y() > viewport[3])){ + // cerr << "Warning: point is out of the grid for fedge " << fe->getId() << endl; + // //return 0; + // } + + Vec3r vp; + if (_orthographicProjection) { + vp = Vec3r(center.x(), center.y(), _viewpoint.z()); + } else { + vp = Vec3r(_viewpoint); + } + Vec3r u(vp - center); + real raylength = u.norm(); + u.normalize(); + //cout << "grid origin " << iGrid->getOrigin().x() << "," << iGrid->getOrigin().y() << "," << iGrid->getOrigin().z() << endl; + //cout << "center " << center.x() << "," << center.y() << "," << center.z() << endl; + + iGrid->castRay(center, vp, occluders, timestamp); + + WFace *face = 0; + if(fe->isSmooth()){ + FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe); + face = (WFace*)fes->face(); + } + vector<WVertex*> faceVertices; + WVertex::incoming_edge_iterator ie; + + WFace * oface; + bool skipFace; + OccludersSet::iterator p, pend; + if(face) + face->RetrieveVertexList(faceVertices); + + for(p=occluders.begin(),pend=occluders.end(); + p!=pend; + p++) + { + // If we're dealing with an exact silhouette, check whether + // we must take care of this occluder of not. + // (Indeed, we don't consider the occluders that + // share at least one vertex with the face containing + // this edge). + //----------- + oface = (WFace*)(*p)->userdata; + Vec3r v1(((*p)->getVertices())[0]); + Vec3r normal((*p)->getNormal()); + real d = -(v1 * normal); + real t, t_u, t_v; + + if(0 != face) + { + skipFace = false; + + if(face == oface) + continue; + + + for(vector<WVertex*>::iterator fv=faceVertices.begin(), fvend=faceVertices.end(); + fv!=fvend; + ++fv) + { + if((*fv)->isBoundary()) + continue; + + WVertex::incoming_edge_iterator iebegin=(*fv)->incoming_edges_begin(); + WVertex::incoming_edge_iterator ieend=(*fv)->incoming_edges_end(); + for(ie=iebegin;ie!=ieend; ++ie) + { + if((*ie) == 0) + continue; + + WFace * sface = (*ie)->GetbFace(); + //WFace * sfacea = (*ie)->GetaFace(); + //if((sface == oface) || (sfacea == oface)) + if(sface == oface) + { + skipFace = true; + break; + } + } + if(skipFace) + break; + } + if(skipFace) + continue; + } + else + { + // check whether the edge and the polygon plane are coincident: + //------------------------------------------------------------- + //first let us compute the plane equation. + + if(GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, normal, d, t, epsilon)) + continue; + } + + if((*p)->rayIntersect(center, u, t, t_u, t_v)) + { + if (fabs(u * normal) > 0.0001) + if ((t>0.0) && (t<raylength)) + { + WFace *f = (WFace*)((*p)->userdata); + ViewShape *vshape = _ViewMap->viewShape(f->GetVertex(0)->shape()->GetId()); + oOccluders.insert(vshape); + ++qi; + if(!_EnableQI) + break; + } + } + } + + // Find occludee + FindOccludee(fe,iGrid, epsilon, oaPolygon, timestamp, + u, center, edge, origin, faceVertices); + + return qi; +} + +void ViewMapBuilder::ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo, real epsilon) +{ + switch(iAlgo) + { + case sweep_line: + ComputeSweepLineIntersections(ioViewMap, epsilon); + break; + default: + break; + } + ViewMap::viewvertices_container& vvertices = ioViewMap->ViewVertices(); + for(ViewMap::viewvertices_container::iterator vv=vvertices.begin(), vvend=vvertices.end(); + vv!=vvend; + ++vv) + { + if((*vv)->getNature() == Nature::T_VERTEX) + { + TVertex *tvertex = (TVertex*)(*vv); + cout << "TVertex " << tvertex->getId() << " has :" << endl; + cout << "FrontEdgeA: " << tvertex->frontEdgeA().first << endl; + cout << "FrontEdgeB: " << tvertex->frontEdgeB().first << endl; + cout << "BackEdgeA: " << tvertex->backEdgeA().first << endl; + cout << "BackEdgeB: " << tvertex->backEdgeB().first << endl << endl; + } + } +} + +struct less_SVertex2D : public binary_function<SVertex*, SVertex*, bool> +{ + real epsilon; + less_SVertex2D(real eps) + : binary_function<SVertex*,SVertex*,bool>() + { + epsilon = eps; + } + bool operator()(SVertex* x, SVertex* y) + { + Vec3r A = x->point2D(); + Vec3r B = y->point2D(); + for(unsigned int i=0; i<3; i++) + { + if((fabs(A[i] - B[i])) < epsilon) + continue; + if(A[i] < B[i]) + return true; + if(A[i] > B[i]) + return false; + } + + return false; + } +}; + +typedef Segment<FEdge*,Vec3r > segment; +typedef Intersection<segment> intersection; + +struct less_Intersection : public binary_function<intersection*, intersection*, bool> +{ + segment *edge; + less_Intersection(segment *iEdge) + : binary_function<intersection*,intersection*,bool>() + { + edge = iEdge; + } + bool operator()(intersection* x, intersection* y) + { + real tx = x->getParameter(edge); + real ty = y->getParameter(edge); + if(tx > ty) + return true; + return false; + } +}; + +struct silhouette_binary_rule : public binary_rule<segment,segment> +{ + silhouette_binary_rule() : binary_rule<segment,segment>() {} + virtual bool operator() (segment& s1, segment& s2) + { + FEdge * f1 = s1.edge(); + FEdge * f2 = s2.edge(); + + if((!(((f1)->getNature() & Nature::SILHOUETTE) || ((f1)->getNature() & Nature::BORDER))) && (!(((f2)->getNature() & Nature::SILHOUETTE) || ((f2)->getNature() & Nature::BORDER)))) + return false; + + return true; + } +}; + +void ViewMapBuilder::ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon) +{ + vector<SVertex*>& svertices = ioViewMap->SVertices(); + bool progressBarDisplay = false; + unsigned sVerticesSize = svertices.size(); + unsigned fEdgesSize = ioViewMap->FEdges().size(); + // ViewMap::fedges_container& fedges = ioViewMap->FEdges(); + // for(ViewMap::fedges_container::const_iterator f=fedges.begin(), end=fedges.end(); + // f!=end; + // ++f){ + // cout << (*f)->aMaterialIndex() << "-" << (*f)->bMaterialIndex() << endl; + // } + + unsigned progressBarStep = 0; + + if(_pProgressBar != NULL && fEdgesSize > gProgressBarMinSize) { + unsigned progressBarSteps = min(gProgressBarMaxSteps, sVerticesSize); + progressBarStep = sVerticesSize / progressBarSteps; + _pProgressBar->reset(); + _pProgressBar->setLabelText("Computing Sweep Line Intersections"); + _pProgressBar->setTotalSteps(progressBarSteps); + _pProgressBar->setProgress(0); + progressBarDisplay = true; + } + + unsigned counter = progressBarStep; + + sort(svertices.begin(), svertices.end(), less_SVertex2D(epsilon)); + + SweepLine<FEdge*,Vec3r> SL; + + vector<FEdge*>& ioEdges = ioViewMap->FEdges(); + + vector<segment* > segments; + + vector<FEdge*>::iterator fe,fend; + + for(fe=ioEdges.begin(), fend=ioEdges.end(); + fe!=fend; + fe++) + { + segment * s = new segment((*fe), (*fe)->vertexA()->point2D(), (*fe)->vertexB()->point2D()); + (*fe)->userdata = s; + segments.push_back(s); + } + + vector<segment*> vsegments; + for(vector<SVertex*>::iterator sv=svertices.begin(),svend=svertices.end(); + sv!=svend; + sv++) + { + const vector<FEdge*>& vedges = (*sv)->fedges(); + + for(vector<FEdge*>::const_iterator sve=vedges.begin(), sveend=vedges.end(); + sve!=sveend; + sve++) + { + vsegments.push_back((segment*)((*sve)->userdata)); + } + + Vec3r evt((*sv)->point2D()); + silhouette_binary_rule sbr; + SL.process(evt, vsegments, sbr, epsilon); + + if(progressBarDisplay) { + counter--; + if (counter <= 0) { + counter = progressBarStep; + _pProgressBar->setProgress(_pProgressBar->getProgress() + 1); + } + } + vsegments.clear(); + } + + // reset userdata: + for(fe=ioEdges.begin(), fend=ioEdges.end(); + fe!=fend; + fe++) + (*fe)->userdata = NULL; + + // list containing the new edges resulting from splitting operations. + vector<FEdge*> newEdges; + + // retrieve the intersected edges: + vector<segment* >& iedges = SL.intersectedEdges(); + // retrieve the intersections: + vector<intersection*>& intersections = SL.intersections(); + + int id=0; + // create a view vertex for each intersection and linked this one + // with the intersection object + vector<intersection*>::iterator i, iend; + for(i=intersections.begin(),iend=intersections.end(); + i!=iend; + i++) + { + FEdge *fA = (*i)->EdgeA->edge(); + FEdge *fB = (*i)->EdgeB->edge(); + + Vec3r A1 = fA->vertexA()->point3D(); + Vec3r A2 = fA->vertexB()->point3D(); + Vec3r B1 = fB->vertexA()->point3D(); + Vec3r B2 = fB->vertexB()->point3D(); + + Vec3r a1 = fA->vertexA()->point2D(); + Vec3r a2 = fA->vertexB()->point2D(); + Vec3r b1 = fB->vertexA()->point2D(); + Vec3r b2 = fB->vertexB()->point2D(); + + real ta = (*i)->tA; + real tb = (*i)->tB; + + if((ta < -epsilon) || (ta > 1+epsilon)) + cerr << "Warning: 2D intersection out of range for edge " << fA->vertexA()->getId() << " - " << fA->vertexB()->getId() << endl; + + if((tb < -epsilon) || (tb > 1+epsilon)) + cerr << "Warning: 2D intersection out of range for edge " << fB->vertexA()->getId() << " - " << fB->vertexB()->getId() << endl; + + real Ta = SilhouetteGeomEngine::ImageToWorldParameter(fA, ta); + real Tb = SilhouetteGeomEngine::ImageToWorldParameter(fB, tb); + + if((Ta < -epsilon) || (Ta > 1+epsilon)) + cerr << "Warning: 3D intersection out of range for edge " << fA->vertexA()->getId() << " - " << fA->vertexB()->getId() << endl; + + if((Tb < -epsilon) || (Tb > 1+epsilon)) + cerr << "Warning: 3D intersection out of range for edge " << fB->vertexA()->getId() << " - " << fB->vertexB()->getId() << endl; + +#if 0 + if((Ta < -epsilon) || (Ta > 1+epsilon) || (Tb < -epsilon) || (Tb > 1+epsilon)) { + printf("ta %.12e\n", ta); + printf("tb %.12e\n", tb); + printf("a1 %e, %e -- b1 %e, %e\n", a1[0], a1[1], b1[0], b1[1]); + printf("a2 %e, %e -- b2 %e, %e\n", a2[0], a2[1], b2[0], b2[1]); + if((Ta < -epsilon) || (Ta > 1+epsilon)) + printf("Ta %.12e\n", Ta); + if((Tb < -epsilon) || (Tb > 1+epsilon)) + printf("Tb %.12e\n", Tb); + printf("A1 %e, %e, %e -- B1 %e, %e, %e\n", A1[0], A1[1], A1[2], B1[0], B1[1], B1[2]); + printf("A2 %e, %e, %e -- B2 %e, %e, %e\n", A2[0], A2[1], A2[2], B2[0], B2[1], B2[2]); + } +#endif + + TVertex * tvertex = ioViewMap->CreateTVertex(Vec3r(A1 + Ta*(A2-A1)), Vec3r(a1 + ta*(a2-a1)), fA, + Vec3r(B1 + Tb*(B2-B1)), Vec3r(b1 + tb*(b2-b1)), fB, id); + + (*i)->userdata = tvertex; + ++id; + } + + progressBarStep = 0; + + if(progressBarDisplay) { + unsigned iEdgesSize = iedges.size(); + unsigned progressBarSteps = min(gProgressBarMaxSteps, iEdgesSize); + progressBarStep = iEdgesSize / progressBarSteps; + _pProgressBar->reset(); + _pProgressBar->setLabelText("Splitting intersected edges"); + _pProgressBar->setTotalSteps(progressBarSteps); + _pProgressBar->setProgress(0); + } + + counter = progressBarStep; + + vector<TVertex*> edgeVVertices; + vector<ViewEdge*> newVEdges; + vector<segment* >::iterator s, send; + for(s=iedges.begin(),send=iedges.end(); + s!=send; + s++) + { + edgeVVertices.clear(); + newEdges.clear(); + newVEdges.clear(); + + FEdge* fedge = (*s)->edge(); + ViewEdge *vEdge = fedge->viewedge(); + ViewShape *shape = vEdge->viewShape(); + + vector<intersection*>& eIntersections = (*s)->intersections(); + // we first need to sort these intersections from farther to closer to A + sort(eIntersections.begin(), eIntersections.end(), less_Intersection(*s)); + for(i=eIntersections.begin(),iend=eIntersections.end(); + i!=iend; + i++) + edgeVVertices.push_back((TVertex*)(*i)->userdata); + + shape->SplitEdge(fedge, edgeVVertices, ioViewMap->FEdges(), ioViewMap->ViewEdges()); + + if(progressBarDisplay) { + counter--; + if (counter <= 0) { + counter = progressBarStep; + _pProgressBar->setProgress(_pProgressBar->getProgress() + 1); + } + } + } + + // reset userdata: + for(fe=ioEdges.begin(), fend=ioEdges.end(); + fe!=fend; + fe++) + (*fe)->userdata = NULL; + + // delete segments + // if(!segments.empty()){ + // for(s=segments.begin(),send=segments.end(); + // s!=send; + // s++){ + // delete *s; + // } + // segments.clear(); + // } +} diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h new file mode 100755 index 00000000000..aad9aa245b7 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h @@ -0,0 +1,226 @@ +// +// Filename : ViewMapBuilder.h +// Author(s) : Stephane Grabli +// Purpose : Class to build silhouette edges from a +// Winged-Edge structure +// Date of creation : 25/03/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef VIEWMAPBUILDER_H +# define VIEWMAPBUILDER_H + +# include <vector> +# include "../system/FreestyleConfig.h" +# include "../geometry/Geom.h" +# include "../scene_graph/NodeGroup.h" +# include "../winged_edge/WXEdge.h" +# include "Silhouette.h" +# include "../geometry/GeomUtils.h" +# include "../geometry/Grid.h" +# include "../system/ProgressBar.h" +# include "../geometry/SweepLine.h" +# include "ViewMap.h" +# include "SilhouetteGeomEngine.h" +# include "../scene_graph/TriangleRep.h" +# include "../winged_edge/WEdge.h" +# include "ViewEdgeXBuilder.h" + + +using namespace Geometry; + +class LIB_VIEW_MAP_EXPORT ViewMapBuilder +{ +private: + + ViewMap * _ViewMap; // result + //SilhouetteGeomEngine _GeomEngine; + ProgressBar *_pProgressBar; + Vec3r _viewpoint; + bool _orthographicProjection; + Grid* _Grid; + ViewEdgeXBuilder *_pViewEdgeBuilder; + bool _EnableQI; + double _epsilon; + + // tmp values: + int _currentId; + int _currentFId; + int _currentSVertexId; + + +public: + + typedef enum { + sweep_line + } intersection_algo; + + typedef enum { + ray_casting, + ray_casting_fast, + ray_casting_very_fast + } visibility_algo; + + inline ViewMapBuilder() + { + _pProgressBar = 0; + _Grid = 0; + _currentId = 1; + _currentFId = 0; + _currentSVertexId = 0; + _pViewEdgeBuilder = new ViewEdgeXBuilder; + _EnableQI = true; + } + + inline ~ViewMapBuilder() + { + if(_pViewEdgeBuilder){ + delete _pViewEdgeBuilder; + _pViewEdgeBuilder = 0; + } + } + + /*! Compute Shapes from a WingedEdge containing a list of WShapes */ + void computeInitialViewEdges(WingedEdge&); + + /*! Compute Cusps */ + void computeCusps(ViewMap *ioViewMap); + /*! Detects cusps (for a single ViewEdge) among SVertices and builds a ViewVertex on top of + * each cusp SVertex + * We use a hysteresis approach to avoid noise. + */ + void DetectCusps(ViewEdge *ioEdge); + + + /*! Sets the current viewpoint */ + inline void setViewpoint(const Vec3r& ivp) {_viewpoint = ivp; SilhouetteGeomEngine::setViewpoint(ivp);} + + /*! Sets the current transformation + * iModelViewMatrix + * The 4x4 model view matrix, in column major order (openGL like). + * iProjection matrix + * The 4x4 projection matrix, in column major order (openGL like). + * iViewport + * The viewport. 4 real array: origin.x, origin.y, width, length + */ + inline void setTransform(const real iModelViewMatrix[4][4], + const real iProjectionMatrix[4][4], + const int iViewport[4], + real iFocalLength, + real iAspect, + real iFovy) { + _orthographicProjection = (iProjectionMatrix[3][3] != 0.0); + SilhouetteGeomEngine::setTransform(iModelViewMatrix, iProjectionMatrix, iViewport, iFocalLength); + } + + inline void setFrustum(real iZnear, real iZfar) { + SilhouetteGeomEngine::setFrustum(iZnear, iZfar); + } + + /*! Builds the scene view map + * returns the list the view map + * it is up to the caller to delete this ViewMap + * iWRoot + * The root group node containing the WEdge structured scene + */ + + ViewMap* BuildViewMap(WingedEdge& we, visibility_algo iAlgo = ray_casting, real epsilon=1e-06) ; + /*! computes the intersection between all 2D + * feature edges of the scene. + * ioViewMap + * The view map. It is modified by the method. + * The list of all features edges of the scene. + * Each time an intersection is found, the 2 intersecting + * edges are splitted (creating 2 new vertices) + * At the end, this list is updated with the adding + * of all new created edges (resulting from splitting). + * iAlgo + * The algo to use for computing the intersections + */ + void ComputeIntersections(ViewMap *ioViewMap, intersection_algo iAlgo = sweep_line, real epsilon=1e-06); + + /*! Computes the 2D scene silhouette edges visibility + * iGrid + * For the Ray Casting algorithm. + */ + void ComputeEdgesVisibility(ViewMap *ioViewMap, visibility_algo iAlgo= ray_casting, Grid* iGrid = 0, real epsilon=1e-6); + + void setGrid(Grid *iGrid) {_Grid = iGrid;} + + /*! accessors */ + + /*! Modifiers */ + inline void setProgressBar(ProgressBar *iProgressBar) {_pProgressBar = iProgressBar;} + inline void setEnableQI(bool iBool) {_EnableQI = iBool;} + +protected: + + /*! Computes intersections on all edges of the scene using a sweep line + * algorithm*/ + void ComputeSweepLineIntersections(ViewMap *ioViewMap, real epsilon = 1e-6); + + /*! Computes the 2D scene silhouette edges visibility + * using a ray casting. On each edge, a ray is cast + * to check its quantitative invisibility. The list + * of occluders are each time stored in the tested edge. + * ioViewMap + * The view map. + * The 2D scene silhouette edges as FEdges. + * These edges have already been splitted at their intersections points. + * Thus, these edges do not intersect anymore. + * The visibility corresponding to each edge of ioScene is set is this + * edge. + */ + void ComputeRayCastingVisibility(ViewMap *ioViewMap, Grid *iGrid, real epsilon=1e-6); + void ComputeFastRayCastingVisibility(ViewMap *ioViewMap, Grid *iGrid, real epsilon=1e-6); + void ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, Grid *iGrid, real epsilon=1e-6); + + /*! Compute the visibility for the FEdge fe. + * The occluders are added to fe occluders list. + * fe + * The FEdge + * iGrid + * The grid used to compute the ray casting visibility + * epsilon + * The epsilon used for computation + * oShapeId + * fe is the border (in 2D) between 2 2D spaces. + * if fe is a silhouette, + * One of these 2D spaces is occupied by the shape + * to which fe belongs (on its left) and the other one is either occupied + * by another shape or empty or occupied by the same shape. + * We use this ray csating operation to determine which shape + * lies on fe's right. + * The result is the shape id stored in oShapeId + */ + int ComputeRayCastingVisibility(FEdge *fe, Grid* iGrid, real epsilon, set<ViewShape*>& oOccluders, + Polygon3r** oaPolygon, unsigned timestamp); + // FIXME + void FindOccludee(FEdge *fe, Grid* iGrid, real epsilon, Polygon3r** oaPolygon, unsigned timestamp); + void FindOccludee(FEdge *fe, Grid* iGrid, real epsilon, Polygon3r** oaPolygon, unsigned timestamp, + Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices); + +}; + +#endif // VIEWMAPBUILDER_H diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.cpp b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp new file mode 100755 index 00000000000..f99a574766b --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewMapIO.cpp @@ -0,0 +1,1245 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "ViewMapIO.h" + +#ifdef IRIX +# define WRITE(n) Internal::write<sizeof((n))>(out, (const char*)(&(n))) +# define READ(n) Internal::read<sizeof((n))>(in, (char*)(&(n))) +#else +# define WRITE(n) out.write((const char*)(&(n)), sizeof((n))) +# define READ(n) in.read((char*)(&(n)), sizeof((n))) +#endif + +#define WRITE_IF_NON_NULL(ptr) if ((ptr) == NULL) { WRITE(ZERO); } else { WRITE((ptr)->userdata); } +#define READ_IF_NON_NULL(ptr, array) READ(tmp); if (tmp == ZERO) { (ptr) = NULL; } else { (ptr) = (array)[tmp]; } + +namespace ViewMapIO { + + namespace Internal { + + ViewMap* g_vm; + + //////////////////// 'load' Functions //////////////////// + + inline + int load(istream& in, Vec3r& v) { + + if (Options::getFlags() & Options::FLOAT_VECTORS) { + float tmp; + READ(tmp); + v[0] = tmp; + READ(tmp); + v[1] = tmp; + READ(tmp); + v[2] = tmp; + } else { + Vec3r::value_type tmp; + READ(tmp); + v[0] = tmp; + READ(tmp); + v[1] = tmp; + READ(tmp); + v[2] = tmp; + } + return 0; + } + + + inline + int load(istream& in, Polygon3r& p) { + + unsigned tmp; + + // Id + READ(tmp); + p.setId(tmp); + + // vertices (List) + vector<Vec3r> tmp_vec; + Vec3r v; + READ(tmp); + for (unsigned i = 0; i < tmp; i++) { + load(in, v); + tmp_vec.push_back(v); + } + p.setVertices(tmp_vec); + + // min & max + // Already computed (in the SetVertices() method) + + return 0; + } + + + inline + int load(istream& in, FrsMaterial& m) { + + float tmp_array[4]; + int i; + + // Diffuse + for (i = 0; i < 4; i++) + READ(tmp_array[i]); + m.setDiffuse(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]); + + // Specular + for (i = 0; i < 4; i++) + READ(tmp_array[i]); + m.setSpecular(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]); + + // Ambient + for (i = 0; i < 4; i++) + READ(tmp_array[i]); + m.setAmbient(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]); + + // Emission + for (i = 0; i < 4; i++) + READ(tmp_array[i]); + m.setEmission(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]); + + // Shininess + READ(tmp_array[0]); + m.setShininess(tmp_array[0]); + + return 0; + } + + + int load(istream& in, ViewShape* vs) { + + if (!vs || !vs->sshape()) + return 1; + + // SShape + + // -> Id + Id::id_type id1, id2; + READ(id1); + READ(id2); + vs->sshape()->setId(Id(id1, id2)); + + // -> Importance + float importance; + READ(importance); + vs->sshape()->setImportance(importance); + + // -> BBox + // Not necessary (only used during view map computatiom) + + unsigned i, size, tmp; + + // -> Material + READ(size); + vector<FrsMaterial> frs_materials; + FrsMaterial m; + for(i=0; i<size; ++i){ + load(in, m); + frs_materials.push_back(m); + } + vs->sshape()->setFrsMaterials(frs_materials); + + + + // -> VerticesList (List) + READ(size); + for (i = 0; i < size; i++) { + SVertex* sv; + READ_IF_NON_NULL(sv, g_vm->SVertices()); + vs->sshape()->AddNewVertex(sv); + } + + // -> Chains (List) + READ(size); + for (i = 0; i < size; i++) { + FEdge* fe; + READ_IF_NON_NULL(fe, g_vm->FEdges()); + vs->sshape()->AddChain(fe); + } + + // -> EdgesList (List) + READ(size); + for (i = 0; i < size; i++) { + FEdge* fe; + READ_IF_NON_NULL(fe, g_vm->FEdges()); + vs->sshape()->AddEdge(fe); + } + + // ViewEdges (List) + READ(size); + for (i = 0; i < size; i++) { + ViewEdge* ve; + READ_IF_NON_NULL(ve, g_vm->ViewEdges()); + vs->AddEdge(ve); + } + + // ViewVertices (List) + READ(size); + for (i = 0; i < size; i++) { + ViewVertex* vv; + READ_IF_NON_NULL(vv, g_vm->ViewVertices()); + vs->AddVertex(vv); + } + + return 0; + } + + + int load(istream& in, FEdge* fe) { + + if (!fe) + return 1; + + bool b; + + FEdgeSmooth *fesmooth = 0; + FEdgeSharp * fesharp = 0; + if(fe->isSmooth()){ + fesmooth = dynamic_cast<FEdgeSmooth*>(fe); + }else{ + fesharp = dynamic_cast<FEdgeSharp*>(fe); + } + + // Id + Id::id_type id1, id2; + READ(id1); + READ(id2); + fe->setId(Id(id1, id2)); + + // Nature + Nature::EdgeNature nature; + READ(nature); + fe->setNature(nature); + + // hasVisibilityPoint + // bool b; + // READ(b); + // fe->setHasVisibilityPoint(b); + + Vec3r v; + unsigned int matindex; + + // VisibilityPointA + // load(in, v); + // fe->setVisibilityPointA(v); + + // VisibilityPointB + // load(in, v); + // fe->setVisibilityPointB(v); + + if(fe->isSmooth()){ + // Normal + load(in, v); + fesmooth->setNormal(v); + + // Material + READ(matindex); + fesmooth->setFrsMaterialIndex(matindex); + }else{ + // aNormal + load(in, v); + fesharp->setNormalA(v); + + // bNormal + load(in, v); + fesharp->setNormalB(v); + + // Materials + READ(matindex); + fesharp->setaFrsMaterialIndex(matindex); + READ(matindex); + fesharp->setbFrsMaterialIndex(matindex); + } + + unsigned tmp; + + // VertexA + SVertex* sva; + READ_IF_NON_NULL(sva, g_vm->SVertices()); + fe->setVertexA(sva); + + // VertexB + SVertex* svb; + READ_IF_NON_NULL(svb, g_vm->SVertices()); + fe->setVertexB(svb); + + // NextEdge + FEdge* nfe; + READ_IF_NON_NULL(nfe, g_vm->FEdges()); + fe->setNextEdge(nfe); + + // PreviousEdge + FEdge* pfe; + READ_IF_NON_NULL(pfe, g_vm->FEdges()); + fe->setPreviousEdge(pfe); + + // ViewEdge + ViewEdge* ve; + READ_IF_NON_NULL(ve, g_vm->ViewEdges()); + fe->setViewEdge(ve); + + // Face + // Not necessary (only used during view map computatiom) + + Polygon3r p; + + // aFace + load(in, p); + fe->setaFace(p); + + // occludeeEmpty + READ(b); + fe->setOccludeeEmpty(b); + + // occludeeIntersection + load(in, v); + fe->setOccludeeIntersection(v); + + return 0; + } + + + int load(istream& in, SVertex* sv) { + + if (!sv) + return 1; + + // Id + Id::id_type id1, id2; + READ(id1); + READ(id2); + sv->setId(Id(id1, id2)); + + Vec3r v; + + // Point3D + load(in, v); + sv->setPoint3D(v); + + // Point2D + load(in, v); + sv->setPoint2D(v); + + unsigned tmp; + + // Shape + ViewShape* vs; + READ_IF_NON_NULL(vs, g_vm->ViewShapes()); + sv->setShape(vs->sshape()); + + // pViewVertex + ViewVertex* vv; + READ_IF_NON_NULL(vv, g_vm->ViewVertices()); + sv->setViewVertex(vv); + + unsigned i, size; + + // Normals (List) + READ(size); + for (i = 0; i < size; i++) { + load(in, v); + sv->AddNormal(v); + } + + // FEdges (List) + READ(size); + FEdge* fe; + for (i = 0; i < size; i++) { + READ_IF_NON_NULL(fe, g_vm->FEdges()); + sv->AddFEdge(fe); + } + + return 0; + } + + + int load(istream& in, ViewEdge* ve) { + + if (!ve) + return 1; + + unsigned tmp; + + // Id + Id::id_type id1, id2; + READ(id1); + READ(id2); + ve->setId(Id(id1, id2)); + + // Nature + Nature::EdgeNature nature; + READ(nature); + ve->setNature(nature); + + // QI + READ(tmp); + ve->setQI(tmp); + + // Shape + ViewShape* vs; + READ_IF_NON_NULL(vs, g_vm->ViewShapes()); + ve->setShape(vs); + + // aShape + ViewShape* avs; + READ_IF_NON_NULL(avs, g_vm->ViewShapes()); + ve->setaShape(avs); + + // FEdgeA + FEdge* fea; + READ_IF_NON_NULL(fea, g_vm->FEdges()); + ve->setFEdgeA(fea); + + // FEdgeB + FEdge* feb; + READ_IF_NON_NULL(feb, g_vm->FEdges()); + ve->setFEdgeB(feb); + + // A + ViewVertex* vva; + READ_IF_NON_NULL(vva, g_vm->ViewVertices()); + ve->setA(vva); + + // B + ViewVertex* vvb; + READ_IF_NON_NULL(vvb, g_vm->ViewVertices()); + ve->setB(vvb); + + // Occluders (List) + if (!(Options::getFlags() & Options::NO_OCCLUDERS)) { + unsigned size; + READ(size); + ViewShape* vso; + for (unsigned i = 0; i < size; i++) { + READ_IF_NON_NULL(vso, g_vm->ViewShapes()); + ve->AddOccluder(vso); + } + } + + return 0; + } + + + int load(istream& in, ViewVertex* vv) { + + if (!vv) + return 1; + + unsigned tmp; + bool b; + + // Nature + Nature::VertexNature nature; + READ(nature); + vv->setNature(nature); + + if (vv->getNature() & Nature::T_VERTEX) { + TVertex* tv = dynamic_cast<TVertex*>(vv); + + // Id + Id::id_type id1, id2; + READ(id1); + READ(id2); + tv->setId(Id(id1, id2)); + + // FrontSVertex + SVertex* fsv; + READ_IF_NON_NULL(fsv, g_vm->SVertices()); + tv->setFrontSVertex(fsv); + + // BackSVertex + SVertex* bsv; + READ_IF_NON_NULL(bsv, g_vm->SVertices()); + tv->setBackSVertex(bsv); + + // FrontEdgeA + ViewEdge* fea; + READ_IF_NON_NULL(fea, g_vm->ViewEdges()); + READ(b); + tv->setFrontEdgeA(fea, b); + + // FrontEdgeB + ViewEdge* feb; + READ_IF_NON_NULL(feb, g_vm->ViewEdges()); + READ(b); + tv->setFrontEdgeB(feb, b); + + // BackEdgeA + ViewEdge* bea; + READ_IF_NON_NULL(bea, g_vm->ViewEdges()); + READ(b); + tv->setBackEdgeA(bea, b); + + // BackEdgeB + ViewEdge* beb; + READ_IF_NON_NULL(beb, g_vm->ViewEdges()); + READ(b); + tv->setBackEdgeB(beb, b); + } + else if (vv->getNature() & Nature::NON_T_VERTEX) { + NonTVertex* ntv = dynamic_cast<NonTVertex*>(vv); + + // SVertex + SVertex* sv; + READ_IF_NON_NULL(sv, g_vm->SVertices()); + ntv->setSVertex(sv); + + // ViewEdges (List) + unsigned size; + READ(size); + ViewEdge* ve; + for (unsigned i = 0; i < size; i++) { + READ_IF_NON_NULL(ve, g_vm->ViewEdges()); + READ(b); + ntv->AddViewEdge(ve, b); + } + } + + return 0; + } + + //////////////////// 'save' Functions //////////////////// + + inline + int save(ostream& out, const Vec3r& v) { + + if (Options::getFlags() & Options::FLOAT_VECTORS) { + float tmp; + + tmp = v[0]; + WRITE(tmp); + tmp = v[1]; + WRITE(tmp); + tmp = v[2]; + WRITE(tmp); + } else { + Vec3r::value_type tmp; + + tmp = v[0]; + WRITE(tmp); + tmp = v[1]; + WRITE(tmp); + tmp = v[2]; + WRITE(tmp); + } + return 0; + } + + + inline + int save(ostream& out, const Polygon3r& p) { + + unsigned tmp; + + // Id + tmp = p.getId(); + WRITE(tmp); + + // vertices (List) + tmp = p.getVertices().size(); + WRITE(tmp); + for (vector<Vec3r>::const_iterator i = p.getVertices().begin(); + i != p.getVertices().end(); i++) { + save(out, *i); + } + + // min & max + // Do not need to be saved + + return 0; + } + + + inline + int save(ostream& out, const FrsMaterial& m) { + + unsigned i; + + // Diffuse + for (i = 0; i < 4; i++) + WRITE(m.diffuse()[i]); + + // Specular + for (i = 0; i < 4; i++) + WRITE(m.specular()[i]); + + // Ambient + for (i = 0; i < 4; i++) + WRITE(m.ambient()[i]); + + // Emission + for (i = 0; i < 4; i++) + WRITE(m.emission()[i]); + + // Shininess + float shininess = m.shininess(); + WRITE(shininess); + + return 0; + } + + + int save(ostream& out, ViewShape* vs) { + + if (!vs || !vs->sshape()) { + cerr << "Warning: null ViewShape" << endl; + return 1; + } + + unsigned tmp; + + // SShape + + // -> Id + Id::id_type id = vs->sshape()->getId().getFirst(); + WRITE(id); + id = vs->sshape()->getId().getSecond(); + WRITE(id); + + // -> Importance + float importance = vs->sshape()->importance(); + WRITE(importance); + + // -> BBox + // Not necessary (only used during view map computatiom) + + // -> Material + unsigned size = vs->sshape()->frs_materials().size(); + WRITE(size); + for(unsigned i=0; i<size; ++i) + save(out, vs->sshape()->frs_material(i)); + + // -> VerticesList (List) + tmp = vs->sshape()->getVertexList().size(); + WRITE(tmp); + for (vector<SVertex*>::const_iterator i1 = vs->sshape()->getVertexList().begin(); + i1 != vs->sshape()->getVertexList().end(); i1++) + WRITE_IF_NON_NULL(*i1); + + // -> Chains (List) + tmp = vs->sshape()->getChains().size(); + WRITE(tmp); + for (vector<FEdge*>::const_iterator i2 = vs->sshape()->getChains().begin(); + i2 != vs->sshape()->getChains().end(); i2++) + WRITE_IF_NON_NULL(*i2); + + // -> EdgesList (List) + tmp = vs->sshape()->getEdgeList().size(); + WRITE(tmp); + for (vector<FEdge*>::const_iterator i3 = vs->sshape()->getEdgeList().begin(); + i3 != vs->sshape()->getEdgeList().end(); i3++) + WRITE_IF_NON_NULL(*i3); + + // ViewEdges (List) + tmp = vs->edges().size(); + WRITE(tmp); + for (vector<ViewEdge*>::const_iterator i4 = vs->edges().begin(); + i4 != vs->edges().end(); i4++) + WRITE_IF_NON_NULL(*i4); + + // ViewVertices (List) + tmp = vs->vertices().size(); + WRITE(tmp); + for (vector<ViewVertex*>::const_iterator i5 = vs->vertices().begin(); + i5 != vs->vertices().end(); i5++) + WRITE_IF_NON_NULL(*i5); + + + return 0; + } + + + int save(ostream& out, FEdge* fe) { + + if (!fe) { + cerr << "Warning: null FEdge" << endl; + return 1; + } + + FEdgeSmooth * fesmooth = dynamic_cast<FEdgeSmooth*>(fe); + FEdgeSharp * fesharp = dynamic_cast<FEdgeSharp*>(fe); + + // Id + Id::id_type id = fe->getId().getFirst(); + WRITE(id); + id = fe->getId().getSecond(); + WRITE(id); + + // Nature + Nature::EdgeNature nature = fe->getNature(); + WRITE(nature); + + bool b; + + // hasVisibilityPoint + // b = fe->hasVisibilityPoint(); + // WRITE(b); + + // VisibilityPointA + // save(out, fe->visibilityPointA()); + // + // // VisibilityPointB + // save(out, fe->visibilityPointB()); + + unsigned index; + if(fe->isSmooth()){ + // normal + save(out, fesmooth->normal()); + // material + index = fesmooth->frs_materialIndex(); + WRITE(index); + }else{ + // aNormal + save(out, fesharp->normalA()); + // bNormal + save(out, fesharp->normalB()); + // aMaterial + index = fesharp->aFrsMaterialIndex(); + WRITE(index); + // bMaterial + index = fesharp->bFrsMaterialIndex(); + WRITE(index); + } + + + // VertexA + WRITE_IF_NON_NULL(fe->vertexA()); + + // VertexB + WRITE_IF_NON_NULL(fe->vertexB()); + + // NextEdge + WRITE_IF_NON_NULL(fe->nextEdge()); + + // PreviousEdge + WRITE_IF_NON_NULL(fe->previousEdge()); + + // ViewEdge + WRITE_IF_NON_NULL(fe->viewedge()); + + // Face + // Not necessary (only used during view map computatiom) + + // aFace + save(out, (Polygon3r&)fe->aFace()); + + // occludeeEmpty + b = fe->getOccludeeEmpty(); + WRITE(b); + + // occludeeIntersection + save(out, fe->getOccludeeIntersection()); + + return 0; + } + + + int save(ostream& out, SVertex* sv) { + + if (!sv) { + cerr << "Warning: null SVertex" << endl; + return 1; + } + + unsigned tmp; + + // Id + Id::id_type id = sv->getId().getFirst(); + WRITE(id); + id = sv->getId().getSecond(); + WRITE(id); + + Vec3r v; + + // Point3D + v = sv->point3D(); + save(out, sv->point3D()); + + // Point2D + v = sv->point2D(); + save(out, v); + + // Shape + WRITE_IF_NON_NULL(sv->shape()); + + // pViewVertex + WRITE_IF_NON_NULL(sv->viewvertex()); + + // Normals (List) + // Note: the 'size()' method of a set doesn't seem to return the + // actual size of the given set, so we have to hack it... + set<Vec3r>::const_iterator i; + for (i = sv->normals().begin(), tmp = 0; + i != sv->normals().end(); + i++, tmp++); + WRITE(tmp); + for (i = sv->normals().begin(); i != sv->normals().end(); i++) + save(out, *i); + + // FEdges (List) + tmp = sv->fedges().size(); + WRITE(tmp); + for (vector<FEdge*>::const_iterator j = sv->fedges_begin(); + j != sv->fedges_end(); j++) + WRITE_IF_NON_NULL(*j); + + return 0; + } + + + int save(ostream& out, ViewEdge* ve) { + + if (!ve) { + cerr << "Warning: null ViewEdge" << endl; + return 1; + } + + unsigned tmp; + + // Id + Id::id_type id = ve->getId().getFirst(); + WRITE(id); + id = ve->getId().getSecond(); + WRITE(id); + + // Nature + Nature::EdgeNature nature = ve->getNature(); + WRITE(nature); + + // QI + unsigned qi = ve->qi(); + WRITE(qi); + + // Shape + WRITE_IF_NON_NULL(ve->shape()); + + // aShape + WRITE_IF_NON_NULL(ve->aShape()); + + // FEdgeA + WRITE_IF_NON_NULL(ve->fedgeA()); + + // FEdgeB + WRITE_IF_NON_NULL(ve->fedgeB()); + + // A + WRITE_IF_NON_NULL(ve->A()); + + // B + WRITE_IF_NON_NULL(ve->B()); + + // Occluders (List) + if (!(Options::getFlags() & Options::NO_OCCLUDERS)) { + tmp = ve->occluders().size(); + WRITE(tmp); + for (vector<ViewShape*>::const_iterator i = ve->occluders().begin(); + i != ve->occluders().end(); i++) + WRITE_IF_NON_NULL((*i)); + } + + return 0; + } + + + int save(ostream& out, ViewVertex* vv) { + + if (!vv) { + cerr << "Warning: null ViewVertex" << endl; + return 1; + } + + // Nature + Nature::VertexNature nature = vv->getNature(); + WRITE(nature); + + if (vv->getNature() & Nature::T_VERTEX) { + TVertex* tv = dynamic_cast<TVertex*>(vv); + + // Id + Id::id_type id = tv->getId().getFirst(); + WRITE(id); + id = tv->getId().getSecond(); + WRITE(id); + + // FrontSVertex + WRITE_IF_NON_NULL(tv->frontSVertex()); + + // BackSVertex + WRITE_IF_NON_NULL(tv->backSVertex()); + + // FrontEdgeA + WRITE_IF_NON_NULL(tv->frontEdgeA().first); + WRITE(tv->frontEdgeA().second); + + // FrontEdgeB + WRITE_IF_NON_NULL(tv->frontEdgeB().first); + WRITE(tv->frontEdgeB().second); + + // BackEdgeA + WRITE_IF_NON_NULL(tv->backEdgeA().first); + WRITE(tv->backEdgeA().second); + + // BackEdgeB + WRITE_IF_NON_NULL(tv->backEdgeB().first); + WRITE(tv->backEdgeB().second); + + } + else if (vv->getNature() & Nature::NON_T_VERTEX) { + NonTVertex* ntv = dynamic_cast<NonTVertex*>(vv); + + // SVertex + WRITE_IF_NON_NULL(ntv->svertex()); + + // ViewEdges (List) + unsigned size = ntv->viewedges().size(); + WRITE(size); + vector<ViewVertex::directedViewEdge>::const_iterator i = ntv->viewedges().begin(); + for ( ; i != ntv->viewedges().end(); i++){ + WRITE_IF_NON_NULL(i->first); + WRITE(i->second); + } + + } else { + cerr << "Warning: unexpected ViewVertex nature" << endl; + return 1; + } + + return 0; + } + + } // End of namespace Internal + + + //////////////////// "Public" 'load' and 'save' functions //////////////////// + +#define SET_PROGRESS(n) if (pb) pb->setProgress((n)) + + int load(istream& in, ViewMap* vm, ProgressBar* pb) { + + if (!vm) + return 1; + + //soc unused - unsigned tmp; + + int err = 0; + + Internal::g_vm = vm; + + // Management of the progress bar (if present) + if (pb) { + pb->reset(); + pb->setLabelText("Loading View Map..."); + pb->setTotalSteps(6); + pb->setProgress(0); + } + + // Read and set the options + unsigned char flags; + READ(flags); + Options::setFlags(flags); + + // Read the size of the five ViewMap's lists (with some extra informations for the ViewVertices) + // and instantiate them (with default costructors) + unsigned vs_s, fe_s, fe_rle1, fe_rle2, sv_s, ve_s, vv_s, vv_rle1, vv_rle2; + READ(vs_s); + READ(fe_s); + + if (fe_s) { + bool b; + READ(b); + for (READ(fe_rle1), fe_rle2 = 0; + fe_rle1 < fe_s+1; + fe_rle2 = fe_rle1, READ(fe_rle1)) { + if (b) { + for (unsigned i = fe_rle2; i < fe_rle1; i++) { + FEdgeSmooth * fes = new FEdgeSmooth; + vm->AddFEdge(fes); + } + b = !b; + } + else if (!b) { + for (unsigned i = fe_rle2; i < fe_rle1; i++) { + FEdgeSharp * fes = new FEdgeSharp; + vm->AddFEdge(fes); + } + b = !b; + } + } + } + + READ(sv_s); + READ(ve_s); + READ(vv_s); + + if (vv_s) { + Nature::VertexNature nature; + READ(nature); + for (READ(vv_rle1), vv_rle2 = 0; + vv_rle1 < vv_s+1; + vv_rle2 = vv_rle1, READ(vv_rle1)) { + if (nature & Nature::T_VERTEX) { + for (unsigned i = vv_rle2; i < vv_rle1; i++) { + TVertex* tv = new TVertex(); + vm->AddViewVertex(tv); + } + nature = Nature::NON_T_VERTEX; + } + else if (nature & Nature::NON_T_VERTEX) { + for (unsigned i = vv_rle2; i < vv_rle1; i++) { + NonTVertex* ntv = new NonTVertex(); + vm->AddViewVertex(ntv); + } + nature = Nature::T_VERTEX; + } + } + } + + for (unsigned i0 = 0; i0 < vs_s; i0++) { + SShape* ss = new SShape(); + ViewShape* vs = new ViewShape(); + vs->setSShape(ss); + ss->setViewShape(vs); + vm->AddViewShape(vs); + } + // for (unsigned i1 = 0; i1 < fe_s; i1++) { + // FEdge* fe = new FEdge(); + // vm->AddFEdge(fe); + // } + for (unsigned i2 = 0; i2 < sv_s; i2++) { + SVertex* sv = new SVertex(); + vm->AddSVertex(sv); + } + for (unsigned i3 = 0; i3 < ve_s; i3++) { + ViewEdge* ve = new ViewEdge(); + vm->AddViewEdge(ve); + } + + + // Read the values for all the objects created above + SET_PROGRESS(1); + for (vector<ViewShape*>::const_iterator i4 = vm->ViewShapes().begin(); + i4 != vm->ViewShapes().end(); i4++) + err += Internal::load(in, *i4); + SET_PROGRESS(2); + for (vector<FEdge*>::const_iterator i5 = vm->FEdges().begin(); + i5 != vm->FEdges().end(); i5++) + err += Internal::load(in, *i5); + SET_PROGRESS(3); + for (vector<SVertex*>::const_iterator i6 = vm->SVertices().begin(); + i6 != vm->SVertices().end(); i6++) + err += Internal::load(in, *i6); + SET_PROGRESS(4); + for (vector<ViewEdge*>::const_iterator i7 = vm->ViewEdges().begin(); + i7 != vm->ViewEdges().end(); i7++) + err += Internal::load(in, *i7); + SET_PROGRESS(5); + for (vector<ViewVertex*>::const_iterator i8 = vm->ViewVertices().begin(); + i8 != vm->ViewVertices().end(); i8++) + err += Internal::load(in, *i8); + SET_PROGRESS(6); + + // Read the shape id to index mapping + unsigned map_s; + READ(map_s); + unsigned id,index; + for(unsigned i4=0;i4<map_s;++i4){ + READ(id); + READ(index); + vm->shapeIdToIndexMap()[id] = index; + } + + return err; + } + + + int save(ostream& out, ViewMap* vm, ProgressBar* pb) { + + if (!vm) + return 1; + + int err = 0; + + // Management of the progress bar (if present) + if (pb) { + pb->reset(); + pb->setLabelText("Saving View Map..."); + pb->setTotalSteps(6); + pb->setProgress(0); + } + + // For every object, initialize its userdata member to its index in the ViewMap list + for (unsigned i0 = 0; i0 < vm->ViewShapes().size(); i0++) { + vm->ViewShapes()[i0]->userdata = (void*)i0; + vm->ViewShapes()[i0]->sshape()->userdata = (void*)i0; + } + for (unsigned i1 = 0; i1 < vm->FEdges().size(); i1++) + vm->FEdges()[i1]->userdata = (void*)i1; + for (unsigned i2 = 0; i2 < vm->SVertices().size(); i2++) + vm->SVertices()[i2]->userdata = (void*)i2; + for (unsigned i3 = 0; i3 < vm->ViewEdges().size(); i3++) + vm->ViewEdges()[i3]->userdata = (void*)i3; + for (unsigned i4 = 0; i4 < vm->ViewVertices().size(); i4++) + vm->ViewVertices()[i4]->userdata = (void*)i4; + + // Write the current options + unsigned char flags = Options::getFlags(); + WRITE(flags); + + // Write the size of the five lists (with some extra informations for the ViewVertices) + unsigned size; + size = vm->ViewShapes().size(); + WRITE(size); + size = vm->FEdges().size(); + WRITE(size); + if (size) { + bool b = vm->FEdges()[0]->isSmooth(); + WRITE(b); + for (unsigned i = 0; i < size; i++) { + while (i < size && (vm->FEdges()[i]->isSmooth() == b)) + i++; + if (i < size) { + WRITE(i); + b = !b; + } + } + WRITE(size); + size++; + WRITE(size); + } + size = vm->SVertices().size(); + WRITE(size); + size = vm->ViewEdges().size(); + WRITE(size); + size = vm->ViewVertices().size(); + WRITE(size); + if (size) { + Nature::VertexNature nature = vm->ViewVertices()[0]->getNature(); + WRITE(nature); + nature &= ~Nature::VIEW_VERTEX; + for (unsigned i = 0; i < size; i++) { + while (i < size && (vm->ViewVertices()[i]->getNature() & nature)) + i++; + if (i < size) { + WRITE(i); + nature = vm->ViewVertices()[i]->getNature() & ~Nature::VIEW_VERTEX; + } + } + WRITE(size); + size++; + WRITE(size); + } + + + // Write all the elts of the ViewShapes List + SET_PROGRESS(1); + for (vector<ViewShape*>::const_iterator i5 = vm->ViewShapes().begin(); + i5 != vm->ViewShapes().end(); i5++) + err += Internal::save(out, *i5); + SET_PROGRESS(2); + for (vector<FEdge*>::const_iterator i6 = vm->FEdges().begin(); + i6 != vm->FEdges().end(); i6++) + err += Internal::save(out, *i6); + SET_PROGRESS(3); + for (vector<SVertex*>::const_iterator i7 = vm->SVertices().begin(); + i7 != vm->SVertices().end(); i7++) + err += Internal::save(out, *i7); + SET_PROGRESS(4); + for (vector<ViewEdge*>::const_iterator i8 = vm->ViewEdges().begin(); + i8 != vm->ViewEdges().end(); i8++) + err += Internal::save(out, *i8); + SET_PROGRESS(5); + for (vector<ViewVertex*>::const_iterator i9 = vm->ViewVertices().begin(); + i9 != vm->ViewVertices().end(); i9++) + err += Internal::save(out, *i9); + + // Write the shape id to index mapping + size = vm->shapeIdToIndexMap().size(); + WRITE(size); + unsigned id,index; + for(ViewMap::id_to_index_map::iterator mit=vm->shapeIdToIndexMap().begin(), mitend=vm->shapeIdToIndexMap().end(); mit!=mitend; ++mit){ + id = mit->first; + index = mit->second; + WRITE(id); + WRITE(index); + } + + // Reset 'userdata' members + for (vector<ViewShape*>::const_iterator j0 = vm->ViewShapes().begin(); + j0 != vm->ViewShapes().end(); j0++) { + (*j0)->userdata = 0; + (*j0)->sshape()->userdata = 0; + } + for (vector<FEdge*>::const_iterator j1 = vm->FEdges().begin(); + j1 != vm->FEdges().end(); j1++) + (*j1)->userdata = 0; + for (vector<SVertex*>::const_iterator j2 = vm->SVertices().begin(); + j2 != vm->SVertices().end(); j2++) + (*j2)->userdata = 0; + for (vector<ViewEdge*>::const_iterator j3 = vm->ViewEdges().begin(); + j3 != vm->ViewEdges().end(); j3++) + (*j3)->userdata = 0; + for (vector<ViewVertex*>::const_iterator j4 = vm->ViewVertices().begin(); + j4 != vm->ViewVertices().end(); j4++) + (*j4)->userdata = 0; + SET_PROGRESS(6); + + return err; + } + + + //////////////////// Options //////////////////// + + namespace Options { + + namespace Internal { + + static unsigned char g_flags = 0; + static string g_models_path; + + } // End of namespace Internal + + void setFlags(const unsigned char flags) { + Internal::g_flags = flags; + } + + void addFlags(const unsigned char flags) { + Internal::g_flags |= flags; + } + + void rmFlags(const unsigned char flags) { + Internal::g_flags &= ~flags; + } + + unsigned char getFlags() { + return Internal::g_flags; + } + + void setModelsPath(const string& path) { + Internal::g_models_path = path; + } + + string getModelsPath() { + return Internal::g_models_path; + } + + }; // End of namepace Options + +} // End of namespace ViewMapIO diff --git a/source/blender/freestyle/intern/view_map/ViewMapIO.h b/source/blender/freestyle/intern/view_map/ViewMapIO.h new file mode 100755 index 00000000000..33e168b537b --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewMapIO.h @@ -0,0 +1,116 @@ +// +// Filename : ViewMapIO.h +// Author(s) : Emmanuel Turquin +// Purpose : Functions to manage I/O for the view map +// Date of creation : 09/01/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef VIEWMAPIO_H +# define VIEWMAPIO_H + +# include <fstream> +# include <string> +# include "../system/FreestyleConfig.h" +# include "../system/ProgressBar.h" +# include "ViewMap.h" + +namespace ViewMapIO { + + static const unsigned ZERO = UINT_MAX; + + LIB_VIEW_MAP_EXPORT + int load(istream& in, ViewMap* vm, ProgressBar* pb = NULL); + + LIB_VIEW_MAP_EXPORT + int save(ostream& out, ViewMap* vm, ProgressBar* pb = NULL); + + namespace Options { + + static const unsigned char FLOAT_VECTORS = 1; + static const unsigned char NO_OCCLUDERS = 2; + + LIB_VIEW_MAP_EXPORT + void setFlags(const unsigned char flags); + + LIB_VIEW_MAP_EXPORT + void addFlags(const unsigned char flags); + + LIB_VIEW_MAP_EXPORT + void rmFlags(const unsigned char flags); + + LIB_VIEW_MAP_EXPORT + unsigned char getFlags(); + + LIB_VIEW_MAP_EXPORT + void setModelsPath(const string& path); + + LIB_VIEW_MAP_EXPORT + string getModelsPath(); + + }; // End of namepace Options + +# ifdef IRIX + + namespace Internal { + + template <unsigned S> + ostream& write(ostream& out, const char* str) { + out.put(str[S - 1]); + return write<S - 1>(out, str); + } + + template<> + ostream& write<1>(ostream& out, const char* str) { + return out.put(str[0]); + } + + template<> + ostream& write<0>(ostream& out, const char*) { + return out; + } + + template <unsigned S> + istream& read(istream& in, char* str) { + in.get(str[S - 1]); + return read<S - 1>(in, str); + } + + template<> + istream& read<1>(istream& in, char* str) { + return in.get(str[0]); + } + + template<> + istream& read<0>(istream& in, char*) { + return in; + } + + } // End of namespace Internal + +# endif // IRIX + +} // End of namespace ViewMapIO + +#endif // VIEWMAPIO_H diff --git a/source/blender/freestyle/intern/view_map/ViewMapIterators.h b/source/blender/freestyle/intern/view_map/ViewMapIterators.h new file mode 100755 index 00000000000..789aec0d5c3 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewMapIterators.h @@ -0,0 +1,549 @@ +// +// Filename : ViewMapIterators.h +// Author(s) : Stephane Grabli +// Purpose : Iterators used to iterate over the various elements +// of the ViewMap +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef VIEWMAPITERATORS_H +# define VIEWMAPITERATORS_H + +#include "ViewMap.h" +#include "../system/Iterator.h" //soc + + + /**********************************/ + /* */ + /* */ + /* ViewMap */ + /* */ + /* */ + /**********************************/ + + /**********************************/ + /* */ + /* */ + /* ViewVertex */ + /* */ + /* */ + /**********************************/ + +namespace ViewVertexInternal{ + + /*! Class representing an iterator over oriented ViewEdges + * around a ViewVertex. This iterator allows a CCW iteration + * (in the image plane). + * An instance of an orientedViewEdgeIterator can only + * be obtained from a ViewVertex by calling edgesBegin() or edgesEnd(). + */ + class orientedViewEdgeIterator : public Iterator + { + public: + friend class ViewVertex; + friend class TVertex; + friend class NonTVertex; + friend class ViewEdge; + + // FIXME + typedef ::TVertex::edge_pointers_container edge_pointers_container; + typedef ::NonTVertex::edges_container edges_container; + protected: + + Nature::VertexNature _Nature; // the nature of the underlying vertex + // T vertex attributes + edge_pointers_container::iterator _tbegin; + edge_pointers_container::iterator _tend; + edge_pointers_container::iterator _tvertex_iter; + + // Non TVertex attributes + edges_container::iterator _begin; + edges_container::iterator _end; + edges_container::iterator _nontvertex_iter; + + public: + /*! Default constructor */ + inline orientedViewEdgeIterator() {} + inline orientedViewEdgeIterator(Nature::VertexNature iNature) + {_Nature = iNature;} + /*! Copy constructor */ + orientedViewEdgeIterator(const orientedViewEdgeIterator& iBrother) + { + _Nature = iBrother._Nature; + if(_Nature & Nature::T_VERTEX) + { + _tbegin = iBrother._tbegin; + _tend = iBrother._tend; + _tvertex_iter = iBrother._tvertex_iter; + } + else + { + _begin = iBrother._begin; + _end = iBrother._end; + _nontvertex_iter = iBrother._nontvertex_iter; + } + } + virtual ~orientedViewEdgeIterator() {} + + public: + inline orientedViewEdgeIterator(edge_pointers_container::iterator begin, + edge_pointers_container::iterator end, + edge_pointers_container::iterator iter) + { + _Nature = Nature::T_VERTEX; + _tbegin = begin; + _tend = end; + _tvertex_iter = iter; + } + inline orientedViewEdgeIterator(edges_container::iterator begin, + edges_container::iterator end, + edges_container::iterator iter) + { + _Nature = Nature::NON_T_VERTEX; + _begin = begin; + _end = end; + _nontvertex_iter = iter; + } + + public: + + + /*! Tells whether the ViewEdge pointed + * by this iterator is the first one of the + * iteration list or not. + */ + virtual bool isBegin() const + { + if(_Nature & Nature::T_VERTEX) + return (_tvertex_iter == _tbegin); + else + return (_nontvertex_iter == _begin); + } + /*! Tells whether the ViewEdge pointed + * by this iterator is after the last one of the + * iteration list or not. + */ + virtual bool isEnd() const + { + if(_Nature & Nature::T_VERTEX) + return (_tvertex_iter == _tend); + else + return (_nontvertex_iter == _end); + } + + // operators + /*! Increments.In the scripting language, call + * "increment()". + */ + virtual orientedViewEdgeIterator& operator++() // operator corresponding to ++i + { + increment(); + return *this; + } + /*! Increments.In the scripting language, call + * "increment()". + */ + virtual orientedViewEdgeIterator operator++(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + orientedViewEdgeIterator tmp = *this; // C'est pour cela qu'on stocke la valeur + increment(); // dans un temporaire. + return tmp; + } + + // comparibility + /*! operator != */ + virtual bool operator!=(const orientedViewEdgeIterator& b) const + { + if(_Nature & Nature::T_VERTEX) + return (_tvertex_iter != b._tvertex_iter); + else + return (_nontvertex_iter != b._nontvertex_iter); + } + + /*! operator == */ + virtual bool operator==(const orientedViewEdgeIterator& b) const + {return !(*this != b);} + + // dereferencing + /*! Returns a reference to the pointed orientedViewEdge. + * In the scripting language, you must call + * "getObject()"instead. + */ + virtual ::ViewVertex::directedViewEdge& operator*() const + { + if(_Nature & Nature::T_VERTEX) + //return _tvertex_iter; + return **_tvertex_iter; + else + return (*_nontvertex_iter); + } + /*! Returns a pointer to the pointed orientedViewEdge. + * Can't be called in the scripting language. + */ + virtual ::ViewVertex::directedViewEdge* operator->() const { return &(operator*());} + + public: + /*! increments.*/ + virtual inline int increment() + { + if(_Nature & Nature::T_VERTEX) + { + ::ViewVertex::directedViewEdge tmp = (**_tvertex_iter); + ++_tvertex_iter; + if(_tvertex_iter != _tend){ + // FIXME : pquoi deja ? + ::ViewVertex::directedViewEdge tmp2 = (**_tvertex_iter); + if(tmp2.first == tmp.first) + ++_tvertex_iter; + } + } + else + ++_nontvertex_iter; + return 0; + } + }; + + } + /**********************************/ + /* */ + /* */ + /* ViewEdge */ + /* */ + /* */ + /**********************************/ + +namespace ViewEdgeInternal { +// +// SVertexIterator +// +///////////////////////////////////////////////// + + class SVertexIterator : public Interface0DIteratorNested + { + public: + + SVertexIterator() { + _vertex = NULL; + _begin = NULL; + _previous_edge = NULL; + _next_edge = NULL; + _t = 0; + } + + SVertexIterator(const SVertexIterator& vi) { + _vertex = vi._vertex; + _begin = vi._begin; + _previous_edge = vi._previous_edge; + _next_edge = vi._next_edge; + _t = vi._t; + } + + SVertexIterator(SVertex* v, SVertex* begin, FEdge* prev, FEdge* next, float t) { + _vertex = v; + _begin = begin; + _previous_edge = prev; + _next_edge = next; + _t = t; + } + + SVertexIterator& operator=(const SVertexIterator& vi) { + _vertex = vi._vertex; + _begin = vi._begin; + _previous_edge = vi._previous_edge; + _next_edge = vi._next_edge; + _t = vi._t; + return *this; + } + + virtual ~SVertexIterator() {} + + virtual string getExactTypeName() const { + return "SVertexIterator"; + } + + virtual SVertex& operator*() { + return *_vertex; + } + + virtual SVertex* operator->() { + return &(operator*()); + } + + virtual SVertexIterator& operator++() { + increment(); + return *this; + } + + virtual SVertexIterator operator++(int) { + SVertexIterator ret(*this); + increment(); + return ret; + } + + virtual SVertexIterator& operator--() { + decrement(); + return *this; + } + + virtual SVertexIterator operator--(int) { + SVertexIterator ret(*this); + decrement(); + return ret; + } + + virtual int increment(){ + if (!_next_edge) { + _vertex = 0; + return 0; + } + _t += (float)_next_edge->getLength2D(); + _vertex = _next_edge->vertexB(); + _previous_edge = _next_edge; + _next_edge = _next_edge->nextEdge(); + return 0; + + } + virtual int decrement(){ + if (!_previous_edge) { + _vertex = 0; + return 0; + } + if((!_next_edge) && (!_vertex)){ + _vertex = _previous_edge->vertexB(); + return 0; + } + _t -= (float)_previous_edge->getLength2D(); + _vertex = _previous_edge->vertexA(); + _next_edge = _previous_edge; + _previous_edge = _previous_edge->previousEdge(); + return 0; + } + + virtual bool isBegin() const { + return _vertex == _begin; + } + + virtual bool isEnd() const { + return (!_vertex) || (_vertex == _begin && _previous_edge); + } + + virtual float t() const { + return _t; + } + virtual float u() const { + return _t/(float)_next_edge->viewedge()->getLength2D(); + } + + virtual bool operator==(const Interface0DIteratorNested& it) const { + const SVertexIterator* it_exact = dynamic_cast<const SVertexIterator*>(&it); + if (!it_exact) + return false; + return (_vertex == it_exact->_vertex); + } + + virtual SVertexIterator* copy() const { + return new SVertexIterator(*this); + } + + private: + + SVertex* _vertex; + SVertex* _begin; + FEdge* _previous_edge; + FEdge* _next_edge; + float _t; // curvilinear abscissa + }; + + + +// +// ViewEdgeIterator (base class) +// +/////////////////////////////////////////////////////////// + + /*! Base class for iterators over ViewEdges of the ViewMap Graph. + * Basically the "increment()" operator of this class should + * be able to take the decision of "where" (on which ViewEdge) to go + * when pointing on a given ViewEdge. + * ::Caution::: the dereferencing operator returns a *pointer* to + * the pointed ViewEdge. + */ +class ViewEdgeIterator : public Iterator +{ +public: + + /*! Builds a ViewEdgeIterator from a starting ViewEdge and its orientation. + * \param begin + * The ViewEdge from where to start the iteration. + * \param orientation + * If true, we'll look for the next ViewEdge among the + * ViewEdges that surround the ending ViewVertex of begin. + * If false, we'll search over the ViewEdges surrounding + * the ending ViewVertex of begin. + */ + ViewEdgeIterator(ViewEdge* begin = 0, bool orientation = true) { + _orientation = orientation; + _edge = begin; + _begin = begin; + } + + /*! Copy constructor */ + ViewEdgeIterator(const ViewEdgeIterator& it) { + _orientation = it._orientation; + _edge = it._edge; + _begin = it._begin; + } + + virtual ~ViewEdgeIterator() {} + + /*! Returns the string "ViewEdgeIterator" */ + virtual string getExactTypeName() const { + return "ViewEdgeIterator"; + } + + /*! Returns the current pointed ViewEdge. */ + ViewEdge* getCurrentEdge() { + return _edge; + } + + /*! Sets the current pointed ViewEdge. */ + void setCurrentEdge(ViewEdge* edge) { + _edge = edge; + } + + /*! Returns the first ViewEdge used for the iteration. */ + ViewEdge* getBegin() { + return _begin; + } + + /*! Sets the first ViewEdge used for the iteration. */ + void setBegin(ViewEdge* begin) { + _begin = begin; + } + + /*! Gets the orientation of the pointed ViewEdge in the iteration. */ + bool getOrientation() const { + return _orientation; + } + + /*! Sets the orientation of the pointed ViewEdge in the iteration. */ + void setOrientation(bool orientation) { + _orientation = orientation; + } + + /*! Changes the current orientation. */ + void changeOrientation() { + _orientation = !_orientation; + } + + /*! Returns a *pointer* to the pointed ViewEdge. */ + virtual ViewEdge* operator*() { + return _edge; + } + + virtual ViewEdge* operator->() { + return operator*(); + } + + /*! Increments. In the scripting language, call + * "increment()". + */ + virtual ViewEdgeIterator& operator++() { + increment(); + return *this; + } + + /*! Increments. In the scripting language, call + * "increment()". + */ + virtual ViewEdgeIterator operator++(int) { + ViewEdgeIterator tmp(*this); + increment(); + return tmp; + } + + /*! increments. */ + virtual int increment() { + cerr << "Warning: method increment() not implemented" << endl; + return 0; + } + + /*! Decrements. In the scripting language, call + * "decrement()". + */ + virtual ViewEdgeIterator& operator--() { + decrement(); + return *this; + } + + /*! Decrements. In the scripting language, call + * "decrement()". + */ + virtual ViewEdgeIterator operator--(int) { + ViewEdgeIterator tmp(*this); + decrement(); + return tmp; + } + + /*! decrements. */ + virtual int decrement(){ + cerr << "Warning: method decrement() not implemented" << endl; + return 0; + } + + /*! Returns true if the pointed ViewEdge is the + * first one used for the iteration. + */ + virtual bool isBegin() const { + return _edge == _begin; + } + + /*! Returns true if the pointed ViewEdge* equals 0. + */ + virtual bool isEnd() const { + return !_edge; + } + + /*! operator == */ + virtual bool operator==(ViewEdgeIterator& it) const { + return _edge == it._edge; + } + + /*! operator != */ + virtual bool operator!=(ViewEdgeIterator& it) const { + return !(*this == it); + } + +protected: + + bool _orientation; + ViewEdge* _edge; + ViewEdge* _begin; +}; + +} // end of namespace ViewEdgeInternal + +#endif // VIEWMAPITERATORS_H + diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp b/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp new file mode 100755 index 00000000000..6041f527d17 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.cpp @@ -0,0 +1,36 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "ViewMapTesselator.h" + +NodeGroup* ViewMapTesselator::Tesselate(ViewMap *iViewMap) +{ + if(0 == iViewMap->ViewEdges().size()) + return NULL; + + const vector<ViewEdge*>& viewedges = iViewMap->ViewEdges(); + return Tesselate(viewedges.begin(), viewedges.end()); +} + +NodeGroup* ViewMapTesselator::Tesselate(WShape *) +{ + return NULL; +} diff --git a/source/blender/freestyle/intern/view_map/ViewMapTesselator.h b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h new file mode 100755 index 00000000000..630bfa561f2 --- /dev/null +++ b/source/blender/freestyle/intern/view_map/ViewMapTesselator.h @@ -0,0 +1,196 @@ +// +// Filename : ViewMapTesselator.h +// Author(s) : Stephane Grabli +// Purpose : Class to build a Node Tree designed to be displayed +// from a Silhouette View Map structure. +// Date of creation : 26/03/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef VIEWMAPTESSELATOR_H +# define VIEWMAPTESSELATOR_H + +# include "../scene_graph/NodeShape.h" +# include "../winged_edge/WEdge.h" +# include "Silhouette.h" +# include "ViewMap.h" +# include "../scene_graph/NodeGroup.h" +# include "../scene_graph/LineRep.h" +# include "../scene_graph/OrientedLineRep.h" +# include "../scene_graph/VertexRep.h" + +class NodeShape; +class NodeGroup; +class SShape; +class WShape; + +class LIB_VIEW_MAP_EXPORT ViewMapTesselator +{ +public: + + inline ViewMapTesselator() {_nature = Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE;_FrsMaterial.setDiffuse(0,0,0,1);_overloadFrsMaterial=false;} + virtual ~ViewMapTesselator() {} + + /*! Builds a set of lines rep contained under a + * a NodeShape, itself contained under a NodeGroup from a ViewMap + */ + NodeGroup* Tesselate(ViewMap* iViewMap) ; + + /*! Builds a set of lines rep contained under a + * a NodeShape, itself contained under a NodeGroup from a + * set of view edges + */ + template<class ViewEdgesIterator> + NodeGroup* Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end) ; + + /*! Builds a set of lines rep contained among a + * a NodeShape, from a WShape + */ + NodeGroup* Tesselate(WShape* iWShape); + + + inline void setNature(Nature::EdgeNature iNature) {_nature = iNature;} + inline void setFrsMaterial(const FrsMaterial& iMaterial) {_FrsMaterial=iMaterial;_overloadFrsMaterial=true;} + inline Nature::EdgeNature nature() {return _nature;} + inline const FrsMaterial& frs_material() const {return _FrsMaterial;} + +protected: + virtual void AddVertexToLine(LineRep *iLine, SVertex *v) = 0; + +private: + Nature::EdgeNature _nature; + FrsMaterial _FrsMaterial; + bool _overloadFrsMaterial; +}; + +/*! Class to tesselate the 2D projected silhouette */ +class ViewMapTesselator2D : public ViewMapTesselator +{ +public: + inline ViewMapTesselator2D() : ViewMapTesselator() {} + virtual ~ViewMapTesselator2D() {} + +protected: + virtual void AddVertexToLine(LineRep *iLine, SVertex *v) + { + iLine->AddVertex(v->point2D()); + } +}; + +/*! Class to tesselate the 3D silhouette */ +class ViewMapTesselator3D : public ViewMapTesselator +{ +public: + inline ViewMapTesselator3D() : ViewMapTesselator() {} + virtual ~ViewMapTesselator3D() {} + +protected: + virtual void AddVertexToLine(LineRep *iLine, SVertex *v) + { + iLine->AddVertex(v->point3D()); + } +}; + +// +// Implementation +// +/////////////////////////////////////////////// + +template<class ViewEdgesIterator> +NodeGroup * ViewMapTesselator::Tesselate(ViewEdgesIterator begin, ViewEdgesIterator end) +{ + NodeGroup *group = new NodeGroup; + NodeShape *tshape = new NodeShape; + group->AddChild(tshape); + //tshape->frs_material().setDiffuse(0.f, 0.f, 0.f, 1.f); + tshape->setFrsMaterial(_FrsMaterial); + + LineRep* line; + + + FEdge *firstEdge; + FEdge *nextFEdge, *currentEdge; + + int id=0; + // for(vector<ViewEdge*>::const_iterator c=viewedges.begin(),cend=viewedges.end(); + // c!=cend; + // c++) + for(ViewEdgesIterator c=begin, cend=end; + c!=cend; + c++) + { + // if((*c)->qi() > 0){ + // continue; + // } + // if(!((*c)->nature() & (_nature))) + // continue; + // + firstEdge = (*c)->fedgeA(); + + // if(firstEdge->invisibility() > 0) + // continue; + + line = new OrientedLineRep(); + if(_overloadFrsMaterial) + line->setFrsMaterial(_FrsMaterial); + + // there might be chains containing a single element + if(0 == (firstEdge)->nextEdge()) + { + line->setStyle(LineRep::LINES); + // line->AddVertex((*c)->vertexA()->point3D()); + // line->AddVertex((*c)->vertexB()->point3D()); + AddVertexToLine(line, firstEdge->vertexA()); + AddVertexToLine(line, firstEdge->vertexB()); + } + else + { + line->setStyle(LineRep::LINE_STRIP); + + //firstEdge = (*c); + nextFEdge = firstEdge; + currentEdge = firstEdge; + do + { + //line->AddVertex(nextFEdge->vertexA()->point3D()); + AddVertexToLine(line, nextFEdge->vertexA()); + currentEdge = nextFEdge; + nextFEdge = nextFEdge->nextEdge(); + }while((nextFEdge != NULL) && (nextFEdge != firstEdge)); + // Add the last vertex + //line->AddVertex(currentEdge->vertexB()->point3D()); + AddVertexToLine(line, currentEdge->vertexB()); + + } + + line->setId((*c)->getId().getFirst()); + line->ComputeBBox(); + tshape->AddRep(line); + id++; + } + + return group; +} + +#endif // VIEWMAPTESSELATOR_H diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp new file mode 100755 index 00000000000..2997d9b6922 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp @@ -0,0 +1,648 @@ +/* GTS - Library for the manipulation of triangulated surfaces + * Copyright (C) 1999-2002 Ray Jones, Stéphane Popinet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <cstdlib> // for malloc and free +#include "Curvature.h" +#include <math.h> +#include "WEdge.h" +#include "../system/FreestyleConfig.h" +#include "../geometry/normal_cycle.h" +#include <set> +#include <stack> + +static bool angle_obtuse (WVertex * v, WFace * f) +{ + WOEdge * e; + f->getOppositeEdge (v, e); + + Vec3r vec1(e->GetaVertex()->GetVertex()-v->GetVertex()); + Vec3r vec2(e->GetbVertex()->GetVertex()-v->GetVertex()); + return ((vec1 * vec2) < 0); +} + +// FIXME +// WVvertex is useless but kept for history reasons +static bool triangle_obtuse (WVertex*, WFace * f) +{ + bool b=false; + for (int i=0; i<3; i++) + b = b || + ((f->getEdgeList()[i]->getVec3r() * f->getEdgeList()[(i+1)%3]->getVec3r()) < 0); + return b; +} + +static real cotan (WVertex * vo, WVertex * v1, WVertex * v2) +{ + /* cf. Appendix B of [Meyer et al 2002] */ + real udotv, denom; + + Vec3r u(v1->GetVertex()- vo->GetVertex()); + Vec3r v(v2->GetVertex()- vo->GetVertex()); + + udotv = u * v; + denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv); + + /* denom can be zero if u==v. Returning 0 is acceptable, based on + * the callers of this function below. */ + if (denom == 0.0) return (0.0); + + return (udotv / denom); +} + +static real angle_from_cotan (WVertex * vo, WVertex * v1, WVertex * v2) +{ + /* cf. Appendix B and the caption of Table 1 from [Meyer et al 2002] */ + real udotv, denom; + + Vec3r u (v1->GetVertex()-vo->GetVertex()); + Vec3r v(v2->GetVertex()-vo->GetVertex()); + + udotv = u * v; + denom = sqrt(u.squareNorm() * v.squareNorm() - udotv * udotv); + + /* Note: I assume this is what they mean by using atan2 (). -Ray Jones */ + + /* tan = denom/udotv = y/x (see man page for atan2) */ + return (fabs (atan2 (denom, udotv))); +} + +/** + * gts_vertex_mean_curvature_normal: + * @v: a #WVertex. + * @s: a #GtsSurface. + * @Kh: the Mean Curvature Normal at @v. + * + * Computes the Discrete Mean Curvature Normal approximation at @v. + * The mean curvature at @v is half the magnitude of the vector @Kh. + * + * Note: the normal computed is not unit length, and may point either + * into or out of the surface, depending on the curvature at @v. It + * is the responsibility of the caller of the function to use the mean + * curvature normal appropriately. + * + * This approximation is from the paper: + * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds + * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr + * VisMath '02, Berlin (Germany) + * http://www-grail.usc.edu/pubs.html + * + * Returns: %TRUE if the operator could be evaluated, %FALSE if the + * evaluation failed for some reason (@v is boundary or is the + * endpoint of a non-manifold edge.) + */ +bool gts_vertex_mean_curvature_normal (WVertex * v, Vec3r &Kh) +{ + real area = 0.0; + + if (!v) return false; + + /* this operator is not defined for boundary edges */ + if (v->isBoundary()) return false; + + WVertex::incoming_edge_iterator itE; + + for (itE=v->incoming_edges_begin(); + itE!=v->incoming_edges_end(); itE++) + area+=(*itE)->GetaFace()->getArea(); + + Kh=Vec3r(0.0, 0.0, 0.0); + + for (itE=v->incoming_edges_begin(); + itE!=v->incoming_edges_end(); itE++) + { + WOEdge * e = (*itE)->getPrevOnFace(); + //if ((e->GetaVertex()==v) || (e->GetbVertex()==v)) cerr<< "BUG "; + + WVertex * v1 = e->GetaVertex(); + WVertex * v2 = e->GetbVertex(); + real temp; + + temp = cotan (v1, v, v2); + Kh = Vec3r(Kh+temp*(v2->GetVertex()-v->GetVertex())); + + temp = cotan (v2, v, v1); + Kh = Vec3r(Kh+temp*(v1->GetVertex()-v->GetVertex())); + } + if (area > 0.0) + { + Kh[0] /= 2*area; + Kh[1] /= 2*area; + Kh[2] /= 2*area; + } + else return false; + + return true; +} + +/** + * gts_vertex_gaussian_curvature: + * @v: a #WVertex. + * @s: a #GtsSurface. + * @Kg: the Discrete Gaussian Curvature approximation at @v. + * + * Computes the Discrete Gaussian Curvature approximation at @v. + * + * This approximation is from the paper: + * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds + * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr + * VisMath '02, Berlin (Germany) + * http://www-grail.usc.edu/pubs.html + * + * Returns: %TRUE if the operator could be evaluated, %FALSE if the + * evaluation failed for some reason (@v is boundary or is the + * endpoint of a non-manifold edge.) + */ +bool gts_vertex_gaussian_curvature (WVertex * v, real * Kg) +{ + real area = 0.0; + real angle_sum = 0.0; + + if (!v) return false; + if (!Kg) return false; + + /* this operator is not defined for boundary edges */ + if (v->isBoundary()) {*Kg=0.0 ;return false;} + + WVertex::incoming_edge_iterator itE; + for (itE=v->incoming_edges_begin(); + itE!=v->incoming_edges_end(); itE++) + area+=(*itE)->GetaFace()->getArea(); + + for (itE=v->incoming_edges_begin(); + itE!=v->incoming_edges_end(); itE++) + { + WOEdge * e = (*itE)->getPrevOnFace(); + WVertex * v1 = e->GetaVertex(); + WVertex * v2 = e->GetbVertex(); + angle_sum += angle_from_cotan (v, v1, v2); + } + + *Kg = (2.0*M_PI - angle_sum)/area; + + return true; +} + +/** + * gts_vertex_principal_curvatures: + * @Kh: mean curvature. + * @Kg: Gaussian curvature. + * @K1: first principal curvature. + * @K2: second principal curvature. + * + * Computes the principal curvatures at a point given the mean and + * Gaussian curvatures at that point. + * + * The mean curvature can be computed as one-half the magnitude of the + * vector computed by gts_vertex_mean_curvature_normal(). + * + * The Gaussian curvature can be computed with + * gts_vertex_gaussian_curvature(). + */ +void gts_vertex_principal_curvatures (real Kh, real Kg, + real * K1, real * K2) +{ + real temp = Kh*Kh - Kg; + + if (!K1) return; + if (!K1) return; + + if (temp < 0.0) temp = 0.0; + temp = sqrt (temp); + *K1 = Kh + temp; + *K2 = Kh - temp; +} + +/* from Maple */ +static void linsolve (real m11, real m12, real b1, + real m21, real m22, real b2, + real * x1, real * x2) +{ + real temp; + + temp = 1.0 / (m21*m12 - m11*m22); + *x1 = (m12*b2 - m22*b1)*temp; + *x2 = (m11*b2 - m21*b1)*temp; +} + +/* from Maple - largest eigenvector of [a b; b c] */ +static void eigenvector (real a, real b, real c, + Vec3r e) +{ + if (b == 0.0) { + e[0] = 0.0; + } else { + e[0] = -(c - a - sqrt (c*c - 2*a*c + a*a + 4*b*b))/(2*b); + } + e[1] = 1.0; + e[2] = 0.0; +} + +/** + * gts_vertex_principal_directions: + * @v: a #WVertex. + * @s: a #GtsSurface. + * @Kh: mean curvature normal (a #Vec3r). + * @Kg: Gaussian curvature (a real). + * @e1: first principal curvature direction (direction of largest curvature). + * @e2: second principal curvature direction. + * + * Computes the principal curvature directions at a point given @Kh + * and @Kg, the mean curvature normal and Gaussian curvatures at that + * point, computed with gts_vertex_mean_curvature_normal() and + * gts_vertex_gaussian_curvature(), respectively. + * + * Note that this computation is very approximate and tends to be + * unstable. Smoothing of the surface or the principal directions may + * be necessary to achieve reasonable results. + */ +void gts_vertex_principal_directions (WVertex * v, + Vec3r Kh, real Kg, + Vec3r &e1, Vec3r &e2) +{ + Vec3r N; + real normKh; + + Vec3r basis1, basis2, d, eig; + real ve2, vdotN; + real aterm_da, bterm_da, cterm_da, const_da; + real aterm_db, bterm_db, cterm_db, const_db; + real a, b, c; + real K1, K2; + real *weights, *kappas, *d1s, *d2s; + int edge_count; + real err_e1, err_e2; + int e; + WVertex::incoming_edge_iterator itE; + + /* compute unit normal */ + normKh = Kh.norm(); + + if (normKh > 0.0) { + Kh.normalize(); + } else { + /* This vertex is a point of zero mean curvature (flat or saddle + * point). Compute a normal by averaging the adjacent triangles + */ + N[0] = N[1] = N[2] = 0.0; + + for (itE=v->incoming_edges_begin(); + itE!=v->incoming_edges_end(); itE++) + N=Vec3r(N+(*itE)->GetaFace()->GetNormal()); + real normN = N.norm(); + if (normN <= 0.0) + return; + N.normalize(); + } + + + /* construct a basis from N: */ + /* set basis1 to any component not the largest of N */ + basis1[0] = basis1[1] = basis1[2] = 0.0; + if (fabs (N[0]) > fabs (N[1])) + basis1[1] = 1.0; + else + basis1[0] = 1.0; + + /* make basis2 orthogonal to N */ + basis2 = (N ^ basis1); + basis2.normalize(); + + /* make basis1 orthogonal to N and basis2 */ + basis1 = (N ^ basis2); + basis1.normalize(); + + aterm_da = bterm_da = cterm_da = const_da = 0.0; + aterm_db = bterm_db = cterm_db = const_db = 0.0; + int nb_edges=v->GetEdges().size(); + + weights = (real *) malloc (sizeof (real)*nb_edges); + kappas = (real*) malloc (sizeof (real)*nb_edges); + d1s = (real*) malloc (sizeof (real)*nb_edges); + d2s = (real*) malloc (sizeof (real)*nb_edges); + edge_count = 0; + + for (itE=v->incoming_edges_begin(); + itE!=v->incoming_edges_end(); itE++) + { + WOEdge * e; + WFace * f1, * f2; + real weight, kappa, d1, d2; + Vec3r vec_edge; + if (! *itE) continue; + e = *itE; + + /* since this vertex passed the tests in + * gts_vertex_mean_curvature_normal(), this should be true. */ + //g_assert (gts_edge_face_number (e, s) == 2); + + /* identify the two triangles bordering e in s */ + f1=e->GetaFace(); + f2=e->GetbFace(); + + /* We are solving for the values of the curvature tensor + * B = [ a b ; b c ]. + * The computations here are from section 5 of [Meyer et al 2002]. + * + * The first step is to calculate the linear equations governing + * the values of (a,b,c). These can be computed by setting the + * derivatives of the error E to zero (section 5.3). + * + * Since a + c = norm(Kh), we only compute the linear equations + * for dE/da and dE/db. (NB: [Meyer et al 2002] has the + * equation a + b = norm(Kh), but I'm almost positive this is + * incorrect.) + * + * Note that the w_ij (defined in section 5.2) are all scaled by + * (1/8*A_mixed). We drop this uniform scale factor because the + * solution of the linear equations doesn't rely on it. + * + * The terms of the linear equations are xterm_dy with x in + * {a,b,c} and y in {a,b}. There are also const_dy terms that are + * the constant factors in the equations. + */ + + /* find the vector from v along edge e */ + vec_edge=Vec3r(-1*e->getVec3r()); + + ve2 = vec_edge.squareNorm(); + vdotN = vec_edge * N; + + /* section 5.2 - There is a typo in the computation of kappa. The + * edges should be x_j-x_i. + */ + kappa = 2.0 * vdotN / ve2; + + /* section 5.2 */ + + /* I don't like performing a minimization where some of the + * weights can be negative (as can be the case if f1 or f2 are + * obtuse). To ensure all-positive weights, we check for + * obtuseness. */ + weight = 0.0; + if (! triangle_obtuse(v, f1)) { + weight += ve2 * + cotan (f1->GetNextOEdge(e->twin())->GetbVertex(), + e->GetaVertex(), e->GetbVertex()) / 8.0; + } else { + if (angle_obtuse (v, f1)) { + weight += ve2 * f1->getArea() / 4.0; + } else { + weight += ve2 * f1->getArea() / 8.0; + } + } + + if (! triangle_obtuse(v, f2)) { + weight += ve2 * + cotan (f2->GetNextOEdge(e)->GetbVertex(), + e->GetaVertex(), e->GetbVertex()) / 8.0; + } else { + if (angle_obtuse (v, f2)) { + weight += ve2 * f1->getArea() / 4.0; + } else { + weight += ve2 * f1->getArea() / 8.0; + } + } + + /* projection of edge perpendicular to N (section 5.3) */ + d[0] = vec_edge[0] - vdotN * N[0]; + d[1] = vec_edge[1] - vdotN * N[1]; + d[2] = vec_edge[2] - vdotN * N[2]; + d.normalize(); + + /* not explicit in the paper, but necessary. Move d to 2D basis. */ + d1 = d * basis1; + d2 = d * basis2; + + /* store off the curvature, direction of edge, and weights for later use */ + weights[edge_count] = weight; + kappas[edge_count] = kappa; + d1s[edge_count] = d1; + d2s[edge_count] = d2; + edge_count++; + + /* Finally, update the linear equations */ + aterm_da += weight * d1 * d1 * d1 * d1; + bterm_da += weight * d1 * d1 * 2 * d1 * d2; + cterm_da += weight * d1 * d1 * d2 * d2; + const_da += weight * d1 * d1 * (- kappa); + + aterm_db += weight * d1 * d2 * d1 * d1; + bterm_db += weight * d1 * d2 * 2 * d1 * d2; + cterm_db += weight * d1 * d2 * d2 * d2; + const_db += weight * d1 * d2 * (- kappa); + + } + + /* now use the identity (Section 5.3) a + c = |Kh| = 2 * kappa_h */ + aterm_da -= cterm_da; + const_da += cterm_da * normKh; + + aterm_db -= cterm_db; + const_db += cterm_db * normKh; + + /* check for solvability of the linear system */ + if (((aterm_da * bterm_db - aterm_db * bterm_da) != 0.0) && + ((const_da != 0.0) || (const_db != 0.0))) { + linsolve (aterm_da, bterm_da, -const_da, + aterm_db, bterm_db, -const_db, + &a, &b); + + c = normKh - a; + + eigenvector (a, b, c, eig); + } else { + /* region of v is planar */ + eig[0] = 1.0; + eig[1] = 0.0; + } + + /* Although the eigenvectors of B are good estimates of the + * principal directions, it seems that which one is attached to + * which curvature direction is a bit arbitrary. This may be a bug + * in my implementation, or just a side-effect of the inaccuracy of + * B due to the discrete nature of the sampling. + * + * To overcome this behavior, we'll evaluate which assignment best + * matches the given eigenvectors by comparing the curvature + * estimates computed above and the curvatures calculated from the + * discrete differential operators. */ + + gts_vertex_principal_curvatures (0.5 * normKh, Kg, &K1, &K2); + + err_e1 = err_e2 = 0.0; + /* loop through the values previously saved */ + for (e = 0; e < edge_count; e++) { + real weight, kappa, d1, d2; + real temp1, temp2; + real delta; + + weight = weights[e]; + kappa = kappas[e]; + d1 = d1s[e]; + d2 = d2s[e]; + + temp1 = fabs (eig[0] * d1 + eig[1] * d2); + temp1 = temp1 * temp1; + temp2 = fabs (eig[1] * d1 - eig[0] * d2); + temp2 = temp2 * temp2; + + /* err_e1 is for K1 associated with e1 */ + delta = K1 * temp1 + K2 * temp2 - kappa; + err_e1 += weight * delta * delta; + + /* err_e2 is for K1 associated with e2 */ + delta = K2 * temp1 + K1 * temp2 - kappa; + err_e2 += weight * delta * delta; + } + free (weights); + free (kappas); + free (d1s); + free (d2s); + + /* rotate eig by a right angle if that would decrease the error */ + if (err_e2 < err_e1) { + real temp = eig[0]; + + eig[0] = eig[1]; + eig[1] = -temp; + } + + e1[0] = eig[0] * basis1[0] + eig[1] * basis2[0]; + e1[1] = eig[0] * basis1[1] + eig[1] * basis2[1]; + e1[2] = eig[0] * basis1[2] + eig[1] * basis2[2]; + e1.normalize(); + + /* make N,e1,e2 a right handed coordinate sytem */ + e2 = N ^ e1; + e2.normalize(); +} + +namespace OGF { + static real angle(WOEdge* h) { + Vec3r e(h->GetbVertex()->GetVertex()-h->GetaVertex()->GetVertex()) ; + Vec3r n1 = h->GetbFace()->GetNormal(); + Vec3r n2 = h->GetaFace()->GetNormal(); + real sine = (n1 ^ n2) * e / e.norm() ; + if(sine >= 1.0) { + return M_PI / 2.0 ; + } + if(sine <= -1.0) { + return -M_PI / 2.0 ; + } + return ::asin(sine) ; + } + + // precondition1: P is inside the sphere + // precondition2: P,V points to the outside of + // the sphere (i.e. OP.V > 0) + static bool sphere_clip_vector( + const Vec3r& O, real r, + const Vec3r& P, Vec3r& V + ) { + + Vec3r W = P - O ; + real a = V.squareNorm() ; + real b = 2.0 * V * W ; + real c = W.squareNorm() - r*r ; + real delta = b*b - 4*a*c ; + if(delta < 0) { + // Should not happen, but happens sometimes (numerical precision) + return true ; + } + real t = - b + ::sqrt(delta) / (2.0 * a) ; + if(t < 0.0) { + // Should not happen, but happens sometimes (numerical precision) + return true ; + } + if(t >= 1.0) { + // Inside the sphere + return false ; + } + + V[0] = (t * V.x()) ; + V[1] = (t * V.y()) ; + V[2] = (t * V.z()) ; + + return true ; + } + + // TODO: check optimizations: + // use marking ? (measure *timings* ...) + void compute_curvature_tensor( + WVertex* start, real radius, NormalCycle& nc + ) { + // in case we have a non-manifold vertex, skip it... + if(start->isBoundary()) + return; + + std::set<WVertex*> vertices ; + const Vec3r& O = start->GetVertex() ; + std::stack<WVertex*> S ; + S.push(start) ; + vertices.insert(start) ; + while(!S.empty()) { + WVertex* v = S.top() ; + S.pop() ; + if(v->isBoundary()) + continue; + const Vec3r& P = v->GetVertex() ; + WVertex::incoming_edge_iterator woeit = v->incoming_edges_begin(); + WVertex::incoming_edge_iterator woeitend = v->incoming_edges_end(); + for(;woeit!=woeitend; ++woeit){ + WOEdge *h = *woeit; + Vec3r V(h->GetaVertex()->GetVertex()-h->GetbVertex()->GetVertex()) ; + if((v == start) || V * (P - O) > 0.0) { + bool isect = sphere_clip_vector(O, radius, P, V) ; + if(h->GetOwner()->GetNumberOfOEdges() == 2) { + real beta = angle(h) ; + nc.accumulate_dihedral_angle(V, beta) ; + } + if(!isect) { + WVertex* w = h->GetaVertex() ; + if(vertices.find(w) == vertices.end()) { + vertices.insert(w) ; + S.push(w) ; + } + } + } + } + } + } + + + void compute_curvature_tensor_one_ring( + WVertex* start, NormalCycle& nc + ) { + // in case we have a non-manifold vertex, skip it... + if(start->isBoundary()) + return; + + WVertex::incoming_edge_iterator woeit = start->incoming_edges_begin(); + WVertex::incoming_edge_iterator woeitend = start->incoming_edges_end(); + for(;woeit!=woeitend; ++woeit){ + WOEdge *h = (*woeit)->twin(); + Vec3r hvec(h->GetbVertex()->GetVertex()-h->GetaVertex()->GetVertex()); + nc.accumulate_dihedral_angle(hvec, angle(h)) ; + WOEdge *hprev = h->getPrevOnFace(); + Vec3r hprevvec(hprev->GetbVertex()->GetVertex()-hprev->GetaVertex()->GetVertex()); + nc.accumulate_dihedral_angle(hprevvec, angle(hprev)) ; + } + } + +} diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.h b/source/blender/freestyle/intern/winged_edge/Curvature.h new file mode 100755 index 00000000000..214a32ca922 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/Curvature.h @@ -0,0 +1,156 @@ + +/* GTS - Library for the manipulation of triangulated surfaces + * Copyright (C) 1999 Stéphane Popinet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CURVATURE_H__ +#define __CURVATURE_H__ + +# include "../system/FreestyleConfig.h" +# include "../system/Precision.h" +# include "../geometry/Geom.h" +using namespace Geometry; + +class WVertex; + +class LIB_WINGED_EDGE_EXPORT CurvatureInfo +{ +public: + + CurvatureInfo() + { + K1 = 0.0; + K2 = 0.0; + e1 = Vec3r(0.0,0.0,0.0); + e2 = Vec3r(0.0,0.0,0.0); + Kr = 0.0; + dKr = 0.0; + er = Vec3r(0.0,0.0,0.0); + } + + CurvatureInfo(const CurvatureInfo& iBrother){ + K1 = iBrother.K1; + K2 = iBrother.K2; + e1 = iBrother.e1; + e2 = iBrother.e2; + Kr = iBrother.Kr; + dKr = iBrother.dKr; + er = iBrother.er; + } + + CurvatureInfo(const CurvatureInfo& ca, const CurvatureInfo& cb, real t) { + K1 = ca.K1 + t * (cb.K1 - ca.K1); + K2 = ca.K2 + t * (cb.K2 - ca.K2); + e1 = ca.e1 + t * (cb.e1 - ca.e1); + e2 = ca.e2 + t * (cb.e2 - ca.e2); + Kr = ca.Kr + t * (cb.Kr - ca.Kr); + dKr = ca.dKr + t * (cb.dKr - ca.dKr); + er = ca.er + t * (cb.er - ca.er); + } + + real K1; // maximum curvature + real K2; // minimum curvature + Vec3r e1; // maximum curvature direction + Vec3r e2; // minimum curvature direction + real Kr; // radial curvature + real dKr; // radial curvature + Vec3r er; // radial curvature direction +}; + +class Face_Curvature_Info{ +public: + Face_Curvature_Info() {} + ~Face_Curvature_Info(){ + for(vector<CurvatureInfo*>::iterator ci=vec_curvature_info.begin(), ciend=vec_curvature_info.end(); + ci!=ciend; + ++ci){ + delete (*ci); + } + vec_curvature_info.clear(); + } + vector<CurvatureInfo *> vec_curvature_info; +}; + +bool LIB_WINGED_EDGE_EXPORT gts_vertex_mean_curvature_normal (WVertex * v, + Vec3r &n); + +bool LIB_WINGED_EDGE_EXPORT gts_vertex_gaussian_curvature (WVertex * v, + real * Kg); + +void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_curvatures (real Kh, + real Kg, + real * K1, + real * K2); + +void LIB_WINGED_EDGE_EXPORT gts_vertex_principal_directions (WVertex * v, + Vec3r Kh, + real Kg, + Vec3r &e1, + Vec3r &e2); + +/* + * OGF/Graphite: Geometry and Graphics Programming Library + Utilities + * Copyright (C) 2000-2003 Bruno Levy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * If you modify this software, you should include a notice giving the + * name of the person performing the modification, the date of modification, + * and the reason for such modification. + * + * Contact: Bruno Levy + * + * levy@loria.fr + * + * ISA Project + * LORIA, INRIA Lorraine, + * Campus Scientifique, BP 239 + * 54506 VANDOEUVRE LES NANCY CEDEX + * FRANCE + * + * Note that the GNU General Public License does not permit incorporating + * the Software into proprietary programs. + */ + namespace OGF { + + class NormalCycle ; + + void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor( + WVertex* start, double radius, NormalCycle& nc + ) ; + + void LIB_WINGED_EDGE_EXPORT compute_curvature_tensor_one_ring( + WVertex* start, NormalCycle& nc + ) ; + } + + +#endif /* __CURVATURE_H__ */ + diff --git a/source/blender/freestyle/intern/winged_edge/Nature.h b/source/blender/freestyle/intern/winged_edge/Nature.h new file mode 100755 index 00000000000..1f165e677f5 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/Nature.h @@ -0,0 +1,75 @@ +// +// Filename : Nature.h +// Author(s) : Emmanuel Turquin +// Purpose : Different natures for both vertices and edges +// Date of creation : 01/07/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef NATURE_H +# define NATURE_H + +/*! \file Nature.h + * Definitions of Natures of the ViewMap's elements + */ + +/*! Namespace gathering the different possible + * natures of 0D and 1D elements of the ViewMap + */ +namespace Nature { + + typedef unsigned short VertexNature; + + /*! true for any 0D element */ + static const VertexNature POINT = 0; // 0 + /*! true for SVertex */ + static const VertexNature S_VERTEX = (1 << 0); // 1 + /*! true for ViewVertex */ + static const VertexNature VIEW_VERTEX = (1 << 1); // 2 + /*! true for NonTVertex */ + static const VertexNature NON_T_VERTEX = (1 << 2); // 4 + /*! true for TVertex */ + static const VertexNature T_VERTEX = (1 << 3); // 8 + /*! true for CUSP */ + static const VertexNature CUSP = (1 << 4); // 16 + + typedef unsigned short EdgeNature; + /*! true for non feature edges (always false for 1D elements of the ViewMap) */ + static const EdgeNature NO_FEATURE = 0; // 0 + /*! true for silhouettes */ + static const EdgeNature SILHOUETTE = (1 << 0); // 1 + /*! true for borders */ + static const EdgeNature BORDER = (1 << 1); // 2 + /*! true for creases */ + static const EdgeNature CREASE = (1 << 2); // 4 + /*! true for ridges */ + static const EdgeNature RIDGE = (1 << 3); // 8 + /*! true for valleys */ + static const EdgeNature VALLEY = (1 << 4); // 16 + /*! true for suggestive contours */ + static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32 + +} // end of namespace Nature + +#endif // NATURE_H diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.cpp b/source/blender/freestyle/intern/winged_edge/WEdge.cpp new file mode 100755 index 00000000000..95be5f55794 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WEdge.cpp @@ -0,0 +1,732 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include <iostream> +#include "WEdge.h" + +/*! Temporary structures */ +class vertexdata +{ +public: + WVertex *_copy; +}; + +class oedgedata +{ +public: + WOEdge *_copy; +}; + +class edgedata +{ +public: + WEdge *_copy; +}; + +class facedata +{ +public: + WFace *_copy; +}; + + + /**********************************/ + /* */ + /* */ + /* WVertex */ + /* */ + /* */ + /**********************************/ + +WVertex::WVertex(WVertex& iBrother) +{ + _Id = iBrother._Id; + _Vertex = iBrother._Vertex; + _EdgeList = iBrother._EdgeList; + + _Shape = iBrother._Shape; + _Smooth = iBrother._Smooth; + _Border = iBrother._Border; + userdata = NULL; + iBrother.userdata = new vertexdata; + ((vertexdata*)(iBrother.userdata))->_copy = this; +} + +WVertex* WVertex::duplicate() +{ + WVertex *clone = new WVertex(*this); + return clone; +} + + +WOEdge* WVertex::incoming_edge_iterator::operator*() + +{ + return _current; +} +void WVertex::incoming_edge_iterator::increment(){ + WOEdge *twin = _current->twin(); + if(!twin){ + // we reached a hole + _current = 0; + return; + } + WOEdge *next = twin->getPrevOnFace(); + if(next == _begin){ + next = 0; + } + _current = next; +} + +WFace* WVertex::face_iterator::operator*(){ + WOEdge * woedge = *_edge_it; + if(woedge == 0) + return 0; + return (woedge)->GetbFace(); +} + +//bool WVertex::isBoundary () const{ +// return _Border; +//} +bool WVertex::isBoundary () +{ + if(_Border == 1) + return true; + else if(_Border == 0) + return false; + + vector<WEdge *>::const_iterator it; + for(it=_EdgeList.begin(); it!=_EdgeList.end(); it++){ + if((*it)->GetNumberOfOEdges() == 1){ + _Border = 1; + return true; + } + } + //if (!(*it)->GetaOEdge()->GetaFace()) return true; + _Border = 0; + return false; +} + +void WVertex::AddEdge(WEdge *iEdge) { + _EdgeList.push_back(iEdge); +} + +WVertex::incoming_edge_iterator WVertex::incoming_edges_begin(){ + WOEdge *begin; + WEdge * wedge = _EdgeList.front(); + WOEdge* aOEdge = wedge->GetaOEdge(); + if(aOEdge->GetbVertex() == this) + begin = aOEdge; + else + begin = _EdgeList.front()->GetbOEdge(); + return incoming_edge_iterator(this, begin, begin); +} +WVertex::incoming_edge_iterator WVertex::incoming_edges_end(){ + WOEdge *begin; + WOEdge* aOEdge = _EdgeList.front()->GetaOEdge(); + if(aOEdge->GetbVertex() == this) + begin = aOEdge; + else + begin = _EdgeList.front()->GetbOEdge(); + return incoming_edge_iterator(this, begin, 0); +} +//WOEdge** WVertex::incoming_edge_iterator::operator->() +//{ +// WOEdge ** ppaOEdge = (*_iter)->GetaOEdge(); +// if(aOEdge->GetbVertex() == _vertex) +// return ppaOEdge; +// else +// { +// WOEdge *bOEdge = (*_iter)->GetbOEdge(); +// return &bOEdge; +// } +// +//} + /**********************************/ + /* */ + /* */ + /* WOEdge */ + /* */ + /* */ + /**********************************/ + +WOEdge::WOEdge(WOEdge& iBrother) +{ + _paVertex = iBrother.GetaVertex(); + _pbVertex = iBrother.GetbVertex(); + _paFace = iBrother.GetaFace(); + _pbFace = iBrother.GetbFace(); + _pOwner = iBrother.GetOwner(); + userdata = NULL; + iBrother.userdata = new oedgedata; + ((oedgedata*)(iBrother.userdata))->_copy = this; +} + +WOEdge * WOEdge::duplicate() +{ + WOEdge *clone = new WOEdge(*this); + return clone; +} + +Vec3r +WOEdge::getVec3r () +{ + return Vec3r(_pbVertex->GetVertex() - _paVertex->GetVertex()); +} + +WOEdge * WOEdge::twin () +{ + return GetOwner()->GetOtherOEdge(this); +} + +WOEdge * +WOEdge::getPrevOnFace() +{ + return _pbFace->GetPrevOEdge(this); +} + + /**********************************/ + /* */ + /* */ + /* WEdge */ + /* */ + /* */ + /**********************************/ + +WEdge::WEdge(WEdge& iBrother) +{ + _paOEdge = NULL; + _pbOEdge = NULL; + WOEdge *aoedge = iBrother.GetaOEdge(); + WOEdge *boedge = iBrother.GetbOEdge(); + userdata = NULL; + + if(NULL != aoedge) + //_paOEdge = new WOEdge(*aoedge); + _paOEdge = aoedge->duplicate(); + if(NULL != boedge) + //_pbOEdge = new WOEdge(*boedge); + _pbOEdge = boedge->duplicate(); + + _nOEdges = iBrother.GetNumberOfOEdges(); + _Id = iBrother.GetId(); + iBrother.userdata = new edgedata; + ((edgedata*)(iBrother.userdata))->_copy = this; +} + +WEdge * WEdge::duplicate() +{ + WEdge *clone = new WEdge(*this); + return clone; +} + + /**********************************/ + /* */ + /* */ + /* WFace */ + /* */ + /* */ + /**********************************/ + + +WFace::WFace(WFace& iBrother) +{ + _OEdgeList = iBrother.getEdgeList(); + _Normal = iBrother.GetNormal(); + _VerticesNormals = iBrother._VerticesNormals; + _VerticesTexCoords = iBrother._VerticesTexCoords; + _Id = iBrother.GetId(); + _FrsMaterialIndex = iBrother._FrsMaterialIndex; + userdata = NULL; + iBrother.userdata = new facedata; + ((facedata*)(iBrother.userdata))->_copy = this; +} + +WFace * WFace::duplicate() +{ + WFace * clone = new WFace(*this); + return clone; +} + +const FrsMaterial& WFace::frs_material() { + return getShape()->frs_material(_FrsMaterialIndex); +} + +WOEdge * WFace::MakeEdge(WVertex *v1, WVertex *v2) +{ + // First check whether the same oriented edge already exists + // or not: + vector<WEdge *>& v1Edges = v1->GetEdges(); + for(vector<WEdge*>::iterator it1=v1Edges.begin(), end=v1Edges.end(); + it1!=end; + it1++) + { + + WEdge *we=(*it1); + + WOEdge *woea = we->GetaOEdge(); + + if((woea->GetaVertex() == v1) && (woea->GetbVertex() == v2)) + //if((*it1)->GetbVertex() == v2) + { + // The oriented edge already exists + cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl; + // Adds the edge to the face + //AddEdge((*it1)->GetaOEdge()); + AddEdge(woea); + (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges()+1); + //sets these vertices as border: + v1->setBorder(true); + v2->setBorder(true); + //return (*it1)->GetaOEdge(); + return woea; + } + + WOEdge *woeb = we->GetbOEdge(); + if((woeb != 0) && (woeb->GetaVertex() == v1) && (woeb->GetbVertex() == v2)) + + //if((*it1)->GetbVertex() == v2) + + { + // The oriented edge already exists + cerr << "Warning: edge " << v1->GetId() << " - " << v2->GetId() << " appears twice, correcting" << endl; + // Adds the edge to the face + //AddEdge((*it1)->GetaOEdge()); + AddEdge(woeb); + (*it1)->setNumberOfOEdges((*it1)->GetNumberOfOEdges()+1); + //sets these vertices as border: + v1->setBorder(true); + v2->setBorder(true); + //return (*it1)->GetaOEdge(); + return woeb; + } + } + + // the oriented edge we're about to build + WOEdge *pOEdge = new WOEdge; + + WEdge * edge; // The edge containing the oriented edge. + + // checks whether this edge already exists or not + // If it exists, it points outward v2 + + bool exist = false; + WOEdge *pInvertEdge = NULL; // The inverted edge if it exists + vector<WEdge *>& v2Edges = v2->GetEdges(); + vector<WEdge *>::iterator it; + for(it=v2Edges.begin(); it!=v2Edges.end(); it++) + { + if((*it)->GetbVertex() == v1) + { + // The invert edge already exists + exist = true; + pInvertEdge = (*it)->GetaOEdge(); + break; + } + } + + //DEBUG: + + + if(true == exist) // The invert edge already exists + { + // Retrieves the corresponding edge + edge = pInvertEdge->GetOwner(); + + // Sets the a Face (retrieved from pInvertEdge + pOEdge->setaFace(pInvertEdge->GetbFace()); + + // Updates the invert edge: + pInvertEdge->setaFace(this); + } + else // The invert edge does not exist yet + { + // we must create a new edge + //edge = new WEdge; + edge = instanciateEdge(); + + // updates the a,b vertex edges list: + v1->AddEdge(edge); + v2->AddEdge(edge); + + } + + pOEdge->setOwner(edge); + // Add the vertices: + pOEdge->setaVertex(v1); + pOEdge->setbVertex(v2); + + // Debug: + if(v1->GetId() == v2->GetId()) + cerr << "Warning: edge " << this << " null with vertex " << v1->GetId() << endl; + + edge->AddOEdge(pOEdge); + //edge->setNumberOfOEdges(edge->GetNumberOfOEdges()+1); + + // Add this face (the b face) + pOEdge->setbFace(this); + + // Adds the edge to the face + AddEdge(pOEdge); + + return pOEdge; +} + + +bool +WFace::getOppositeEdge (const WVertex *v, WOEdge* &e) +{ + if (_OEdgeList.size()!=3) return false; + + vector<WOEdge *>::iterator it; + e=NULL; + for(it=_OEdgeList.begin(); it!=_OEdgeList.end(); it++) + if ((*it)->GetaVertex()==v) e=*it; + if (!e) return false; + e=NULL; + for(it=_OEdgeList.begin(); it!=_OEdgeList.end(); it++) + if (((*it)->GetaVertex()!=v) && ((*it)->GetbVertex()!=v)) e=*it; + if (!e) return false; + else return true; +} + +real +WFace::getArea () +{ + vector<WOEdge *>::iterator it; + Vec3r origin=(*(_OEdgeList.begin()))->GetaVertex()->GetVertex(); + it=_OEdgeList.begin(); + real a=0; + for (it=it++; it!=_OEdgeList.end(); it++) { + Vec3r v1=Vec3r((*it)->GetaVertex()->GetVertex() - origin); + Vec3r v2=Vec3r((*it)->GetbVertex()->GetVertex() - origin); + a += (v1 ^ v2).norm() / 2.0; + } + return a; +} + + +WOEdge* +WFace::GetPrevOEdge(WOEdge* iOEdge) + { + vector<WOEdge*>::iterator woe,woend, woefirst; + woefirst = _OEdgeList.begin(); + woend=_OEdgeList.end(); + WOEdge *prev =*woefirst; + woe=woefirst; + woe++; + for(; + woe!=woend; + woe++) + { + if((*woe) == iOEdge) + return prev; + prev= *woe; + } + // We left the loop. That means that the first + // OEdge was the good one: + if((*woefirst)==iOEdge) + return prev; + + return NULL; + } + +WShape * WFace::getShape() +{ + return GetVertex(0)->shape(); +} + + /**********************************/ + /* */ + /* */ + /* WShape */ + /* */ + /* */ + /**********************************/ + + +LIB_WINGED_EDGE_EXPORT +unsigned WShape::_SceneCurrentId = 0; + +WShape * WShape::duplicate() +{ + WShape *clone = new WShape(*this); + return clone; +} + +WShape::WShape(WShape& iBrother) +{ + _Id = iBrother.GetId(); + _FrsMaterials = iBrother._FrsMaterials; + _meanEdgeSize = iBrother._meanEdgeSize; + iBrother.bbox(_min, _max); + vector<WVertex*>& vertexList = iBrother.getVertexList(); + vector<WVertex*>::iterator v=vertexList.begin(), vend=vertexList.end(); + for(; + v!=vend; + v++) + { + //WVertex *newVertex = new WVertex(*(*v)); + WVertex *newVertex = (*v)->duplicate(); + + newVertex->setShape(this); + AddVertex(newVertex); + } + + vector<WEdge*>& edgeList = iBrother.getEdgeList(); + vector<WEdge*>::iterator e=edgeList.begin(), eend=edgeList.end(); + for(; + e!=eend; + e++) + { + //WEdge *newEdge = new WEdge(*(*e)); + WEdge *newEdge = (*e)->duplicate(); + AddEdge(newEdge); + } + + vector<WFace*>& faceList = iBrother.GetFaceList(); + vector<WFace*>::iterator f=faceList.begin(), fend=faceList.end(); + for(; + f!=fend; + f++) + { + //WFace *newFace = new WFace(*(*f)); + WFace *newFace = (*f)->duplicate(); + AddFace(newFace); + } + + // update all pointed addresses thanks to the newly created objects: + vend=_VertexList.end(); + for(v=_VertexList.begin(); + v!=vend; + v++) + { + const vector<WEdge*>& vedgeList = (*v)->GetEdges(); + vector<WEdge*> newvedgelist; + unsigned int i; + for(i=0; i<vedgeList.size(); i++) + { + WEdge *current = vedgeList[i]; + edgedata * currentvedata = (edgedata*)current->userdata; + newvedgelist.push_back(currentvedata->_copy); + } + (*v)->setEdges(newvedgelist); + } + + eend = _EdgeList.end(); + for(e=_EdgeList.begin(); + e!=eend; + e++) + { + // update aOedge: + WOEdge *aoEdge = (*e)->GetaOEdge(); + aoEdge->setaVertex(((vertexdata*)(aoEdge->GetaVertex()->userdata))->_copy); + aoEdge->setbVertex(((vertexdata*)(aoEdge->GetbVertex()->userdata))->_copy); + if(NULL != aoEdge->GetaFace()) + aoEdge->setaFace(((facedata*)(aoEdge->GetaFace()->userdata))->_copy); + aoEdge->setbFace(((facedata*)(aoEdge->GetbFace()->userdata))->_copy); + aoEdge->setOwner(((edgedata*)(aoEdge->GetOwner()->userdata))->_copy); + // update bOedge: + + WOEdge *boEdge = (*e)->GetbOEdge(); + if(boEdge != 0) + { + boEdge->setaVertex(((vertexdata*)(boEdge->GetaVertex()->userdata))->_copy); + boEdge->setbVertex(((vertexdata*)(boEdge->GetbVertex()->userdata))->_copy); + if(NULL != boEdge->GetaFace()) + boEdge->setaFace(((facedata*)(boEdge->GetaFace()->userdata))->_copy); + boEdge->setbFace(((facedata*)(boEdge->GetbFace()->userdata))->_copy); + boEdge->setOwner(((edgedata*)(boEdge->GetOwner()->userdata))->_copy); + } + } + + fend = _FaceList.end(); + for(f=_FaceList.begin(); + f!=fend; + f++) + { + unsigned i; + const vector<WOEdge*>& oedgeList = (*f)->getEdgeList(); + vector<WOEdge*> newoedgelist; + + unsigned n = oedgeList.size(); + for(i=0; i<n; i++) + { + WOEdge *current = oedgeList[i]; + oedgedata * currentoedata = (oedgedata*)current->userdata; + newoedgelist.push_back(currentoedata->_copy); + //oedgeList[i] = currentoedata->_copy; + //oedgeList[i] = ((oedgedata*)(oedgeList[i]->userdata))->_copy; + } + (*f)->setEdgeList(newoedgelist); + } + + // Free all memory (arghh!) + // Vertex + vend = iBrother.getVertexList().end(); + for(v=iBrother.getVertexList().begin(); + v!=vend; + v++) + { + delete (vertexdata*)((*v)->userdata); + (*v)->userdata = NULL; + } + + // Edges and OEdges: + eend = iBrother.getEdgeList().end(); + for(e=iBrother.getEdgeList().begin(); + e!=eend; + e++) + { + delete (edgedata*)((*e)->userdata); + (*e)->userdata = NULL; + // OEdge a : + delete (oedgedata*)((*e)->GetaOEdge()->userdata); + (*e)->GetaOEdge()->userdata = NULL; + // OEdge b: + WOEdge* oedgeb = (*e)->GetbOEdge(); + if(NULL != oedgeb) + { + delete (oedgedata*)(oedgeb->userdata); + oedgeb->userdata = NULL; + } + } + // Faces + fend = iBrother.GetFaceList().end(); + for(f=iBrother.GetFaceList().begin(); + f!=fend; + f++) + { + delete (facedata*)((*f)->userdata); + (*f)->userdata = NULL; + } +} + +WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterial) +{ + // allocate the new face + WFace *face = instanciateFace(); + + return MakeFace(iVertexList, iMaterial, face); +} + +WFace * WShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, unsigned iMaterial) +{ + // allocate the new face + WFace *face = MakeFace(iVertexList, iMaterial); + + if(0 == face) + + return 0; + + // set the list of per-vertex normals + face->setNormalList(iNormalsList); + // set the list of per-vertex tex coords + face->setTexCoordsList(iTexCoordsList); + + return face; +} + +WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterial, WFace *face) +{ + + int id = _FaceList.size(); + + face->setFrsMaterialIndex(iMaterial); + + // Check whether we have a degenerated face: + + // LET'S HACK IT FOR THE TRIANGLE CASE: + + if(3 == iVertexList.size()) + + { + + if((iVertexList[0] == iVertexList[1]) + + || (iVertexList[0] == iVertexList[2]) + + || (iVertexList[2] == iVertexList[1])) + + { + + cerr << "Warning: degenerated triangle detected, correcting" << endl; + return 0; + + } + + } + // vertex pointers used to build each edge + vector<WVertex*>::iterator va, vb, it; + + va = iVertexList.begin(); + vb = va; + for(; va != iVertexList.end(); va = vb) + { + vb++; + // Adds va to the vertex list: + //face->AddVertex(*va); + + WOEdge * oedge; + if(*va == iVertexList.back()) + oedge = face->MakeEdge(*va, iVertexList.front()); //for the last (closing) edge + else + oedge = face->MakeEdge(*va, *vb); + + + if(oedge == 0) + return 0; + + + WEdge *edge = oedge->GetOwner(); + if(1 == edge->GetNumberOfOEdges()) + { + // means that we just created a new edge and that we must add it to the + // shape's edges list + edge->setId(_EdgeList.size()); + AddEdge(edge); + // compute the mean edge value: + _meanEdgeSize += edge->GetaOEdge()->getVec3r().norm(); + } + } + + // compute the face normal (v1v2 ^ v1v3) + WVertex *v1, *v2, *v3; + it = iVertexList.begin(); + v1 = *it; + it++; + v2 = *it; + it++; + v3 = *it; + + Vec3r vector1(v2->GetVertex()-v1->GetVertex()); + Vec3r vector2(v3->GetVertex()-v1->GetVertex()); + + Vec3r normal(vector1 ^ vector2); + normal.normalize(); + face->setNormal(normal); + + // Add the face to the shape's faces list: + face->setId(id); + AddFace(face); + + return face; +} diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.h b/source/blender/freestyle/intern/winged_edge/WEdge.h new file mode 100755 index 00000000000..9b05b4577a9 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WEdge.h @@ -0,0 +1,955 @@ +// +// Filename : WEdge.h +// Author(s) : Stephane Grabli +// Purpose : Classes to define a Winged Edge data structure. +// Date of creation : 18/02/2002 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef WEDGE_H +# define WEDGE_H + +# include <vector> +# include <iterator> +# include "../system/FreestyleConfig.h" +# include "../geometry/Geom.h" +# include "../scene_graph/FrsMaterial.h" + +using namespace std; +using namespace Geometry; + + + /**********************************/ + /* */ + /* */ + /* WVertex */ + /* */ + /* */ + /**********************************/ + + +class WOEdge; +class WEdge; +class WShape; +class WFace; +class LIB_WINGED_EDGE_EXPORT WVertex +{ +protected: + int _Id; // an identificator + Vec3r _Vertex; + vector<WEdge*> _EdgeList; + WShape * _Shape; // the shape to which the vertex belongs + bool _Smooth; // flag to indicate whether the Vertex belongs to a smooth edge or not + int _Border; // 1 -> border, 0 -> no border, -1 -> not set + +public: + void * userdata; // designed to store specific user data + inline WVertex(const Vec3r &v) {_Id = 0; _Vertex = v; userdata = NULL; _Shape = NULL;_Smooth=true;_Border=-1;} + /*! Copy constructor */ + WVertex(WVertex& iBrother); + virtual WVertex * duplicate(); + virtual ~WVertex() {} + + /*! accessors */ + inline Vec3r& GetVertex() {return _Vertex;} + inline vector<WEdge*>& GetEdges() {return _EdgeList;} + inline int GetId() {return _Id;} + inline WShape * shape() const {return _Shape;} + inline bool isSmooth() const {return _Smooth;} + bool isBoundary(); + + /*! modifiers */ + inline void setVertex(const Vec3r& v) {_Vertex = v;} + inline void setEdges(const vector<WEdge *>& iEdgeList) {_EdgeList = iEdgeList;} + inline void setId(int id) {_Id = id;} + inline void setShape(WShape *iShape) {_Shape = iShape;} + inline void setSmooth(bool b) {_Smooth = b;} + inline void setBorder(bool b) {if(b) _Border= 1; else _Border = 0;} + + /*! Adds an edge to the edges list */ + void AddEdge(WEdge *iEdge) ; + + virtual void ResetUserData() {userdata = 0;} + + + +public: + + + + /*! Iterator to iterate over a vertex incoming edges in the CCW order*/ +# if defined(__GNUC__) && (__GNUC__ < 3) + class incoming_edge_iterator : public input_iterator<WOEdge*,ptrdiff_t> +# else + class LIB_WINGED_EDGE_EXPORT incoming_edge_iterator : public iterator<input_iterator_tag, WOEdge*,ptrdiff_t> +# endif + { + private: + WVertex *_vertex; + // + WOEdge *_begin; + WOEdge *_current; + + public: +# if defined(__GNUC__) && (__GNUC__ < 3) + inline incoming_edge_iterator() : input_iterator<WOEdge*,ptrdiff_t>() {} +# else + inline incoming_edge_iterator() : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>() {} +# endif + virtual ~incoming_edge_iterator() {}; //soc + + protected: + friend class WVertex; + inline incoming_edge_iterator( + WVertex *iVertex, + WOEdge * iBegin, + WOEdge * iCurrent) +# if defined(__GNUC__) && (__GNUC__ < 3) + : input_iterator<WOEdge*,ptrdiff_t>() +# else + : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>() +# endif + { + _vertex = iVertex; + _begin = iBegin; + _current = iCurrent; + } + + public: + inline incoming_edge_iterator(const incoming_edge_iterator& iBrother) +# if defined(__GNUC__) && (__GNUC__ < 3) + : input_iterator<WOEdge*,ptrdiff_t>(iBrother) +# else + : iterator<input_iterator_tag, WOEdge*,ptrdiff_t>(iBrother) +# endif + { + _vertex = iBrother._vertex; + _begin = iBrother._begin; + _current = iBrother._current; + } + + public: + // operators + virtual incoming_edge_iterator& operator++() // operator corresponding to ++i + { + increment(); + return *this; + } + virtual incoming_edge_iterator operator++(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + incoming_edge_iterator tmp = *this; // C'est pour cela qu'on stocke la valeur + increment(); // dans un temporaire. + return tmp; + } + + // comparibility + virtual bool operator!=(const incoming_edge_iterator& b) const + { + return ((_current) != (b._current)); + } + + virtual bool operator==(const incoming_edge_iterator& b) const + { + return ((_current)== (b._current)); + } + + // dereferencing + virtual WOEdge* operator*(); + //virtual WOEdge** operator->(); + protected: + virtual void increment(); + }; + + + /*! Iterator to iterate over a vertex faces in the CCW order */ +# if defined(__GNUC__) && (__GNUC__ < 3) + class face_iterator : public input_iterator<WFace*,ptrdiff_t> +# else + class LIB_WINGED_EDGE_EXPORT face_iterator : public iterator<input_iterator_tag, WFace*,ptrdiff_t> +# endif + { + private: + incoming_edge_iterator _edge_it; + + public: +# if defined(__GNUC__) && (__GNUC__ < 3) + inline face_iterator() : input_iterator<WFace*,ptrdiff_t>() {} +# else + inline face_iterator() : iterator<input_iterator_tag, WFace*,ptrdiff_t>() {} +# endif + virtual ~face_iterator() {}; //soc + + protected: + friend class WVertex; + inline face_iterator( + incoming_edge_iterator it) +# if defined(__GNUC__) && (__GNUC__ < 3) + : input_iterator<WFace*,ptrdiff_t>() +# else + : iterator<input_iterator_tag, WFace*,ptrdiff_t>() +# endif + { + _edge_it = it; + } + + public: + inline face_iterator(const face_iterator& iBrother) +# if defined(__GNUC__) && (__GNUC__ < 3) + : input_iterator<WFace*,ptrdiff_t>(iBrother) +# else + : iterator<input_iterator_tag, WFace*,ptrdiff_t>(iBrother) +# endif + { + _edge_it = iBrother._edge_it; + } + + public: + // operators + virtual face_iterator& operator++() // operator corresponding to ++i + { + increment(); + return *this; + } + virtual face_iterator operator++(int) // opérateur correspondant à i++ + { // c.a.d qui renvoie la valeur *puis* incrémente. + face_iterator tmp = *this; // C'est pour cela qu'on stocke la valeur + increment(); // dans un temporaire. + return tmp; + } + + // comparibility + virtual bool operator!=(const face_iterator& b) const + { + return ((_edge_it) != (b._edge_it)); + } + + virtual bool operator==(const face_iterator& b) const + { + return ((_edge_it)== (b._edge_it)); + } + + // dereferencing + virtual WFace* operator*(); + //virtual WOEdge** operator->(); + protected: + inline void increment(){ + ++_edge_it; + } + }; + +public: + /*! iterators access */ + virtual incoming_edge_iterator incoming_edges_begin(); + virtual incoming_edge_iterator incoming_edges_end() ; + + virtual face_iterator faces_begin() { + return face_iterator(incoming_edges_begin()); + } + virtual face_iterator faces_end() { + return face_iterator(incoming_edges_end()); + } +}; + + + /**********************************/ + /* */ + /* */ + /* WOEdge */ + /* */ + /* */ + /**********************************/ +class WFace; +class WEdge; + +class LIB_WINGED_EDGE_EXPORT WOEdge +{ +protected: + // WOEdge *_paCWEdge; // edge reached when traveling clockwise on aFace from the edge + // WOEdge *_pbCWEdge; // edge reached when traveling clockwise on bFace from the edge + // WOEdge *_paCCWEdge; // edge reached when traveling counterclockwise on aFace from the edge + // WOEdge *_pbCCWEdge; // edge reached when traveling counterclockwise on bFace from the edge + WVertex *_paVertex; // starting vertex + WVertex *_pbVertex; // ending vertex + WFace *_paFace; // when following the edge, face on the right + WFace *_pbFace; // when following the edge, face on the left + WEdge *_pOwner; // Edge + +public: + void *userdata; + inline WOEdge() + { + // _paCWEdge = NULL; + // _pbCWEdge = NULL; + // _paCCWEdge = NULL; + // _pbCCWEdge = NULL; + _paVertex = NULL; + _pbVertex = NULL; + _paFace = NULL; + _pbFace = NULL; + _pOwner = NULL; + userdata = NULL; + } + virtual ~WOEdge() {}; //soc + + /*! copy constructor */ + WOEdge(WOEdge& iBrother); + virtual WOEdge * duplicate(); + + /*! accessors */ + // inline WOEdge *GetaCWEdge() {return _paCWEdge;} + // inline WOEdge *GetbCWEdge() {return _pbCWEdge;} + // inline WOEdge *GetaCCWEdge() {return _paCCWEdge;} + // inline WOEdge *GetbCCWEdge() {return _pbCCWEdge;} + inline WVertex *GetaVertex() {return _paVertex;} + inline WVertex *GetbVertex() {return _pbVertex;} + inline WFace *GetaFace() {return _paFace;} + inline WFace *GetbFace() {return _pbFace;} + inline WEdge *GetOwner() {return _pOwner;} + + + /*! modifiers */ + // inline void SetaCWEdge(WOEdge *pe) {_paCWEdge = pe;} + // inline void SetbCWEdge(WOEdge *pe) {_pbCWEdge = pe;} + // inline void SetaCCWEdge(WOEdge *pe) {_paCCWEdge = pe;} + // inline void SetbCCCWEdge(WOEdge *pe) {_pbCCWEdge = pe;} + inline void setaVertex(WVertex *pv) {_paVertex = pv;} + inline void setbVertex(WVertex *pv) {_pbVertex = pv;} + inline void setaFace(WFace *pf) {_paFace = pf;} + inline void setbFace(WFace *pf) {_pbFace = pf;} + inline void setOwner(WEdge *pe) {_pOwner = pe;} + + /*! Retrieves the list of edges in CW order */ + inline void RetrieveCWOrderedEdges(vector<WEdge*>& oEdges); + /*! returns the vector between the two vertices */ + Vec3r getVec3r (); + WOEdge * twin (); + WOEdge * getPrevOnFace(); + virtual void ResetUserData() {userdata = 0;} +}; + + + /**********************************/ + /* */ + /* */ + /* WEdge */ + /* */ + /* */ + /**********************************/ + +class LIB_WINGED_EDGE_EXPORT WEdge +{ +protected: + WOEdge *_paOEdge; // first oriented edge + WOEdge *_pbOEdge; // second oriented edge + int _nOEdges; // number of oriented edges associated with this edge. (1 means border edge) + int _Id; // Identifier for the edge + +public: + void * userdata; // designed to store specific user data + inline WEdge() + { + _paOEdge = NULL; + _pbOEdge = NULL; + _nOEdges = 0; + userdata = NULL; + } + + inline WEdge(WOEdge *iOEdge) + { + _paOEdge = iOEdge; + _pbOEdge = NULL; + _nOEdges = 1; + userdata = NULL; + } + + inline WEdge(WOEdge *iaOEdge, WOEdge *ibOEdge) + { + _paOEdge = iaOEdge; + _pbOEdge = ibOEdge; + _nOEdges = 2; + userdata = NULL; + } + + /*! Copy constructor */ + WEdge(WEdge& iBrother); + virtual WEdge * duplicate(); + + virtual ~WEdge() + { + if(NULL != _paOEdge) + { + delete _paOEdge; + _paOEdge = NULL; + } + + if(NULL != _pbOEdge) + { + delete _pbOEdge; + _pbOEdge = NULL; + } + } + + /*! checks whether two WEdge have a common vertex. + * Returns a pointer on the common vertex if it exists, + * NULL otherwise. + */ + static inline WVertex* CommonVertex(WEdge *iEdge1, WEdge* iEdge2) + { + if((NULL == iEdge1) || (NULL == iEdge2)) + return NULL; + + WVertex *wv1 = iEdge1->GetaOEdge()->GetaVertex(); + WVertex *wv2 = iEdge1->GetaOEdge()->GetbVertex(); + WVertex *wv3 = iEdge2->GetaOEdge()->GetaVertex(); + WVertex *wv4 = iEdge2->GetaOEdge()->GetbVertex(); + + if((wv1 == wv3) || (wv1 == wv4)) + { + return wv1; + } + else if((wv2 == wv3) || (wv2 == wv4)) + { + return wv2; + } + + return NULL; + } + /*! accessors */ + inline WOEdge * GetaOEdge() {return _paOEdge;} + inline WOEdge * GetbOEdge() {return _pbOEdge;} + inline int GetNumberOfOEdges() {return _nOEdges;} + inline int GetId() {return _Id;} + inline WVertex * GetaVertex() {return _paOEdge->GetaVertex();} + inline WVertex * GetbVertex() {return _paOEdge->GetbVertex();} + inline WFace * GetaFace() {return _paOEdge->GetaFace();} + inline WFace * GetbFace() {return _paOEdge->GetbFace();} + inline WOEdge* GetOtherOEdge(WOEdge* iOEdge) + { + if(iOEdge == _paOEdge) + return _pbOEdge; + else + return _paOEdge; + } + + /*! modifiers */ + inline void setaOEdge(WOEdge *iEdge) {_paOEdge = iEdge;} + inline void setbOEdge(WOEdge *iEdge) {_pbOEdge = iEdge;} + inline void AddOEdge(WOEdge *iEdge) + { + if(NULL == _paOEdge) + { + _paOEdge = iEdge; + _nOEdges++; + return; + } + if(NULL == _pbOEdge) + { + _pbOEdge = iEdge; + _nOEdges++; + return; + } + } + inline void setNumberOfOEdges(int n) {_nOEdges = n;} + inline void setId(int id) {_Id = id;} + virtual void ResetUserData() {userdata = 0;} +}; + + /**********************************/ + /* */ + /* */ + /* WFace */ + /* */ + /* */ + /**********************************/ + + +class LIB_WINGED_EDGE_EXPORT WFace +{ +protected: + vector<WOEdge *> _OEdgeList; // list of oriented edges of bording the face + Vec3r _Normal; // normal to the face + vector<Vec3r> _VerticesNormals; // in case there is a normal per vertex. + // The normal number i corresponds to the + // aVertex of the oedge number i, for that face + vector<Vec2r> _VerticesTexCoords; + + int _Id; + unsigned _FrsMaterialIndex; + +public: + void *userdata; + inline WFace() {userdata = NULL;_FrsMaterialIndex = 0;} + /*! copy constructor */ + WFace(WFace& iBrother); + virtual WFace * duplicate(); + virtual ~WFace() {} + + /*! accessors */ + inline const vector<WOEdge*>& getEdgeList() {return _OEdgeList;} + inline WOEdge * GetOEdge(int i) {return _OEdgeList[i];} + inline Vec3r& GetNormal() {return _Normal;} + inline int GetId() {return _Id;} + inline unsigned frs_materialIndex() const {return _FrsMaterialIndex;} + const FrsMaterial& frs_material() ; + + /*! The vertex of index i corresponds to the a vertex + * of the edge of index i + */ + inline WVertex* GetVertex(unsigned int index) + { + // if(index >= _OEdgeList.size()) + // return NULL; + return _OEdgeList[index]->GetaVertex(); + } + /*! returns the index at which iVertex is stored in the + * array. + * returns -1 if iVertex doesn't belong to the face. + */ + inline int GetIndex(WVertex *iVertex){ + int index = 0; + for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end(); + woe!=woend; + woe++){ + if((*woe)->GetaVertex() == iVertex) + return index; + ++index; + } + return -1; + } + inline void RetrieveVertexList(vector<WVertex*>& oVertices) + { + for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end(); + woe!=woend; + woe++) + { + oVertices.push_back((*woe)->GetaVertex()); + } + } + inline void RetrieveBorderFaces(vector<const WFace*>& oWFaces) + { + for(vector<WOEdge*>::iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end(); + woe!=woend; + woe++) + { + WFace *af; + if(NULL != (af = (*woe)->GetaFace())) + oWFaces.push_back(af); + } + } + inline WFace * GetBordingFace(int index) + { + // if(index >= _OEdgeList.size()) + // return 0; + return _OEdgeList[index]->GetaFace(); + } + inline WFace * GetBordingFace(WOEdge *iOEdge) + { + return iOEdge->GetaFace(); + } + inline vector<Vec3r>& GetPerVertexNormals() + { + return _VerticesNormals; + } + inline vector<Vec2r>& GetPerVertexTexCoords() + { + return _VerticesTexCoords; + } + /*! Returns the normal of the vertex of index index */ + inline Vec3r& GetVertexNormal(int index) + { + return _VerticesNormals[index]; + } + /*! Returns the tex coords of the vertex of index index */ + inline Vec2r& GetVertexTexCoords(int index) + { + return _VerticesTexCoords[index]; + } + /*! Returns the normal of the vertex iVertex for that face */ + inline Vec3r& GetVertexNormal(WVertex *iVertex) + { + int i = 0; + int index = 0; + for(vector<WOEdge*>::const_iterator woe=_OEdgeList.begin(), woend=_OEdgeList.end(); + woe!=woend; + woe++) + { + if((*woe)->GetaVertex() == iVertex) + { + index = i; + break; + } + ++i; + } + + return _VerticesNormals[index]; + } + inline WOEdge* GetNextOEdge(WOEdge* iOEdge) + { + bool found = false; + vector<WOEdge*>::iterator woe,woend, woefirst; + woefirst = _OEdgeList.begin(); + for(woe=woefirst,woend=_OEdgeList.end(); + woe!=woend; + woe++) + { + if(true == found) + return (*woe); + + if((*woe) == iOEdge) + { + found = true; + } + } + + // We left the loop. That means that the first + // OEdge was the good one: + if(found) + return (*woefirst); + + return NULL; + } + WOEdge* GetPrevOEdge(WOEdge* iOEdge); + + inline int numberOfEdges() const { return _OEdgeList.size();} + inline int numberOfVertices() const { return _OEdgeList.size();} + /*! Returns true if the face has one ot its edge which is a border + * edge + */ + inline bool isBorder() const + { + for(vector<WOEdge*>::const_iterator woe=_OEdgeList.begin(), woeend=_OEdgeList.end(); + woe!=woeend; + ++woe) + { + if((*woe)->GetOwner()->GetbOEdge() == 0) + return true; + } + return false; + } + /*! modifiers */ + inline void setEdgeList(const vector<WOEdge*>& iEdgeList) {_OEdgeList = iEdgeList;} + inline void setNormal(const Vec3r& iNormal) {_Normal = iNormal;} + inline void setNormalList(const vector<Vec3r>& iNormalsList) {_VerticesNormals = iNormalsList;} + inline void setTexCoordsList(const vector<Vec2r>& iTexCoordsList) {_VerticesTexCoords = iTexCoordsList;} + inline void setId(int id) {_Id = id;} + inline void setFrsMaterialIndex(unsigned iMaterialIndex) {_FrsMaterialIndex = iMaterialIndex;} + + /*! designed to build a specialized WEdge + * for use in MakeEdge + */ + virtual WEdge * instanciateEdge() const {return new WEdge;} + + /*! Builds an oriented edge + * Returns the built edge. + * v1, v2 + * Vertices at the edge's extremities + * The edge is oriented from v1 to v2. + */ + virtual WOEdge * MakeEdge(WVertex *v1, WVertex *v2); + + /*! Adds an edge to the edges list */ + inline void AddEdge(WOEdge *iEdge) {_OEdgeList.push_back(iEdge);} + + /*! For triangles, returns the edge opposite to the vertex in e. + returns flase if the face is not a triangle or if the vertex is not found*/ + bool getOppositeEdge (const WVertex *v, WOEdge* &e); + + /*! compute the area of the face */ + real getArea (); + + WShape * getShape() ; + virtual void ResetUserData() {userdata = 0;} +}; + + + /**********************************/ + /* */ + /* */ + /* WShape */ + /* */ + /* */ + /**********************************/ + + +class LIB_WINGED_EDGE_EXPORT WShape +{ +protected: + vector<WVertex*> _VertexList; + vector<WEdge*> _EdgeList; + vector<WFace*> _FaceList; + int _Id; + static unsigned _SceneCurrentId; + Vec3r _min; + Vec3r _max; + vector<FrsMaterial> _FrsMaterials; + real _meanEdgeSize; + +public: + inline WShape() {_meanEdgeSize = 0;_Id = _SceneCurrentId; _SceneCurrentId++;} + /*! copy constructor */ + WShape(WShape& iBrother); + virtual WShape * duplicate(); + virtual ~WShape() + { + if(_EdgeList.size() != 0) + { + vector<WEdge *>::iterator e; + for(e=_EdgeList.begin(); e!=_EdgeList.end(); e++) + { + delete (*e); + } + _EdgeList.clear(); + } + + if(_VertexList.size() != 0) + { + vector<WVertex *>::iterator v; + for(v=_VertexList.begin(); v!=_VertexList.end(); v++) + { + delete (*v); + } + _VertexList.clear(); + } + + if(_FaceList.size() != 0) + { + vector<WFace *>::iterator f; + for(f=_FaceList.begin(); f!=_FaceList.end(); f++) + { + delete (*f); + } + _FaceList.clear(); + } + } + + /*! accessors */ + inline vector<WEdge *>& getEdgeList() {return _EdgeList;} + inline vector<WVertex*>& getVertexList() {return _VertexList;} + inline vector<WFace*>& GetFaceList() {return _FaceList;} + inline unsigned GetId() {return _Id;} + inline void bbox(Vec3r& min, Vec3r& max) {min=_min; max=_max;} + inline const FrsMaterial& frs_material(unsigned i) const {return _FrsMaterials[i];} + inline const vector<FrsMaterial>& frs_materials() const {return _FrsMaterials;} + inline const real getMeanEdgeSize() const {return _meanEdgeSize;} + /*! modifiers */ + static inline void setCurrentId(const unsigned id) { _SceneCurrentId = id; } + inline void setEdgeList(const vector<WEdge*>& iEdgeList) {_EdgeList = iEdgeList;} + inline void setVertexList(const vector<WVertex*>& iVertexList) {_VertexList = iVertexList;} + inline void setFaceList(const vector<WFace*>& iFaceList) {_FaceList = iFaceList;} + inline void setId(int id) {_Id = id;} + inline void setBBox(const Vec3r& min, const Vec3r& max) {_min = min; _max=max;} + inline void setFrsMaterial(const FrsMaterial& frs_material, unsigned i) {_FrsMaterials[i]=frs_material;} + inline void setFrsMaterials(const vector<FrsMaterial>& iMaterials) {_FrsMaterials = iMaterials;} + + /*! designed to build a specialized WFace + * for use in MakeFace + */ + virtual WFace * instanciateFace() const {return new WFace;} + + /*! adds a new face to the shape + * returns the built face. + * iVertexList + * List of face's vertices. These vertices are + * not added to the WShape vertex list; they are + * supposed to be already stored when calling MakeFace. + * The order in which the vertices are stored in the list + * determines the face's edges orientation and (so) the + * face orientation. + * iMaterialIndex + * The material index for this face + */ + virtual WFace * MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex); + + /*! adds a new face to the shape. The difference with + * the previous method is that this one is designed + * to build a WingedEdge structure for which there are + * per vertex normals, opposed to per face normals. + * returns the built face. + * iVertexList + * List of face's vertices. These vertices are + * not added to the WShape vertex list; they are + * supposed to be already stored when calling MakeFace. + * The order in which the vertices are stored in the list + * determines the face's edges orientation and (so) the + * face orientation. + * iMaterialIndex + * The materialIndex for this face + * iNormalsList + * The list of normals, iNormalsList[i] corresponding to the + * normal of the vertex iVertexList[i] for that face. + * iTexCoordsList + * The list of tex coords, iTexCoordsList[i] corresponding to the + * normal of the vertex iVertexList[i] for that face. + */ + virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, unsigned iMaterialIndex); + + inline void AddEdge(WEdge *iEdge) {_EdgeList.push_back(iEdge);} + inline void AddFace(WFace* iFace) {_FaceList.push_back(iFace);} + inline void AddVertex(WVertex *iVertex) {iVertex->setShape(this); _VertexList.push_back(iVertex);} + + inline void ResetUserData() + { + for(vector<WVertex*>::iterator v=_VertexList.begin(),vend=_VertexList.end(); + v!=vend; + v++) + { + (*v)->ResetUserData(); + } + + for(vector<WEdge*>::iterator e=_EdgeList.begin(),eend=_EdgeList.end(); + e!=eend; + e++) + { + (*e)->ResetUserData(); + // manages WOEdge: + WOEdge *oe = (*e)->GetaOEdge(); + if(oe != NULL) + oe->ResetUserData(); + oe = (*e)->GetbOEdge(); + if(oe != NULL) + oe->ResetUserData(); + } + + for(vector<WFace*>::iterator f=_FaceList.begin(),fend=_FaceList.end(); + f!=fend; + f++) + { + (*f)->ResetUserData(); + } + + } + + inline void ComputeBBox() + { + _min = _VertexList[0]->GetVertex(); + _max = _VertexList[0]->GetVertex(); + + Vec3r v; + for(vector<WVertex*>::iterator wv=_VertexList.begin(), wvend=_VertexList.end(); + wv!=wvend; + wv++) + { + for(unsigned int i=0; i<3; i++) + { + v = (*wv)->GetVertex(); + if(v[i] < _min[i]) + _min[i] = v[i]; + if(v[i] > _max[i]) + _max[i] = v[i]; + } + } + } + + inline real ComputeMeanEdgeSize(){ + _meanEdgeSize = _meanEdgeSize/(_EdgeList.size()); + return _meanEdgeSize; + } + +protected: + /*! Builds the face passed as argument (which as already been allocated) + * iVertexList + * List of face's vertices. These vertices are + * not added to the WShape vertex list; they are + * supposed to be already stored when calling MakeFace. + * The order in which the vertices are stored in the list + * determines the face's edges orientation and (so) the + * face orientation. + * iMaterialIndex + * The material index for this face + * face + * The Face that is filled in + */ + virtual WFace * MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex, WFace *face); +}; + + + /**********************************/ + /* */ + /* */ + /* WingedEdge */ + /* */ + /* */ + /**********************************/ + +class WingedEdge { + + public: + + WingedEdge() {} + + ~WingedEdge() { + clear(); + } + + void clear() { + for (vector<WShape*>::iterator it = _wshapes.begin(); + it != _wshapes.end(); + it++) + delete *it; + _wshapes.clear(); + } + + void addWShape(WShape* wshape) { + _wshapes.push_back(wshape); + } + + vector<WShape*>& getWShapes() { + return _wshapes; + } + + private: + + vector<WShape*> _wshapes; +}; + + + +/* + + ############################################# + ############################################# + ############################################# + ###### ###### + ###### I M P L E M E N T A T I O N ###### + ###### ###### + ############################################# + ############################################# + ############################################# + +*/ +/* for inline functions */ +void WOEdge::RetrieveCWOrderedEdges(vector<WEdge*>& oEdges) +{ + + WOEdge *currentOEdge = this; + do + { + WOEdge* nextOEdge = currentOEdge->GetbFace()->GetNextOEdge(currentOEdge); + oEdges.push_back(nextOEdge->GetOwner()); + currentOEdge = nextOEdge->GetOwner()->GetOtherOEdge(nextOEdge); + + } while((currentOEdge != NULL) && (currentOEdge->GetOwner() != GetOwner())); +} + +#endif // WEDGE_H diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp b/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp new file mode 100755 index 00000000000..7d0a2d3c561 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.cpp @@ -0,0 +1,60 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "WEdge.h" +#include "WFillGrid.h" + +void WFillGrid::fillGrid() { + if (!_winged_edge || !_grid) + return; + + vector<WShape*> wshapes = _winged_edge->getWShapes(); + vector<WVertex*> fvertices; + vector<Vec3r> vectors; + vector<WFace*> faces; + + for (vector<WShape*>::const_iterator it = wshapes.begin(); + it != wshapes.end(); + it++) { + faces = (*it)->GetFaceList(); + + for (vector<WFace*>::const_iterator f = faces.begin(); + f != faces.end(); + f++) { + (*f)->RetrieveVertexList(fvertices); + + for (vector<WVertex*>::const_iterator wv = fvertices.begin(); + wv != fvertices.end(); + wv++) + vectors.push_back(Vec3r((*wv)->GetVertex())); + + // occluder will be deleted by the grid + Polygon3r *occluder = + new Polygon3r(vectors, (*f)->GetNormal()); + occluder->setId(_polygon_id++); + occluder->userdata = (void*)(*f); + _grid->insertOccluder(occluder); + vectors.clear(); + fvertices.clear(); + } + faces.clear(); + } +} diff --git a/source/blender/freestyle/intern/winged_edge/WFillGrid.h b/source/blender/freestyle/intern/winged_edge/WFillGrid.h new file mode 100755 index 00000000000..2ebbc2f359a --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WFillGrid.h @@ -0,0 +1,80 @@ +// +// Filename : WFillGrid.h +// Author(s) : Stephane Grabli +// Emmanuel Turquin +// Purpose : Class to fill in a grid from a SceneGraph +// (uses only the WingedEdge structures) +// Date of creation : 03/05/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef W_FILL_GRID_H +# define W_FILL_GRID_H + +# include "../geometry/Grid.h" +# include "../geometry/Polygon.h" +# include "WEdge.h" + +class LIB_WINGED_EDGE_EXPORT WFillGrid +{ +public: + + inline WFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) { + _winged_edge = winged_edge; + _grid = grid; + _polygon_id = 0; + } + + virtual ~WFillGrid() {} + + void fillGrid(); + + /*! Accessors */ + WingedEdge* getWingedEdge() { + return _winged_edge; + } + + Grid* getGrid() { + return _grid; + } + + /*! Modifiers */ + void setWingedEdge(WingedEdge* winged_edge) { + if (winged_edge) + _winged_edge = winged_edge; + } + + void setGrid(Grid* grid) { + if (grid) + _grid = grid; + } + +private: + + Grid* _grid; + WingedEdge* _winged_edge; + unsigned _polygon_id; +}; + +#endif // WS_FILL_GRID_H diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp b/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp new file mode 100755 index 00000000000..55fa418d4f5 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.cpp @@ -0,0 +1,60 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "WEdge.h" +#include "WSFillGrid.h" + +void WSFillGrid::fillGrid() { + if (!_winged_edge || !_grid) + return; + + vector<WShape*> wshapes = _winged_edge->getWShapes(); + vector<WVertex*> fvertices; + vector<Vec3r> vectors; + vector<WFace*> faces; + + for (vector<WShape*>::const_iterator it = wshapes.begin(); + it != wshapes.end(); + it++) { + faces = (*it)->GetFaceList(); + + for (vector<WFace*>::const_iterator f = faces.begin(); + f != faces.end(); + f++) { + (*f)->RetrieveVertexList(fvertices); + + for (vector<WVertex*>::const_iterator wv = fvertices.begin(); + wv != fvertices.end(); + wv++) + vectors.push_back(Vec3r((*wv)->GetVertex())); + + // occluder will be deleted by the grid + Polygon3r *occluder = + new Polygon3r(vectors, (*f)->GetNormal()); + occluder->setId(_polygon_id++); + occluder->userdata = (void*)(*f); + _grid->insertOccluder(occluder); + vectors.clear(); + fvertices.clear(); + } + faces.clear(); + } +} diff --git a/source/blender/freestyle/intern/winged_edge/WSFillGrid.h b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h new file mode 100755 index 00000000000..2ea5bc6c621 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WSFillGrid.h @@ -0,0 +1,79 @@ +// +// Filename : WSFillGrid.h +// Author(s) : Stephane Grabli +// Purpose : Class to fill in a grid from a SceneGraph +// (uses only the WingedEdge structures) +// Date of creation : 03/05/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef WS_FILL_GRID_H +# define WS_FILL_GRID_H + +# include "../geometry/Grid.h" +# include "../geometry/Polygon.h" +# include "WEdge.h" + +class LIB_WINGED_EDGE_EXPORT WSFillGrid +{ +public: + + inline WSFillGrid(Grid* grid = 0, WingedEdge* winged_edge = 0) { + _winged_edge = winged_edge; + _grid = grid; + _polygon_id = 0; + } + + virtual ~WSFillGrid() {} + + void fillGrid(); + + /*! Accessors */ + WingedEdge* getWingedEdge() { + return _winged_edge; + } + + Grid* getGrid() { + return _grid; + } + + /*! Modifiers */ + void setWingedEdge(WingedEdge* winged_edge) { + if (winged_edge) + _winged_edge = winged_edge; + } + + void setGrid(Grid* grid) { + if (grid) + _grid = grid; + } + +private: + + Grid* _grid; + WingedEdge* _winged_edge; + unsigned _polygon_id; +}; + +#endif // WS_FILL_GRID_H diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp new file mode 100755 index 00000000000..ff567aee06a --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp @@ -0,0 +1,296 @@ +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "WXEdge.h" + + /**********************************/ + /* */ + /* */ + /* WXFace */ + /* */ + /* */ + /**********************************/ + +unsigned int WXFaceLayer::Get0VertexIndex() const { + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for(i=0; i<nEdges; ++i){ + if(_DotP[i] == 0){ + return i; + } + } + return -1; +} +unsigned int WXFaceLayer::GetSmoothEdgeIndex() const{ + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for(i=0; i<nEdges; ++i){ + if((_DotP[i] == 0) && (_DotP[(i+1)%nEdges] == 0)){ + return i; + } + } + return -1; +} + +void WXFaceLayer::RetrieveCuspEdgesIndices(vector<int>& oCuspEdges){ + int i = 0; + int nEdges = _pWXFace->numberOfEdges(); + for(i=0; i<nEdges; ++i){ + if(_DotP[i]*_DotP[(i+1)%nEdges] < 0){ + // we got one + oCuspEdges.push_back(i); + } + } +} + +WXSmoothEdge* WXFaceLayer::BuildSmoothEdge(){ + // if the smooth edge has already been + // built: exit + if(0 != _pSmoothEdge) + return _pSmoothEdge; + real ta, tb; + WOEdge *woea(0), *woeb(0); + bool ok = false; + vector<int> cuspEdgesIndices; + int indexStart, indexEnd; + unsigned nedges = _pWXFace->numberOfEdges(); + if(_nNullDotP == nedges){ + _pSmoothEdge = 0; + return _pSmoothEdge; + } + if((_nPosDotP != 0) && (_nPosDotP != _DotP.size()) && (_nNullDotP == 0)){ + // that means that we have a smooth edge that starts from + // an edge and ends at an edge + //----------------------------- + // We retrieve the 2 edges for which we have + // opposite signs for each extremity + RetrieveCuspEdgesIndices(cuspEdgesIndices); + if(cuspEdgesIndices.size() != 2) // we necessarly have 2 cusp edges + return 0; + + // let us determine which cusp edge corresponds to the starting: + // We can do that because we defined that + // a silhouette edge had the back facing part on its right. + // So if the WOEdge woea is such that woea[0].dotp > 0 and + // woea[1].dotp < 0, it is the starting edge. + //------------------------------------------- + + if(_DotP[cuspEdgesIndices[0]] > 0){ + woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + woeb = _pWXFace->GetOEdge(cuspEdgesIndices[1]); + indexStart = cuspEdgesIndices[0]; + indexEnd = cuspEdgesIndices[1]; + }else{ + woea = _pWXFace->GetOEdge(cuspEdgesIndices[1]); + woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + indexStart = cuspEdgesIndices[1]; + indexEnd = cuspEdgesIndices[0]; + } + + // Compute the interpolation: + ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]); + tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]); + ok = true; + }else if(_nNullDotP == 1){ + // that means that we have exactly one of the + // 2 extremities of our silhouette edge is + // a vertex of the mesh + if((_nPosDotP == 2) || (_nPosDotP == 0)){ + _pSmoothEdge = 0; + return _pSmoothEdge; + } + RetrieveCuspEdgesIndices(cuspEdgesIndices); + // We should have only one EdgeCusp: + if(cuspEdgesIndices.size() != 1){ + cout << "Warning in BuildSmoothEdge: weird WXFace configuration" << endl; + _pSmoothEdge = 0; + return 0; + } + unsigned index0 = Get0VertexIndex(); // retrieve the 0 vertex index + unsigned nedges = _pWXFace->numberOfEdges(); + if(_DotP[cuspEdgesIndices[0]] > 0){ + woea = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + woeb = _pWXFace->GetOEdge(index0); + indexStart = cuspEdgesIndices[0]; + ta = _DotP[indexStart]/(_DotP[indexStart]-_DotP[(indexStart+1)%nedges]); + tb = 0.0; + }else{ + woea = _pWXFace->GetOEdge(index0); + woeb = _pWXFace->GetOEdge(cuspEdgesIndices[0]); + indexEnd = cuspEdgesIndices[0]; + ta = 0.0; + tb = _DotP[indexEnd]/(_DotP[indexEnd]-_DotP[(indexEnd+1)%nedges]); + } + ok = true; + }else if(_nNullDotP == 2){ + // that means that the silhouette edge + // is an edge of the mesh + int index = GetSmoothEdgeIndex(); + if(!_pWXFace->front()) {// is it in the right order ? + // the order of the WOEdge index is wrong + woea = _pWXFace->GetOEdge((index+1)%nedges); + woeb = _pWXFace->GetOEdge((index-1)%nedges); + ta = 0; + tb = 1; + ok = true; + }else{ + // here it's not good, our edge is a single point -> skip that face + ok = false; + // the order of the WOEdge index is good + // woea = _pWXFace->GetOEdge((index-1)%nedges); + // woeb = _pWXFace->GetOEdge((index+1)%nedges); + // ta = 1; + // tb = 0; + } + } + if(ok){ + _pSmoothEdge = new WXSmoothEdge; + _pSmoothEdge->setWOeA(woea); + _pSmoothEdge->setWOeB(woeb); + _pSmoothEdge->setTa(ta); + _pSmoothEdge->setTb(tb); + if(_Nature & Nature::SILHOUETTE){ + if(_nNullDotP != 2){ + if(_DotP[_ClosestPointIndex] + 0.01 > 0) + _pSmoothEdge->setFront(true); + else + _pSmoothEdge->setFront(false); + } + } + } + + // check bording edges to see if they have different dotp values + // in bording faces. + // for(int i=0; i<numberOfEdges(); i++) + // { + // WSFace * bface = (WSFace*)GetBordingFace(i); + // if(bface != 0) + // { + // if((front())^(bface->front())) // fA->front XOR fB->front (true if one is 0 and the other is 1) + // { + // // that means that the edge i of the face is + // // a silhouette edge + // // TESTER D'ABORD SI LE EXACTSILHOUETTEEDGE N'A PAS + // // ETE CONSTRUIT SUR L'AUTRE FACE.(1 suffit) + // if(0 != ((WSExactFace*)bface)->exactSilhouetteEdge()) + // { + // // that means that this silhouette edge has already been built + // return ((WSExactFace*)bface)->exactSilhouetteEdge(); + // } + // // Else we must build it + // WOEdge *woea, *woeb; + // real ta, tb; + // if(!front()) // is it in the right order ? + // { + // // the order of the WOEdge index is wrong + // woea = _OEdgeList[(i+1)%numberOfEdges()]; + // if(0 == i) + // woeb = _OEdgeList[numberOfEdges()-1]; + // else + // woeb = _OEdgeList[(i-1)]; + // ta = 0; + // tb = 1; + // } + // else + // { + // // the order of the WOEdge index is good + // if(0 == i) + // woea = _OEdgeList[numberOfEdges()-1]; + // else + // woea = _OEdgeList[(i-1)]; + // woeb = _OEdgeList[(i+1)%numberOfEdges()]; + // ta = 1; + // tb = 0; + // } + // + // _pSmoothEdge = new ExactSilhouetteEdge(ExactSilhouetteEdge::VERTEX_VERTEX); + // _pSmoothEdge->setWOeA(woea); + // _pSmoothEdge->setWOeA(woeb); + // _pSmoothEdge->setTa(ta); + // _pSmoothEdge->setTb(tb); + // + // return _pSmoothEdge; + // } + // } + //} + return _pSmoothEdge; +} + + +void WXFace::ComputeCenter() +{ + vector<WVertex*> iVertexList; + RetrieveVertexList(iVertexList); + Vec3r center; + for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); + wv!=wvend; + wv++) + { + center += (*wv)->GetVertex(); + } + center /= (real)iVertexList.size(); + setCenter(center); +} + + /**********************************/ + /* */ + /* */ + /* WXShape */ + /* */ + /* */ + /**********************************/ + + +WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex) +{ + WFace *face = WShape::MakeFace(iVertexList, iMaterialIndex); + if(0 == face) + return 0; + + Vec3r center; + for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); + wv!=wvend; + wv++) + { + center += (*wv)->GetVertex(); + } + center /= (real)iVertexList.size(); + ((WXFace*)face)->setCenter(center); + + return face; +} + +WFace * WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, unsigned iMaterialIndex) +{ + WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iMaterialIndex); + + // Vec3r center; + // for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); + // wv!=wvend; + // wv++) + // { + // center += (*wv)->GetVertex(); + // } + // center /= (real)iVertexList.size(); + // ((WSFace*)face)->setCenter(center); + + return face; +} + diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.h b/source/blender/freestyle/intern/winged_edge/WXEdge.h new file mode 100755 index 00000000000..9ec8fd4bddb --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.h @@ -0,0 +1,582 @@ +// +// Filename : WXEdge.h +// Author(s) : Stephane Grabli +// Purpose : Classes to define an Extended Winged Edge data structure. +// Date of creation : 26/10/2003 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef WXEDGE_H +# define WXEDGE_H + +# include "WEdge.h" +# include "Nature.h" +# include "Curvature.h" + +typedef Nature::EdgeNature WXNature; + + /**********************************/ + /* */ + /* */ + /* WXVertex */ + /* */ + /* */ + /**********************************/ + +class WXVertex : public WVertex +{ +private: + // Curvature info + CurvatureInfo *_curvatures; + +public: + inline WXVertex(const Vec3r &v) + : WVertex(v) + {_curvatures = 0;} + /*! Copy constructor */ + WXVertex(WXVertex& iBrother) + : WVertex(iBrother) + {_curvatures = new CurvatureInfo(*iBrother._curvatures);} + virtual WVertex * duplicate() + { + WXVertex *clone = new WXVertex(*this); + return clone; + } + virtual ~WXVertex() {if(_curvatures) delete _curvatures;} + virtual void Reset() {if(_curvatures) _curvatures->Kr = 0.0;} + inline void setCurvatures(CurvatureInfo *ci) {_curvatures = ci;} + + inline bool isFeature(); + inline CurvatureInfo* curvatures() {return _curvatures;} + +}; + + + + /**********************************/ + /* */ + /* */ + /* WXEdge */ + /* */ + /* */ + /**********************************/ +class WXEdge : public WEdge +{ +private: + WXNature _nature; // flag to indicate whether the edge is a silhouette edge or not + int _order; // 0: the order doesn't matter. 1: the order is the orginal one. -1: the order is not good + bool _front; // a front facing edge is an edge for which the bording face which is the nearest + // from the viewpoint is front. A back facing edge is the opposite. + +public: + inline WXEdge() + : WEdge(){ + _nature = Nature::NO_FEATURE; + _front = false; + _order=0; + } + + inline WXEdge(WOEdge *iOEdge) + : WEdge(iOEdge) + { _nature = Nature::NO_FEATURE;_front = false;_order=0;} + + inline WXEdge(WOEdge *iaOEdge, WOEdge *ibOEdge) + : WEdge(iaOEdge, ibOEdge) + { _nature = Nature::NO_FEATURE;_front = false;_order=0;} + + /*! Copy constructor */ + inline WXEdge(WXEdge& iBrother) + : WEdge(iBrother) + {_nature = iBrother.nature();_front = iBrother._front;_order = iBrother._order;} + virtual WEdge * duplicate() + { + WXEdge *clone = new WXEdge(*this); + return clone; + } + + virtual ~WXEdge() + {} + + virtual void Reset(){ + _nature = _nature & ~Nature::SILHOUETTE; + _nature = _nature & ~Nature::SUGGESTIVE_CONTOUR; + } + + /*! accessors */ + inline WXNature nature() {return _nature;} + inline bool front() {return _front;} + inline int order() const {return _order;} + + /*! modifiers */ + inline void setFront(bool iFront) {_front = iFront;} + inline void setNature(WXNature iNature) {_nature = iNature;} + inline void AddNature(WXNature iNature) {_nature = _nature|iNature;} + inline void setOrder(int i) {_order = i;} + +}; + + /**********************************/ + /* */ + /* */ + /* WXFace */ + /* */ + /* */ + /**********************************/ + +/*! Class to store a smooth edge (i.e Hertzman & Zorin smooth silhouette edges) */ +class WXSmoothEdge{ +public: + typedef enum{ + EDGE_EDGE, + VERTEX_EDGE, + EDGE_VERTEX + } Configuration; + + WOEdge *_woea; // Oriented edge from which the silhouette edge starts + WOEdge *_woeb; // Oriented edge where the silhouette edge ends + real _ta; // The silhouette starting point's coordinates are : _woea[0]+ta*(_woea[1]-_woea[0]) + real _tb; // The silhouette ending point's coordinates are : _woeb[0]+ta*(_woeb[1]-_woeb[0]) + bool _front; + Configuration _config; + + WXSmoothEdge(){ + _woea = 0; + _woeb = 0; + _ta = 0; + _tb = 0; + _front = false; + _config = EDGE_EDGE; + } + WXSmoothEdge(const WXSmoothEdge& iBrother){ + _woea = iBrother._woea; + _woeb = iBrother._woeb; + _ta = iBrother._ta; + _tb = iBrother._tb; + _config = iBrother._config; + _front = iBrother._front; + } + ~WXSmoothEdge() {} + + inline WOEdge * woea() {return _woea;} + inline WOEdge * woeb() {return _woeb;} + inline real ta() const {return _ta;} + inline real tb() const {return _tb;} + inline bool front() const {return _front;} + inline Configuration configuration() const {return _config;} + + /*! modifiers */ + inline void setWOeA(WOEdge *iwoea) {_woea = iwoea;} + inline void setWOeB(WOEdge *iwoeb) {_woeb = iwoeb;} + inline void setTa(real ta) {_ta = ta;} + inline void setTb(real tb) {_tb = tb;} + inline void setFront(bool iFront) {_front = iFront;} + inline void setConfiguration(Configuration iConf) {_config = iConf;} + +}; +/* Class to store a value per vertex and a smooth edge. + * The WXFace stores a list of these + */ +class WXFace; +class LIB_WINGED_EDGE_EXPORT WXFaceLayer{ +public: + void * userdata; + WXFace * _pWXFace; + vector<real> _DotP;// in case of silhouette: the values obtained when computing the normal-view direction + // dot product. _DotP[i] is this value for the vertex i for that + // face. + WXSmoothEdge * _pSmoothEdge; + WXNature _Nature; + + //oldtmp values + unsigned _nPosDotP; // count the number of positive dot products for vertices. + // if this number is != 0 and !=_DotP.size() -> it is a silhouette fac + + unsigned _nNullDotP; // count the number of null dot products for vertices. + unsigned _ClosestPointIndex; + bool _viewDependant; + + WXFaceLayer(WXFace *iFace, WXNature iNature, bool viewDependant){ + _pWXFace = iFace; + _pSmoothEdge = 0; + _nPosDotP = 0; + _nNullDotP=0; + _Nature = iNature; + _viewDependant = viewDependant; + userdata = 0; + } + WXFaceLayer(const WXFaceLayer& iBrother){ + _pWXFace = iBrother._pWXFace; + _pSmoothEdge = 0; + _DotP = iBrother._DotP; + _nPosDotP = iBrother._nPosDotP; + _nNullDotP = iBrother._nNullDotP; + _Nature = iBrother._Nature; + if(0 != iBrother._pSmoothEdge) + { + _pSmoothEdge = new WXSmoothEdge(*(iBrother._pSmoothEdge)); + } + _viewDependant = iBrother._viewDependant; + userdata = 0; + } + virtual ~WXFaceLayer() { + if(!_DotP.empty()) + _DotP.clear(); + if(0 != _pSmoothEdge){ + delete _pSmoothEdge; + _pSmoothEdge = 0; + } + } + inline const real dotP(int i) const {return _DotP[i];} + inline unsigned nPosDotP() const {return _nPosDotP;} + inline unsigned nNullDotP() const {return _nNullDotP;} + inline int closestPointIndex() const {return _ClosestPointIndex;} + inline Nature::EdgeNature nature() const {return _Nature;} + inline bool hasSmoothEdge() const {if(_pSmoothEdge) return true; return false;} + inline WXFace * getFace() {return _pWXFace;} + inline WXSmoothEdge * getSmoothEdge() {return _pSmoothEdge;} + inline bool isViewDependant() const {return _viewDependant;} + inline void setClosestPointIndex(int iIndex) {_ClosestPointIndex = iIndex;} + + inline void removeSmoothEdge() { + if(!_DotP.empty()) + _DotP.clear(); + if (_pSmoothEdge) { + delete _pSmoothEdge; + _pSmoothEdge = 0; + } + } + + /*! If one of the face layer vertex has a DotP equal + * to 0, this method returns the vertex where it happens + */ + unsigned int Get0VertexIndex() const ; + + /*! In case one of the edge of the triangle + * is a smooth edge, this method + * allows to retrieve the concerned edge + */ + unsigned int GetSmoothEdgeIndex() const; + /*! retrieves the edges of the triangle for which + * the signs are different (a null value is not considered) for the dotp + * values at each edge extrimity + */ + void RetrieveCuspEdgesIndices(vector<int>& oCuspEdges); + WXSmoothEdge * BuildSmoothEdge(); + inline void setDotP(const vector<real>& iDotP) {_DotP = iDotP;} + inline void PushDotP(real iDotP) { + _DotP.push_back(iDotP); + if(iDotP > 0) + ++_nPosDotP; + if(iDotP == 0) + ++_nNullDotP; + } + inline void ReplaceDotP(unsigned int index, real newDotP){ + _DotP[index] = newDotP; + updateDotPInfos(); + } + inline void updateDotPInfos() { + for(vector<real>::iterator d=_DotP.begin(), dend=_DotP.end(); + d!=dend; + ++d){ + _nPosDotP = 0; + _nNullDotP = 0; + if((*d) > 0) + ++_nPosDotP; + if((*d) == 0) + ++_nNullDotP; + } + } +}; + + +class WXFace : public WFace +{ +protected: + Vec3r _center; // center of the face + real _Z; // distance from viewpoint to the center of the face + bool _front; // flag to tell whether the face is front facing or back facing + real _dotp; // value obtained when computing the normal-viewpoint dot product + + vector<WXFaceLayer*> _SmoothLayers; // The data needed to store one or several smooth edges that traverse the face +public: + inline WXFace() : WFace() {_Z=0.0;_front = false;} + /*! Copy constructor */ + WXFace(WXFace& iBrother) + : WFace(iBrother) + { + _center = iBrother.center(); + _Z = iBrother.Z(); + _front = iBrother.front(); + for(vector<WXFaceLayer*>::iterator wxf = iBrother._SmoothLayers.begin(), wxfend = iBrother._SmoothLayers.end(); + wxf != wxfend; + ++wxf){ + _SmoothLayers.push_back(new WXFaceLayer(**wxf)); + } + } + virtual WFace * duplicate() + { + WXFace * clone = new WXFace(*this); + return clone; + } + + virtual ~WXFace() { + if(!_SmoothLayers.empty()){ + for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf){ + delete (*wxf); + } + _SmoothLayers.clear(); + } + } + + /*! designed to build a specialized WEdge + * for use in MakeEdge + */ + virtual WEdge * instanciateEdge() const {return new WXEdge;} + + /*! accessors */ + inline Vec3r& center() {return _center;} + inline real Z() {return _Z;} + inline bool front() {return _front;} + inline real dotp() {return _dotp;} + inline bool hasSmoothEdges() const { + for(vector<WXFaceLayer*>::const_iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf){ + if( ((*wxf)->hasSmoothEdge())){ + return true; + } + } + return false; + } + vector<WXFaceLayer*>& getSmoothLayers() {return _SmoothLayers;} + /*! retrieve the smooth edges that match the Nature given as argument */ + void retrieveSmoothEdges(WXNature iNature, vector<WXSmoothEdge*>& oSmoothEdges){ + for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf){ + if( ((*wxf)->hasSmoothEdge()) && ((*wxf)->_Nature & iNature) ){ + oSmoothEdges.push_back((*wxf)->_pSmoothEdge); + } + } + } + void retrieveSmoothEdgesLayers(WXNature iNature, vector<WXFaceLayer*>& oSmoothEdgesLayers){ + for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf){ + if( ((*wxf)->hasSmoothEdge()) && ((*wxf)->_Nature & iNature) ){ + oSmoothEdgesLayers.push_back((*wxf)); + } + } + } + void retrieveSmoothLayers(WXNature iNature, vector<WXFaceLayer*>& oSmoothLayers){ + for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf){ + if((*wxf)->_Nature & iNature){ + oSmoothLayers.push_back(*wxf); + } + } + } + /*! modifiers */ + inline void setCenter(const Vec3r& iCenter) {_center = iCenter;} + void ComputeCenter(); + inline void setZ(real z) {_Z = z;} + inline void setFront(bool iFront) {_front = iFront;} + inline void setDotP(real iDotP) + { + _dotp = iDotP; + if(_dotp > 0) + _front = true; + else + _front = false; + } + inline void AddSmoothLayer(WXFaceLayer * iLayer){ + _SmoothLayers.push_back(iLayer); + } + inline void Reset() { + vector<WXFaceLayer*> layersToKeep; + for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf){ + if((*wxf)->isViewDependant()) + delete (*wxf); + else + layersToKeep.push_back(*wxf); + } + _SmoothLayers = layersToKeep; + } + /*! Clears everything */ + inline void Clear() { + for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf){ + delete (*wxf); + } + _SmoothLayers.clear(); + } + virtual void ResetUserData() { + WFace::ResetUserData(); + for(vector<WXFaceLayer*>::iterator wxf = _SmoothLayers.begin(), wxfend = _SmoothLayers.end(); + wxf != wxfend; + ++wxf){ + (*wxf)->userdata = 0; + } + } +}; + + + /**********************************/ + /* */ + /* */ + /* WXShape */ + /* */ + /* */ + /**********************************/ + + +class WXShape : public WShape +{ +public: + typedef WXShape type_name; +protected: + bool _computeViewIndependant; // flag to indicate whether the view independant stuff must be computed or not +public: + inline WXShape() : WShape() {_computeViewIndependant = true;} + /*! copy constructor */ + inline WXShape(WXShape& iBrother) + :WShape(iBrother) + { + _computeViewIndependant = iBrother._computeViewIndependant; + } + virtual WShape * duplicate() + { + WXShape *clone = new WXShape(*this); + return clone; + } + + virtual ~WXShape() + { + } + + inline bool getComputeViewIndependantFlag() const {return _computeViewIndependant;} + inline void setComputeViewIndependantFlag(bool iFlag) {_computeViewIndependant = iFlag;} + + /*! designed to build a specialized WFace + * for use in MakeFace + */ + virtual WFace * instanciateFace() const {return new WXFace;} + + /*! adds a new face to the shape + * returns the built face. + * iVertexList + * List of face's vertices. These vertices are + * not added to the WShape vertex list; they are + * supposed to be already stored when calling MakeFace. + * The order in which the vertices are stored in the list + * determines the face's edges orientation and (so) the + * face orientation. + */ + virtual WFace * MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex); + + /*! adds a new face to the shape. The difference with + * the previous method is that this one is designed + * to build a WingedEdge structure for which there are + * per vertex normals, opposed to per face normals. + * returns the built face. + * iVertexList + * List of face's vertices. These vertices are + * not added to the WShape vertex list; they are + * supposed to be already stored when calling MakeFace. + * The order in which the vertices are stored in the list + * determines the face's edges orientation and (so) the + * face orientation. + * iNormalsList + * The list of normals, iNormalsList[i] corresponding to the + * normal of the vertex iVertexList[i] for that face. + * iTexCoordsList + * The list of tex coords, iTexCoordsList[i] corresponding to the + * normal of the vertex iVertexList[i] for that face. + */ + virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, unsigned iMaterialIndex); + + /*! Reset all edges and vertices flags (which might + * have been set up on a previous pass) + */ + virtual void Reset(){ + // Reset Edges + vector<WEdge*>& wedges = getEdgeList(); + for(vector<WEdge*>::iterator we=wedges.begin(),weend=wedges.end(); + we!=weend; + we++){ + ((WXEdge*)(*we))->Reset(); + } + + //Reset faces: + vector<WFace*>& wfaces = GetFaceList(); + for(vector<WFace*>::iterator wf=wfaces.begin(),wfend=wfaces.end(); + wf!=wfend; + wf++){ + ((WXFace*)(*wf))->Reset(); + } + } + /*! accessors */ +}; + +/* + + ############################################# + ############################################# + ############################################# + ###### ###### + ###### I M P L E M E N T A T I O N ###### + ###### ###### + ############################################# + ############################################# + ############################################# + +*/ +/* for inline functions */ + +bool WXVertex::isFeature() +{ + int counter = 0; + vector<WEdge*>& vedges = GetEdges(); + for(vector<WEdge*>::iterator ve=vedges.begin(), vend=vedges.end(); + ve!=vend; + ve++) + { + if(((WXEdge*)(*ve))->nature() != Nature::NO_FEATURE) + counter++; + } + + if((counter == 1) || (counter > 2)) + return true; + + return false; +} + + +#endif diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp new file mode 100755 index 00000000000..9d22b4f8db5 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp @@ -0,0 +1,43 @@ +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "WXEdgeBuilder.h" +#include "WXEdge.h" + +void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) +{ + WXShape *shape = new WXShape; + buildWShape(*shape, ifs); + shape->setId(ifs.getId().getFirst()); + //ifs.setId(shape->GetId()); +} + +void WXEdgeBuilder::buildWVertices(WShape& shape, + const real *vertices, + unsigned vsize) { + WXVertex *vertex; + for (unsigned i = 0; i < vsize; i += 3) { + vertex = new WXVertex(Vec3r(vertices[i], + vertices[i + 1], + vertices[i + 2])); + vertex->setId(i / 3); + shape.AddVertex(vertex); + } +} diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h new file mode 100755 index 00000000000..b646d66a285 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.h @@ -0,0 +1,51 @@ +#ifndef WXEDGEBUILDER_H +# define WXEDGEBUILDER_H + +// +// Filename : WSBuilder.h +// Author(s) : Stephane Grabli +// Purpose : Class inherited from WingedEdgeBuilder and +// designed to build a WX (WingedEdge + extended info(silhouette etc...)) +// structure from a polygonal model +// Date of creation : 28/05/03 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +# include "WingedEdgeBuilder.h" +# include "../scene_graph/IndexedFaceSet.h" + +class LIB_WINGED_EDGE_EXPORT WXEdgeBuilder : public WingedEdgeBuilder +{ +public: + WXEdgeBuilder() : WingedEdgeBuilder() {} + virtual ~WXEdgeBuilder() {} + VISIT_DECL(IndexedFaceSet) + +protected: + virtual void buildWVertices(WShape& shape, + const real *vertices, + unsigned vsize); +}; + +#endif // WXEDGEBUILDER_H diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp new file mode 100755 index 00000000000..9f3da4707e3 --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp @@ -0,0 +1,362 @@ + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "../geometry/GeomUtils.h" +#include "../scene_graph/NodeShape.h" +#include "WingedEdgeBuilder.h" +#include <set> +using namespace std; + +void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) { + WShape *shape = new WShape; + buildWShape(*shape, ifs); + shape->setId(ifs.getId().getFirst()); + //ifs.setId(shape->GetId()); +} + +void WingedEdgeBuilder::visitNodeShape(NodeShape& ns) { + //Sets the current material to iShapeode->material: + _current_frs_material = &(ns.frs_material()); +} + +void WingedEdgeBuilder::visitNodeTransform(NodeTransform& tn) { + if(!_current_matrix) { + _current_matrix = new Matrix44r(tn.matrix()); + return; + } + + _matrices_stack.push_back(_current_matrix); + Matrix44r *new_matrix = new Matrix44r(*_current_matrix * tn.matrix()); + _current_matrix = new_matrix; +} + +void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) { + if(_current_matrix) + delete _current_matrix; + + if(_matrices_stack.empty()) { + _current_matrix = NULL; + return; + } + + _current_matrix = _matrices_stack.back(); + _matrices_stack.pop_back(); +} + +void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { + unsigned vsize = ifs.vsize(); + unsigned nsize = ifs.nsize(); + //soc unused - unsigned tsize = ifs.tsize(); + + const real* vertices = ifs.vertices(); + const real* normals = ifs.normals(); + const real* texCoords = ifs.texCoords(); + + real* new_vertices; + real* new_normals; + + new_vertices = new real[vsize]; + new_normals = new real[nsize]; + + // transform coordinates from local to world system + if(_current_matrix) { + transformVertices(vertices, vsize, *_current_matrix, new_vertices); + transformNormals(normals, nsize, *_current_matrix, new_normals); + } + else { + memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices)); + memcpy(new_normals, normals, nsize * sizeof(*new_normals)); + } + + const IndexedFaceSet::TRIANGLES_STYLE* faceStyle = ifs.trianglesStyle(); + + vector<FrsMaterial> frs_materials; + if(ifs.msize()){ + const FrsMaterial*const* mats = ifs.frs_materials(); + for(unsigned i=0; i<ifs.msize(); ++i) + frs_materials.push_back(*(mats[i])); + shape.setFrsMaterials(frs_materials); + } + + // const FrsMaterial * mat = (ifs.frs_material()); + // if (mat) + // shape.setFrsMaterial(*mat); + // else if(_current_frs_material) + // shape.setFrsMaterial(*_current_frs_material); + + // sets the current WShape to shape + _current_wshape = &shape; + + // create a WVertex for each vertex + buildWVertices(shape, new_vertices, vsize); + + const unsigned* vindices = ifs.vindices(); + const unsigned* nindices = ifs.nindices(); + const unsigned* tindices = 0; + if(ifs.tsize()){ + tindices = ifs.tindices(); + } + + const unsigned *mindices = 0; + if(ifs.msize()) + mindices = ifs.mindices(); + const unsigned* numVertexPerFace = ifs.numVertexPerFaces(); + const unsigned numfaces = ifs.numFaces(); + + for (unsigned index = 0; index < numfaces; index++) { + switch(faceStyle[index]) { + case IndexedFaceSet::TRIANGLE_STRIP: + buildTriangleStrip(new_vertices, + new_normals, + frs_materials, + texCoords, + vindices, + nindices, + mindices, + tindices, + numVertexPerFace[index]); + break; + case IndexedFaceSet::TRIANGLE_FAN: + buildTriangleFan(new_vertices, + new_normals, + frs_materials, + texCoords, + vindices, + nindices, + mindices, + tindices, + numVertexPerFace[index]); + break; + case IndexedFaceSet::TRIANGLES: + buildTriangles(new_vertices, + new_normals, + frs_materials, + texCoords, + vindices, + nindices, + mindices, + tindices, + numVertexPerFace[index]); + break; + } + vindices += numVertexPerFace[index]; + nindices += numVertexPerFace[index]; + if(mindices) + mindices += numVertexPerFace[index]; + if(tindices) + tindices += numVertexPerFace[index]; + } + + delete[] new_vertices; + delete[] new_normals; + + // compute bbox + shape.ComputeBBox(); + // compute mean edge size: + shape.ComputeMeanEdgeSize(); + + // Parse the built winged-edge shape to update post-flags + set<Vec3r> normalsSet; + vector<WVertex*>& wvertices = shape.getVertexList(); + for(vector<WVertex*>::iterator wv=wvertices.begin(), wvend=wvertices.end(); + wv!=wvend; + ++wv){ + if((*wv)->isBoundary()) + continue; + normalsSet.clear(); + WVertex::face_iterator fit = (*wv)->faces_begin(); + WVertex::face_iterator fitend = (*wv)->faces_end(); + while(fit!=fitend){ + WFace *face = *fit; + normalsSet.insert(face->GetVertexNormal(*wv)); + if(normalsSet.size()!=1){ + break; + } + ++fit; + } + if(normalsSet.size()!=1){ + (*wv)->setSmooth(false); + } + } + // Adds the new WShape to the WingedEdge structure + _winged_edge->addWShape(&shape); +} + +void WingedEdgeBuilder::buildWVertices(WShape& shape, + const real *vertices, + unsigned vsize) { + WVertex *vertex; + for (unsigned i = 0; i < vsize; i += 3) { + vertex = new WVertex(Vec3r(vertices[i], + vertices[i + 1], + vertices[i + 2])); + vertex->setId(i / 3); + shape.AddVertex(vertex); + } +} + +void WingedEdgeBuilder::buildTriangleStrip( const real *vertices, + const real *normals, + vector<FrsMaterial>& iMaterials, + const real *texCoords, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices) { + unsigned nDoneVertices = 2; // number of vertices already treated + unsigned nTriangle = 0; // number of the triangle currently being treated + //int nVertex = 0; // vertex number + + WShape* currentShape = _current_wshape; // the current shape being built + vector<WVertex *> triangleVertices; + vector<Vec3r> triangleNormals; + vector<Vec2r> triangleTexCoords; + + while(nDoneVertices < nvertices) + { + //clear the vertices list: + triangleVertices.clear(); + //Then rebuild it: + if(0 == nTriangle%2) // if nTriangle is even + { + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle]/3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+1]/3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/3]); + + triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2])); + triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]],normals[nindices[nTriangle+1]+1],normals[nindices[nTriangle+1]+2])); + triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]], normals[nindices[nTriangle+2]+1], normals[nindices[nTriangle+2]+2])); + + if(texCoords){ + triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1])); + triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]],texCoords[tindices[nTriangle+1]+1])); + triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]], texCoords[tindices[nTriangle+2]+1])); + } + } + else // if nTriangle is odd + { + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle]/3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+2]/3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle+1]/3]); + + triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]],normals[nindices[nTriangle]+1], normals[nindices[nTriangle]+2])); + triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+2]],normals[nindices[nTriangle+2]+1],normals[nindices[nTriangle+2]+2])); + triangleNormals.push_back(Vec3r(normals[nindices[nTriangle+1]], normals[nindices[nTriangle+1]+1], normals[nindices[nTriangle+1]+2])); + + if(texCoords){ + triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]],texCoords[tindices[nTriangle]+1])); + triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+2]],texCoords[tindices[nTriangle+2]+1])); + triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]], texCoords[tindices[nTriangle+1]+1])); + } + } + if(mindices) + currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, mindices[nTriangle/3]); + else + currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, 0); + nDoneVertices++; // with a strip, each triangle is one vertex more + nTriangle++; + } +} + +void WingedEdgeBuilder::buildTriangleFan( const real *vertices, + const real *normals, + vector<FrsMaterial>& iMaterials, + const real *texCoords, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices) { + // Nothing to be done +} + +void WingedEdgeBuilder::buildTriangles(const real *vertices, + const real *normals, + vector<FrsMaterial>& iMaterials, + const real *texCoords, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices) { + WShape * currentShape = _current_wshape; // the current shape begin built + vector<WVertex *> triangleVertices; + vector<Vec3r> triangleNormals; + vector<Vec2r> triangleTexCoords; + + // Each triplet of vertices is considered as an independent triangle + for(unsigned i = 0; i < nvertices / 3; i++) + { + triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i]/3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i+1]/3]); + triangleVertices.push_back(currentShape->getVertexList()[vindices[3*i+2]/3]); + + triangleNormals.push_back(Vec3r(normals[nindices[3*i]],normals[nindices[3*i]+1], normals[nindices[3*i]+2])); + triangleNormals.push_back(Vec3r(normals[nindices[3*i+1]],normals[nindices[3*i+1]+1],normals[nindices[3*i+1]+2])); + triangleNormals.push_back(Vec3r(normals[nindices[3*i+2]], normals[nindices[3*i+2]+1], normals[nindices[3*i+2]+2])); + + if(texCoords){ + triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i]],texCoords[tindices[3*i]+1])); + triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+1]],texCoords[tindices[3*i+1]+1])); + triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+2]], texCoords[tindices[3*i+2]+1])); + } + } + if(mindices) + currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, mindices[0]); + else + currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords,0); + +} + +void WingedEdgeBuilder::transformVertices(const real *vertices, + unsigned vsize, + const Matrix44r& transform, + real *res) { + const real *v = vertices; + real *pv = res; + + for (unsigned i = 0; i < vsize / 3; i++) { + HVec3r hv_tmp(v[0], v[1], v[2]); + HVec3r hv(transform * hv_tmp); + for (unsigned j = 0; j < 3; j++) + pv[j] = hv[j] / hv[3]; + v += 3; + pv += 3; + } +} + +void WingedEdgeBuilder::transformNormals(const real *normals, + unsigned nsize, + const Matrix44r& transform, + real* res) { + const real *n = normals; + real *pn = res; + + for (unsigned i = 0; i < nsize / 3; i++) { + Vec3r hn(n[0], n[1], n[2]); + hn = GeomUtils::rotateVector(transform, hn); + for (unsigned j = 0; j < 3; j++) + pn[j] = hn[j]; + n += 3; + pn += 3; + } +} diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h new file mode 100755 index 00000000000..6bd515aef0b --- /dev/null +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h @@ -0,0 +1,160 @@ +// +// Filename : WingedEdgeBuilder.h +// Author(s) : Stephane Grabli +// Purpose : Class to render a WingedEdge data structure +// from a polyhedral data structure organized in +// nodes of a scene graph +// Date of creation : 28/05/03 +// +/////////////////////////////////////////////////////////////////////////////// + + +// +// Copyright (C) : Please refer to the COPYRIGHT file distributed +// with this source distribution. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef WINGED_EDGE_BUILDER_H +# define WINGED_EDGE_BUILDER_H + +# include "../system/FreestyleConfig.h" +# include "../scene_graph/SceneVisitor.h" +# include "WEdge.h" +# include "../scene_graph/IndexedFaceSet.h" +# include "../scene_graph/NodeTransform.h" + +class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor +{ + public: + + inline WingedEdgeBuilder() : SceneVisitor() { + _current_wshape = NULL; + _current_frs_material = NULL; + _current_matrix = NULL; + _winged_edge = new WingedEdge; // Not deleted by the destructor + } + + virtual ~WingedEdgeBuilder() { + for (vector<Matrix44r*>::iterator it = _matrices_stack.begin(); + it != _matrices_stack.end(); + it++) + delete *it; + _matrices_stack.clear(); + } + + VISIT_DECL(IndexedFaceSet) + VISIT_DECL(NodeShape) + VISIT_DECL(NodeTransform) + + virtual void visitNodeTransformAfter(NodeTransform&); + + // + // Accessors + // + ///////////////////////////////////////////////////////////////////////////// + + inline WingedEdge* getWingedEdge() { + return _winged_edge; + } + + inline WShape* getCurrentWShape() { + return _current_wshape; + } + + inline FrsMaterial* getCurrentFrsMaterial() { + return _current_frs_material; + } + + inline Matrix44r* getCurrentMatrix() { + return _current_matrix; + } + + // + // Modifiers + // + ///////////////////////////////////////////////////////////////////////////// + + inline void setCurrentWShape(WShape* wshape) { + _current_wshape = wshape; + } + + inline void setCurrentFrsMaterial(FrsMaterial* mat) { + _current_frs_material = mat; + } + + // inline void setCurrentMatrix(Matrix44r* matrix) { + // _current_matrix = matrix; + // } + + protected: + + virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs); + virtual void buildWVertices(WShape& shape, + const real *vertices, + unsigned vsize); + + private: + + void buildTriangleStrip(const real *vertices, + const real *normals, + vector<FrsMaterial>& iMaterials, + const real *texCoords, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices); + + void buildTriangleFan(const real *vertices, + const real *normals, + vector<FrsMaterial>& iMaterials, + const real *texCoords, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices); + + void buildTriangles(const real *vertices, + const real *normals, + vector<FrsMaterial>& iMaterials, + const real *texCoords, + const unsigned *vindices, + const unsigned *nindices, + const unsigned *mindices, + const unsigned *tindices, + const unsigned nvertices); + + void transformVertices(const real *vertices, + unsigned vsize, + const Matrix44r& transform, + real *res); + + void transformNormals(const real *normals, + unsigned nsize, + const Matrix44r& transform, + real *res); + + WShape* _current_wshape; + FrsMaterial* _current_frs_material; + WingedEdge* _winged_edge; + Matrix44r* _current_matrix; + vector<Matrix44r*> _matrices_stack; +}; + +#endif // WINGED_EDGE_BUILDER_H diff --git a/source/blender/makesdna/DNA_freestyle_types.h b/source/blender/makesdna/DNA_freestyle_types.h new file mode 100644 index 00000000000..fb07f33b533 --- /dev/null +++ b/source/blender/makesdna/DNA_freestyle_types.h @@ -0,0 +1,31 @@ +#ifndef DNA_FREESTYLE_TYPES_H +#define DNA_FREESTYLE_TYPES_H + +#include "DNA_listBase.h" + +#define FREESTYLE_SUGGESTIVE_CONTOURS_FLAG 1 +#define FREESTYLE_RIDGES_AND_VALLEYS_FLAG 2 + +typedef struct FreestyleModuleConfig { + struct FreestyleModuleConfig *next, *prev; + + char module_path[256]; + short is_displayed; + short pad[3]; + +} FreestyleModuleConfig; + +typedef struct FreestyleConfig { + ListBase modules; + + int flags; + float sphere_radius; + float dkr_epsilon; + int pad; + +} FreestyleConfig; + + + +#endif + diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index fa6cddd8227..3b516eeb0a7 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -158,7 +158,7 @@ typedef struct Material { short sss_flag, sss_preset; int mapto_textured; /* render-time cache to optimise texture lookups */ - int pad4; + short vcol_alpha, pad4; ListBase gpumaterial; /* runtime */ } Material; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index ef6202c5faa..df7035146e3 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -40,6 +40,7 @@ extern "C" { #include "DNA_vec_types.h" #include "DNA_listBase.h" #include "DNA_ID.h" +#include "DNA_freestyle_types.h" struct Object; struct World; @@ -152,6 +153,9 @@ typedef struct SceneRenderLayer { int passflag; /* pass_xor has to be after passflag */ int pass_xor; + + struct FreestyleConfig freestyleConfig; + } SceneRenderLayer; /* srl->layflag */ @@ -161,6 +165,7 @@ typedef struct SceneRenderLayer { #define SCE_LAY_EDGE 8 #define SCE_LAY_SKY 16 #define SCE_LAY_STRAND 32 +#define SCE_LAY_FRS 64 /* flags between 32 and 0x8000 are set to 1 already, for future options */ #define SCE_LAY_ALL_Z 0x8000 @@ -787,6 +792,11 @@ typedef struct Scene { /* Physics simulation settings */ struct PhysicsSettings physics_settings; + + /* Freestyle */ + short freestyle_current_layer_number; + short pad[3]; + } Scene; @@ -834,6 +844,7 @@ typedef struct Scene { #define R_NO_OVERWRITE 0x400000 /* skip existing files */ #define R_TOUCH 0x800000 /* touch files before rendering */ #define R_SIMPLIFY 0x1000000 +#define R_EDGE_FRS 0x2000000 /* R_EDGE for Freestyle */ /* displaymode */ diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 2d62b81e81b..9379fdf7288 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -133,6 +133,7 @@ char *includefiles[] = { "DNA_anim_types.h", "DNA_boid_types.h", "DNA_smoke_types.h", + "DNA_freestyle_types.h", // empty string to indicate end of includefiles "" @@ -1177,4 +1178,5 @@ int main(int argc, char ** argv) #include "DNA_anim_types.h" #include "DNA_boid_types.h" #include "DNA_smoke_types.h" +#include "DNA_freestyle_types.h" /* end of list */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 1d153e85968..4821ea2d569 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -218,6 +218,7 @@ extern StructRNA RNA_FModifierLimits; extern StructRNA RNA_FModifierNoise; extern StructRNA RNA_FModifierPython; extern StructRNA RNA_FollowPathConstraint; +extern StructRNA RNA_FreestyleModuleSettings; extern StructRNA RNA_Function; extern StructRNA RNA_GameBooleanProperty; extern StructRNA RNA_GameFloatProperty; diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 31183cf08b6..002494504b6 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -235,52 +235,42 @@ static PointerRNA rna_Test_test_get(PointerRNA *ptr) #else -/* local convenience types */ -typedef void (CollectionDefFunc)(struct BlenderRNA *brna, struct PropertyRNA *cprop); - -typedef struct MainCollectionDef { - const char *identifier; - const char *type; - const char *iter_begin; - const char *name; - const char *description; - CollectionDefFunc *func; -} MainCollectionDef; +typedef void (*CollectionDefFunc)(struct BlenderRNA *brna, struct PropertyRNA *cprop); void RNA_def_main(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - CollectionDefFunc *func; - - MainCollectionDef lists[]= { - {"cameras", "Camera", "rna_Main_camera_begin", "Cameras", "Camera datablocks.", RNA_def_main_cameras}, - {"scenes", "Scene", "rna_Main_scene_begin", "Scenes", "Scene datablocks.", RNA_def_main_scenes}, - {"objects", "Object", "rna_Main_object_begin", "Objects", "Object datablocks.", RNA_def_main_objects}, - {"materials", "Material", "rna_Main_mat_begin", "Materials", "Material datablocks.", RNA_def_main_materials}, - {"node_groups", "NodeTree", "rna_Main_nodetree_begin", "Node Groups", "Node group datablocks.", RNA_def_main_node_groups}, - {"meshes", "Mesh", "rna_Main_mesh_begin", "Meshes", "Mesh datablocks.", RNA_def_main_meshes}, - {"lamps", "Lamp", "rna_Main_lamp_begin", "Lamps", "Lamp datablocks.", RNA_def_main_lamps}, - {"libraries", "Library", "rna_Main_library_begin", "Libraries", "Library datablocks.", RNA_def_main_libraries}, - {"screens", "Screen", "rna_Main_screen_begin", "Screens", "Screen datablocks.", RNA_def_main_screens}, - {"window_managers", "WindowManager", "rna_Main_wm_begin", "Window Managers", "Window manager datablocks.", RNA_def_main_window_managers}, - {"images", "Image", "rna_Main_image_begin", "Images", "Image datablocks.", RNA_def_main_images}, - {"lattices", "Lattice", "rna_Main_latt_begin", "Lattices", "Lattice datablocks.", RNA_def_main_lattices}, - {"curves", "Curve", "rna_Main_curve_begin", "Curves", "Curve datablocks.", RNA_def_main_curves} , - {"metaballs", "MetaBall", "rna_Main_mball_begin", "Metaballs", "Metaball datablocks.", RNA_def_main_metaballs}, - {"vfonts", "VectorFont", "rna_Main_vfont_begin", "Vector Fonts", "Vector font datablocks.", RNA_def_main_vfonts}, - {"textures", "Texture", "rna_Main_tex_begin", "Textures", "Texture datablocks.", RNA_def_main_textures}, - {"brushes", "Brush", "rna_Main_brush_begin", "Brushes", "Brush datablocks.", RNA_def_main_brushes}, - {"worlds", "World", "rna_Main_world_begin", "Worlds", "World datablocks.", RNA_def_main_worlds}, - {"groups", "Group", "rna_Main_group_begin", "Groups", "Group datablocks.", RNA_def_main_groups}, + CollectionDefFunc func; + + const char *lists[][6]= { + {"cameras", "Camera", "rna_Main_camera_begin", "Cameras", "Camera datablocks.", (char *)RNA_def_main_cameras}, + {"scenes", "Scene", "rna_Main_scene_begin", "Scenes", "Scene datablocks.", (char *)RNA_def_main_scenes}, + {"objects", "Object", "rna_Main_object_begin", "Objects", "Object datablocks.", (char *)RNA_def_main_objects}, + {"materials", "Material", "rna_Main_mat_begin", "Materials", "Material datablocks.", (char *)RNA_def_main_materials}, + {"node_groups", "NodeTree", "rna_Main_nodetree_begin", "Node Groups", "Node group datablocks.", (char *)RNA_def_main_node_groups}, + {"meshes", "Mesh", "rna_Main_mesh_begin", "Meshes", "Mesh datablocks.", (char *)RNA_def_main_meshes}, + {"lamps", "Lamp", "rna_Main_lamp_begin", "Lamps", "Lamp datablocks.", (char *)RNA_def_main_lamps}, + {"libraries", "Library", "rna_Main_library_begin", "Libraries", "Library datablocks.", (char *)RNA_def_main_libraries}, + {"screens", "Screen", "rna_Main_screen_begin", "Screens", "Screen datablocks.", (char *)RNA_def_main_screens}, + {"window_managers", "WindowManager", "rna_Main_wm_begin", "Window Managers", "Window manager datablocks.", (char *)RNA_def_main_window_managers}, + {"images", "Image", "rna_Main_image_begin", "Images", "Image datablocks.", (char *)RNA_def_main_images}, + {"lattices", "Lattice", "rna_Main_latt_begin", "Lattices", "Lattice datablocks.", (char *)RNA_def_main_lattices}, + {"curves", "Curve", "rna_Main_curve_begin", "Curves", "Curve datablocks.", (char *)RNA_def_main_curves} , + {"metaballs", "MetaBall", "rna_Main_mball_begin", "Metaballs", "Metaball datablocks.", (char *)RNA_def_main_metaballs}, + {"vfonts", "VectorFont", "rna_Main_vfont_begin", "Vector Fonts", "Vector font datablocks.", (char *)RNA_def_main_vfonts}, + {"textures", "Texture", "rna_Main_tex_begin", "Textures", "Texture datablocks.", (char *)RNA_def_main_textures}, + {"brushes", "Brush", "rna_Main_brush_begin", "Brushes", "Brush datablocks.", (char *)RNA_def_main_brushes}, + {"worlds", "World", "rna_Main_world_begin", "Worlds", "World datablocks.", (char *)RNA_def_main_worlds}, + {"groups", "Group", "rna_Main_group_begin", "Groups", "Group datablocks.", (char *)RNA_def_main_groups}, /* {"keys", "Key", "rna_Main_key_begin", "Keys", "Key datablocks.", NULL}, */ - {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks (DEPRECATED).", NULL}, - {"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks.", RNA_def_main_texts}, - {"sounds", "Sound", "rna_Main_sound_begin", "Sounds", "Sound datablocks.", RNA_def_main_sounds}, - {"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks.", RNA_def_main_armatures}, - {"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks.", RNA_def_main_actions}, - {"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks.", RNA_def_main_particles}, - {"gpencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks.", RNA_def_main_gpencil}, + {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks (DEPRECATED).", (char *)NULL}, + {"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks.", (char *)RNA_def_main_texts}, + {"sounds", "Sound", "rna_Main_sound_begin", "Sounds", "Sound datablocks.", (char *)RNA_def_main_sounds}, + {"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks.", (char *)RNA_def_main_armatures}, + {"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks.", (char *)RNA_def_main_actions}, + {"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks.", (char *)RNA_def_main_particles}, + {"gpencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks.", (char *)RNA_def_main_gpencil}, {NULL, NULL, NULL, NULL, NULL, NULL}}; int i; @@ -295,15 +285,15 @@ void RNA_def_main(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Filename", "Path to the .blend file"); - for(i=0; lists[i].name; i++) + for(i=0; lists[i][0]; i++) { - prop= RNA_def_property(srna, lists[i].identifier, PROP_COLLECTION, PROP_NONE); - RNA_def_property_struct_type(prop, lists[i].type); - RNA_def_property_collection_funcs(prop, lists[i].iter_begin, "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0); - RNA_def_property_ui_text(prop, lists[i].name, lists[i].description); + prop= RNA_def_property(srna, lists[i][0], PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, lists[i][1]); + RNA_def_property_collection_funcs(prop, lists[i][2], "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0); + RNA_def_property_ui_text(prop, lists[i][3], lists[i][4]); /* collection functions */ - func= lists[i].func; + func= (CollectionDefFunc *)lists[i][5]; if(func) func(brna, prop); } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 5f1e3acc347..b1a8ecedb8c 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1108,6 +1108,12 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + prop= RNA_def_property(srna, "freestyle", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "layflag", SCE_LAY_FRS); + RNA_def_property_ui_text(prop, "Freestyle", "Render stylized strokes in this Layer."); + if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + else RNA_def_property_clear_flag(prop, PROP_EDITABLE); + /* passes */ prop= RNA_def_property(srna, "pass_combined", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_COMBINED); @@ -1260,6 +1266,62 @@ void rna_def_render_layer_common(StructRNA *srna, int scene) else RNA_def_property_clear_flag(prop, PROP_EDITABLE); } +static void rna_def_freestyle_settings(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + /* FreestyleModuleSettings */ + + srna= RNA_def_struct(brna, "FreestyleModuleSettings", NULL); + RNA_def_struct_sdna(srna, "FreestyleModuleConfig"); + RNA_def_struct_ui_text(srna, "Freestyle Module", "Style module configuration for specifying a style module."); + + prop= RNA_def_property(srna, "module_path", PROP_STRING, PROP_FILEPATH); + RNA_def_property_string_sdna(prop, NULL, "module_path"); + RNA_def_property_ui_text(prop, "Module Path", "Path to a style module file."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "is_displayed", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "is_displayed", 1); + RNA_def_property_ui_text(prop, "Is Displayed", "Enable this style module during the rendering."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + /* FreestyleSettings */ + + srna= RNA_def_struct(brna, "FreestyleSettings", NULL); + RNA_def_struct_sdna(srna, "FreestyleConfig"); + RNA_def_struct_nested(brna, srna, "SceneRenderLayer"); + RNA_def_struct_ui_text(srna, "Frestyle Settings", "Freestyle settings for a SceneRenderLayer datablock."); + + prop= RNA_def_property(srna, "modules", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "modules", NULL); + RNA_def_property_struct_type(prop, "FreestyleModuleSettings"); + RNA_def_property_ui_text(prop, "Style modules", "A list of style modules (to be applied from top to bottom)."); + + prop= RNA_def_property(srna, "suggestive_contours", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_SUGGESTIVE_CONTOURS_FLAG); + RNA_def_property_ui_text(prop, "Suggestive Contours", "Enable suggestive contours."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "ridges_and_valleys", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_RIDGES_AND_VALLEYS_FLAG); + RNA_def_property_ui_text(prop, "Ridges and Valleys", "Enable ridges and valleys."); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "sphere_radius", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "sphere_radius"); + RNA_def_property_range(prop, 0.0, 1000.0); + RNA_def_property_ui_text(prop, "Sphere Radius", "*TBD*"); + RNA_def_property_update(prop, NC_SCENE, NULL); + + prop= RNA_def_property(srna, "dkr_epsilon", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "dkr_epsilon"); + RNA_def_property_range(prop, 0.0, 1000.0); + RNA_def_property_ui_text(prop, "Dkr Epsilon", "*TBD*"); + RNA_def_property_update(prop, NC_SCENE, NULL); +} + static void rna_def_scene_game_data(BlenderRNA *brna) { StructRNA *srna; @@ -1552,11 +1614,22 @@ static void rna_def_scene_game_data(BlenderRNA *brna) static void rna_def_scene_render_layer(BlenderRNA *brna) { StructRNA *srna; + PropertyRNA *prop; srna= RNA_def_struct(brna, "SceneRenderLayer", NULL); RNA_def_struct_ui_text(srna, "Scene Render Layer", "Render layer"); rna_def_render_layer_common(srna, 1); + + /* Freestyle */ + + rna_def_freestyle_settings(brna); + + prop= RNA_def_property(srna, "freestyle_settings", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "freestyleConfig"); + RNA_def_property_struct_type(prop, "FreestyleSettings"); + RNA_def_property_ui_text(prop, "Freestyle Settings", ""); } static void rna_def_scene_render_data(BlenderRNA *brna) @@ -2169,6 +2242,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Edge Color", ""); RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + prop= RNA_def_property(srna, "freestyle", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode", R_EDGE_FRS); + RNA_def_property_ui_text(prop, "Edge", "Draw stylized strokes using Freestyle."); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + prop= RNA_def_property(srna, "threads", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "threads"); RNA_def_property_range(prop, 1, BLENDER_MAX_THREADS); @@ -2844,6 +2922,12 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_struct_type(prop, "GreasePencil"); RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil datablock"); + + /* Freestyle */ + prop= RNA_def_property(srna, "freestyle_current_layer_number", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "freestyle_current_layer_number"); + RNA_def_property_ui_text(prop, "Freestyle Current Layer Number", "Number of current layers in Freestyle."); + RNA_def_property_update(prop, NC_SCENE, NULL); /* Transform Orientations */ prop= RNA_def_property(srna, "orientations", PROP_COLLECTION, PROP_NONE); diff --git a/source/blender/python/CMakeLists.txt b/source/blender/python/CMakeLists.txt index 3c79e9d3056..39c28fe2b94 100644 --- a/source/blender/python/CMakeLists.txt +++ b/source/blender/python/CMakeLists.txt @@ -35,6 +35,7 @@ SET(INC ../blenkernel ../windowmanager ../editors/include + ../freestyle/intern/python ../../../intern/guardedalloc ${PYTHON_INC} ) diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index ca742a3646a..b4ce9898b1b 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -5,6 +5,7 @@ sources = env.Glob('intern/*.c') incs = '. ../editors/include ../makesdna ../makesrna ../blenlib ../blenkernel ../nodes' incs += ' ../imbuf ../blenloader ../render/extern/include ../windowmanager' +incs += ' ../freestyle/intern/python' incs += ' #intern/guardedalloc #intern/memutil #extern/glew/include' incs += ' ' + env['BF_PYTHON_INC'] diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 43accf939aa..5f94966b416 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -40,6 +40,8 @@ #include "../generic/BGL.h" #include "../generic/IDProp.h" +#include "BPy_Freestyle.h" + static char bpy_home_paths_doc[] = ".. function:: home_paths(subfolder)\n" "\n" @@ -107,6 +109,7 @@ void BPy_init_modules( void ) Mathutils_Init(); BGL_Init(); IDProp_Init_Types(); + Freestyle_Init(); mod = PyModule_New("_bpy"); diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index 5dc89af5632..2f029feec2f 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -29,7 +29,7 @@ FILE(GLOB SRC intern/source/*.c intern/raytrace/*.cpp) SET(INC intern/include ../../../intern/guardedalloc ../blenlib ../makesdna extern/include ../blenkernel ../imbuf - ../include ../../kernel/gen_messaging ../blenloader + ../include ../../kernel/gen_messaging ../blenloader ../freestyle ../../../intern/smoke/extern ../makesrna ) diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 366f6bd723c..7f80731e26d 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -6,7 +6,7 @@ raysources = env.Glob('intern/raytrace/*.cpp') incs = 'intern/include #/intern/guardedalloc ../blenlib ../makesdna ../makesrna' incs += ' extern/include ../blenkernel ../radiosity/extern/include ../imbuf' -incs += ' ../include ../blenloader ../../../intern/smoke/extern' +incs += ' ../include ../blenloader ../freestyle ../../../intern/smoke/extern' cflags = env['CCFLAGS'] cxxflags = env['CXXFLAGS'] diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 0122f1b5d65..a5b3b1dd18c 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -67,6 +67,9 @@ #include "RE_pipeline.h" +#include "FRS_freestyle.h" +#include "FRS_freestyle_config.h" + /* internal */ #include "render_types.h" #include "renderpipeline.h" @@ -654,6 +657,7 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int rl->lay= (1<<20) -1; rl->layflag= 0x7FFF; /* solid ztra halo strand */ rl->passflag= SCE_PASS_COMBINED; + FRS_add_freestyle_config( srl ); re->r.actlay= 0; } @@ -1871,6 +1875,11 @@ static void do_render_3d(Render *re) if(!re->test_break(re->tbh)) add_halo_flare(re); + /* Freestyle */ + if( re->r.mode & R_EDGE_FRS && re->r.renderer==R_INTERN) + if(!re->test_break(re->tbh)) + FRS_add_Freestyle(re); + /* free all render verts etc */ RE_Database_Free(re); } diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 60d003f3c21..bbb056648f6 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -1049,6 +1049,7 @@ void shade_input_set_shade_texco(ShadeInput *shi) shi->actcol= obr->actmcol; if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP)) { + float alpha[8]; for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)); i++) { ShadeInputCol *scol= &shi->col[i]; char *cp1, *cp2, *cp3; @@ -1063,13 +1064,15 @@ void shade_input_set_shade_texco(ShadeInput *shi) scol->col[0]= (l*((float)cp3[3]) - u*((float)cp1[3]) - v*((float)cp2[3]))/255.0f; scol->col[1]= (l*((float)cp3[2]) - u*((float)cp1[2]) - v*((float)cp2[2]))/255.0f; scol->col[2]= (l*((float)cp3[1]) - u*((float)cp1[1]) - v*((float)cp2[1]))/255.0f; + + alpha[i]= (l*((float)cp3[0]) - u*((float)cp1[0]) - v*((float)cp2[0]))/255.0f; } if(shi->totcol) { shi->vcol[0]= shi->col[shi->actcol].col[0]; shi->vcol[1]= shi->col[shi->actcol].col[1]; shi->vcol[2]= shi->col[shi->actcol].col[2]; - shi->vcol[3]= 1.0f; + shi->vcol[3]= shi->mat->vcol_alpha ? alpha[shi->actcol] : 1.0f; } else { shi->vcol[0]= 0.0f; diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 7ba6a889ffc..809de09a5b9 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1590,7 +1590,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) shi->r= shi->vcol[0]; shi->g= shi->vcol[1]; shi->b= shi->vcol[2]; - if(ma->mode & (MA_FACETEXTURE_ALPHA)) + if((ma->mode & (MA_FACETEXTURE_ALPHA)) || ma->vcol_alpha) shi->alpha= shi->vcol[3]; } if(ma->texco) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 1afae47e21f..f75ac300086 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -43,6 +43,7 @@ INCLUDE_DIRECTORIES(../../intern/guardedalloc ../blender/render/extern/include ../blender/makesdna ../blender/gpu + ../blender/freestyle ../blender/windowmanager ../kernel/gen_messaging ../kernel/gen_system @@ -359,6 +360,7 @@ ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") SET(BLENDER_SORTED_LIBS bf_windowmanager bf_editors + bf_freestyle bf_decimation blender_BSP bf_ghost diff --git a/source/creator/SConscript b/source/creator/SConscript index 8c71e0e8566..da32370ad74 100644 --- a/source/creator/SConscript +++ b/source/creator/SConscript @@ -8,7 +8,7 @@ incs = '#/intern/guardedalloc ../blender/blenlib ../blender/blenkernel' incs += ' ../blender/editors/include ../blender/blenloader ../blender/imbuf' incs += ' ../blender/renderconverter ../blender/render/extern/include ../blender/windowmanager' incs += ' ../blender/makesdna ../blender/makesrna ../kernel/gen_messaging' -incs += ' ../kernel/gen_system #/extern/glew/include ../blender/gpu' +incs += ' ../kernel/gen_system #/extern/glew/include ../blender/gpu ../blender/freestyle' incs += ' ' + env['BF_OPENGL_INC'] defs = [] diff --git a/source/creator/creator.c b/source/creator/creator.c index 906f6e67a84..929a3ff0655 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -90,6 +90,8 @@ #include "GPU_draw.h" #include "GPU_extensions.h" +#include "FRS_freestyle.h" + /* for passing information between creator and gameengine */ #include "SYS_System.h" @@ -1022,6 +1024,10 @@ int main(int argc, char **argv) printf("Example: setenv BF_TIFF_LIB /usr/lib/libtiff.so\n"); } + /* initialize Freestyle */ + FRS_initialize(); + FRS_set_context(C); + /* OK we are ready for it */ BLI_argsParse(ba, 4, load_file, C); |