forked from bartvdbraak/blender
Part one of editmesh.c refactoring. The huge file has been split in
logical parts, and include files altered to denote internal and external functions. include/editmesh.h: internal calls for editmesh_xxx.c files include/BIF_editmesh.h: external calls for these files src/editmesh.c: basic alloc/lists and in/out editmode, undo, separate src/editmesh_lib.c: basic utility calls for all editmesh_xxx.c (no UI) src/editmesh_add.c: add prim, add duplicate, add vertex/edge/face (UI) src/editmesh_mods.c: selecting, transforming (UI) src/editmesh_loop.c: loop tools like knife, loop select, loop subdiv (UI) src/editmesh_tools.c: other tools (extrude, spin, etc) (UI) And a new file: src/meshtools.c: tools for Mesh outside of editmode (normals, draw flags)
This commit is contained in:
parent
dab46067bf
commit
ca5b7386e5
@ -30,6 +30,8 @@
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/* External for editmesh_xxxx.c functions */
|
||||
|
||||
#ifndef BIF_EDITMESH_H
|
||||
#define BIF_EDITMESH_H
|
||||
|
||||
@ -40,117 +42,13 @@ struct Mesh;
|
||||
struct bDeformGroup;
|
||||
struct View3D;
|
||||
|
||||
void free_hashedgetab(void);
|
||||
void fasterdraw(void);
|
||||
void slowerdraw(void);
|
||||
void vertexnoise(void);
|
||||
void vertexsmooth(void);
|
||||
void make_sticky(void);
|
||||
void deselectall_mesh(void);
|
||||
/* ******************* editmesh.c */
|
||||
extern void make_editMesh(void);
|
||||
extern void load_editMesh(void);
|
||||
extern void free_editMesh(void);
|
||||
extern void remake_editMesh(void);
|
||||
|
||||
/* For Knife subdivide */
|
||||
typedef struct CutCurve {
|
||||
short x;
|
||||
short y;
|
||||
} CutCurve;
|
||||
|
||||
void KnifeSubdivide(char mode);
|
||||
#define KNIFE_PROMPT 0
|
||||
#define KNIFE_EXACT 1
|
||||
#define KNIFE_MIDPOINT 2
|
||||
|
||||
CutCurve *get_mouse_trail(int * length, char mode);
|
||||
#define TRAIL_POLYLINE 1 /* For future use, They don't do anything yet */
|
||||
#define TRAIL_FREEHAND 2
|
||||
#define TRAIL_MIXED 3 /* (1|2) */
|
||||
#define TRAIL_AUTO 4
|
||||
#define TRAIL_MIDPOINTS 8
|
||||
|
||||
short seg_intersect(struct EditEdge * e, CutCurve *c, int len);
|
||||
|
||||
void LoopMenu(void);
|
||||
/* End Knife Subdiv */
|
||||
|
||||
/** Aligns the selected TFace's of @a me to the @a v3d,
|
||||
* using the given axis (0-2). Can give a user error.
|
||||
*/
|
||||
void faceselect_align_view_to_selected(struct View3D *v3d, struct Mesh *me, int axis);
|
||||
/** Aligns the selected faces or vertices of @a me to the @a v3d,
|
||||
* using the given axis (0-2). Can give a user error.
|
||||
*/
|
||||
void editmesh_align_view_to_selected(struct View3D *v3d, int axis);
|
||||
|
||||
struct EditVert *addvertlist(float *vec);
|
||||
struct EditEdge *addedgelist(struct EditVert *v1, struct EditVert *v2, struct EditEdge *example);
|
||||
struct EditFace *addfacelist(struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example);
|
||||
struct EditEdge *findedgelist(struct EditVert *v1, struct EditVert *v2);
|
||||
|
||||
void remedge(struct EditEdge *eed);
|
||||
|
||||
int faceselectedAND(struct EditFace *efa, int flag);
|
||||
|
||||
void recalc_editnormals(void);
|
||||
void flip_editnormals(void);
|
||||
void vertexnormals(int testflip);
|
||||
/* this is currently only used by the python NMesh module: */
|
||||
void vertexnormals_mesh(struct Mesh *me, float *extverts);
|
||||
|
||||
void make_editMesh(void);
|
||||
void load_editMesh(void);
|
||||
void free_editMesh(void);
|
||||
void remake_editMesh(void);
|
||||
|
||||
void convert_to_triface(int all);
|
||||
|
||||
void righthandfaces(int select);
|
||||
|
||||
void mouse_mesh(void);
|
||||
|
||||
void selectconnected_mesh(int qual);
|
||||
short extrudeflag(short flag,short type);
|
||||
void rotateflag(short flag, float *cent, float rotmat[][3]);
|
||||
void translateflag(short flag, float *vec);
|
||||
short removedoublesflag(short flag, float limit);
|
||||
void xsortvert_flag(int flag);
|
||||
void hashvert_flag(int flag);
|
||||
void subdivideflag(int flag, float rad, int beauty);
|
||||
void adduplicateflag(int flag);
|
||||
void extrude_mesh(void);
|
||||
void adduplicate_mesh(void);
|
||||
void split_mesh(void);
|
||||
|
||||
void separatemenu(void);
|
||||
void separate_mesh(void);
|
||||
void separate_mesh_loose(void);
|
||||
|
||||
void loopoperations(char mode);
|
||||
#define LOOP_SELECT 1
|
||||
#define LOOP_CUT 2
|
||||
|
||||
void vertex_loop_select(void);
|
||||
void edge_select(void);
|
||||
|
||||
void extrude_repeat_mesh(int steps, float offs);
|
||||
void spin_mesh(int steps,int degr,float *dvec, int mode);
|
||||
void screw_mesh(int steps,int turns);
|
||||
void selectswap_mesh(void);
|
||||
void addvert_mesh(void);
|
||||
void addedgeface_mesh(void);
|
||||
void delete_mesh(void);
|
||||
void add_primitiveMesh(int type);
|
||||
void hide_mesh(int swap);
|
||||
void reveal_mesh(void);
|
||||
void beauty_fill(void);
|
||||
void join_triangles(void);
|
||||
void edge_flip(void);
|
||||
void join_mesh(void);
|
||||
void sort_faces(void);
|
||||
void vertices_to_sphere(void);
|
||||
void fill_mesh(void);
|
||||
|
||||
void bevel_menu();
|
||||
|
||||
/* Editmesh Undo code */
|
||||
/* Editmesh Undo code */
|
||||
void undo_free_mesh(struct Mesh *me);
|
||||
void undo_push_mesh(char *name);
|
||||
void undo_pop_mesh(int steps);
|
||||
@ -158,21 +56,90 @@ void undo_redo_mesh(void);
|
||||
void undo_clear_mesh(void);
|
||||
void undo_menu_mesh(void);
|
||||
|
||||
/* Selection */
|
||||
void select_non_manifold(void);
|
||||
void select_more(void);
|
||||
void select_less(void);
|
||||
void selectrandom_mesh(void);
|
||||
extern void separatemenu(void);
|
||||
extern void separate_mesh(void);
|
||||
extern void separate_mesh_loose(void);
|
||||
|
||||
void Edge_Menu(void);
|
||||
/* ******************* editmesh_add.c */
|
||||
extern void add_primitiveMesh(int type);
|
||||
extern void adduplicate_mesh(void);
|
||||
extern void addvert_mesh(void);
|
||||
extern void addedgeface_mesh(void);
|
||||
|
||||
void editmesh_select_by_material(int index);
|
||||
void editmesh_deselect_by_material(int index);
|
||||
/* ******************* editmesh_lib.c */
|
||||
extern int faceselectedAND(struct EditFace *efa, int flag);
|
||||
extern void recalc_editnormals(void);
|
||||
extern void flip_editnormals(void);
|
||||
extern void vertexnormals(int testflip);
|
||||
|
||||
void editmesh_mark_seam(int clear);
|
||||
/* ******************* editmesh_mods.c */
|
||||
extern void vertexnoise(void);
|
||||
extern void vertexsmooth(void);
|
||||
extern void righthandfaces(int select);
|
||||
extern void mouse_mesh(void);
|
||||
|
||||
extern void deselectall_mesh(void);
|
||||
extern void selectconnected_mesh(int qual);
|
||||
extern void selectswap_mesh(void);
|
||||
|
||||
extern void hide_mesh(int swap);
|
||||
extern void reveal_mesh(void);
|
||||
|
||||
extern void vertices_to_sphere(void);
|
||||
|
||||
/** Aligns the selected TFace's of @a me to the @a v3d,
|
||||
* using the given axis (0-2). Can give a user error.
|
||||
*/
|
||||
extern void faceselect_align_view_to_selected(struct View3D *v3d, struct Mesh *me, int axis);
|
||||
/** Aligns the selected faces or vertices of @a me to the @a v3d,
|
||||
* using the given axis (0-2). Can give a user error.
|
||||
*/
|
||||
extern void editmesh_align_view_to_selected(struct View3D *v3d, int axis);
|
||||
|
||||
/* Selection */
|
||||
extern void select_non_manifold(void);
|
||||
extern void select_more(void);
|
||||
extern void select_less(void);
|
||||
extern void selectrandom_mesh(void);
|
||||
extern void editmesh_select_by_material(int index);
|
||||
extern void editmesh_deselect_by_material(int index);
|
||||
|
||||
extern void Edge_Menu(void);
|
||||
extern void editmesh_mark_seam(int clear);
|
||||
|
||||
/* ******************* editmesh_loop.c */
|
||||
|
||||
#define KNIFE_PROMPT 0
|
||||
#define KNIFE_EXACT 1
|
||||
#define KNIFE_MIDPOINT 2
|
||||
|
||||
extern void KnifeSubdivide(char mode);
|
||||
extern void LoopMenu(void);
|
||||
|
||||
#define LOOP_SELECT 1
|
||||
#define LOOP_CUT 2
|
||||
|
||||
extern void loopoperations(char mode);
|
||||
extern void vertex_loop_select(void);
|
||||
|
||||
/* ******************* editmesh_tools.c */
|
||||
extern void convert_to_triface(int all);
|
||||
extern short removedoublesflag(short flag, float limit);
|
||||
extern void xsortvert_flag(int flag);
|
||||
extern void hashvert_flag(int flag);
|
||||
extern void subdivideflag(int flag, float rad, int beauty);
|
||||
extern void extrude_mesh(void);
|
||||
extern void split_mesh(void);
|
||||
extern void extrude_repeat_mesh(int steps, float offs);
|
||||
extern void spin_mesh(int steps,int degr,float *dvec, int mode);
|
||||
extern void screw_mesh(int steps,int turns);
|
||||
extern void delete_mesh(void);
|
||||
extern void beauty_fill(void);
|
||||
extern void join_triangles(void);
|
||||
extern void edge_flip(void);
|
||||
extern void fill_mesh(void);
|
||||
extern void bevel_menu();
|
||||
void edge_rotate_selected(void);
|
||||
void edge_rotate(struct EditEdge *eed);
|
||||
|
||||
#endif
|
||||
|
||||
|
47
source/blender/include/BIF_meshtools.h
Normal file
47
source/blender/include/BIF_meshtools.h
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* $Id:
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BIF_MESHTOOLS_H
|
||||
#define BIF_MESHTOOLS_H
|
||||
|
||||
extern void join_mesh(void);
|
||||
extern void make_sticky(void);
|
||||
|
||||
extern void fasterdraw(void);
|
||||
extern void slowerdraw(void);
|
||||
|
||||
extern void vertexnormals_mesh(Mesh *me, float *extverts);
|
||||
extern void sort_faces(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
89
source/blender/include/editmesh.h
Normal file
89
source/blender/include/editmesh.h
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* $Id:
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/* Internal for editmesh_xxxx.c functions */
|
||||
|
||||
#ifndef EDITMESH_H
|
||||
#define EDITMESH_H
|
||||
|
||||
#define TEST_EDITMESH if(G.obedit==0) return; \
|
||||
if( (G.vd->lay & G.obedit->lay)==0 ) return;
|
||||
|
||||
#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
|
||||
|
||||
|
||||
/* ******************* editmesh.c */
|
||||
extern void free_editvert(EditVert *eve);
|
||||
extern void free_editedge(EditEdge *eed);
|
||||
extern void free_editface(EditFace *efa);
|
||||
|
||||
extern void free_vertlist(ListBase *edve);
|
||||
extern void free_edgelist(ListBase *lb);
|
||||
extern void free_facelist(ListBase *lb);
|
||||
|
||||
extern void remedge(EditEdge *eed);
|
||||
|
||||
extern struct EditVert *addvertlist(float *vec);
|
||||
extern struct EditEdge *addedgelist(struct EditVert *v1, struct EditVert *v2, struct EditEdge *example);
|
||||
extern struct EditFace *addfacelist(struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example);
|
||||
extern struct EditEdge *findedgelist(struct EditVert *v1, struct EditVert *v2);
|
||||
|
||||
/* ******************* editmesh_add.c */
|
||||
extern void adduplicateflag(int flag);
|
||||
|
||||
|
||||
/* ******************* editmesh_lib.c */
|
||||
extern int editmesh_nfaces_selected(void);
|
||||
extern int editmesh_nvertices_selected(void);
|
||||
|
||||
extern int faceselectedOR(EditFace *efa, int flag);
|
||||
extern int faceselectedAND(EditFace *efa, int flag);
|
||||
|
||||
extern int exist_face(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4);
|
||||
extern void flipface(EditFace *efa); // flips for normal direction
|
||||
extern int compareface(EditFace *vl1, EditFace *vl2);
|
||||
|
||||
extern void delfaceflag(int flag);
|
||||
extern short extrudeflag(short flag,short type);
|
||||
extern void rotateflag(short flag, float *cent, float rotmat[][3]);
|
||||
extern void translateflag(short flag, float *vec);
|
||||
|
||||
extern float convex(float *v1, float *v2, float *v3, float *v4);
|
||||
|
||||
/* ******************* editmesh_mods.c */
|
||||
extern EditEdge *findnearestedge();
|
||||
|
||||
/* ******************* editmesh_tools.c */
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -59,12 +59,10 @@
|
||||
// TODO check to see how many of these includes are necessary
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_editVert.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_memarena.h"
|
||||
|
||||
#include "BIF_editmesh.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
|
@ -98,6 +98,7 @@
|
||||
#include "BIF_editmesh.h"
|
||||
#include "BIF_editsound.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_meshtools.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_renderwin.h"
|
||||
#include "BIF_resources.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
699
source/blender/src/editmesh_add.c
Normal file
699
source/blender/src/editmesh_add.c
Normal file
@ -0,0 +1,699 @@
|
||||
/**
|
||||
* $Id:
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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) 2004 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_editVert.h"
|
||||
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BIF_editmesh.h"
|
||||
#include "BIF_graphics.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_screen.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_toolbox.h"
|
||||
|
||||
#include "BDR_editobject.h"
|
||||
|
||||
#include "BSE_view.h"
|
||||
#include "BSE_edit.h"
|
||||
|
||||
#include "mydevice.h"
|
||||
#include "blendef.h"
|
||||
|
||||
#include "editmesh.h"
|
||||
|
||||
static float icovert[12][3] = {
|
||||
{0,0,-200},
|
||||
{144.72, -105.144,-89.443},
|
||||
{-55.277, -170.128,-89.443},
|
||||
{-178.885,0,-89.443},
|
||||
{-55.277,170.128,-89.443},
|
||||
{144.72,105.144,-89.443},
|
||||
{55.277,-170.128,89.443},
|
||||
{-144.72,-105.144,89.443},
|
||||
{-144.72,105.144,89.443},
|
||||
{55.277,170.128,89.443},
|
||||
{178.885,0,89.443},
|
||||
{0,0,200}
|
||||
};
|
||||
static short icoface[20][3] = {
|
||||
{1,0,2},
|
||||
{1,0,5},
|
||||
{2,0,3},
|
||||
{3,0,4},
|
||||
{4,0,5},
|
||||
{1,5,10},
|
||||
{2,1,6},
|
||||
{3,2,7},
|
||||
{4,3,8},
|
||||
{5,4,9},
|
||||
{10,1,6},
|
||||
{6,2,7},
|
||||
{7,3,8},
|
||||
{8,4,9},
|
||||
{9,5,10},
|
||||
{6,10,11},
|
||||
{7,6,11},
|
||||
{8,7,11},
|
||||
{9,8,11},
|
||||
{10,9,11}
|
||||
};
|
||||
|
||||
void addvert_mesh(void)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVert *eve,*v1=0;
|
||||
float *curs, mat[3][3],imat[3][3];
|
||||
|
||||
TEST_EDITMESH
|
||||
|
||||
Mat3CpyMat4(mat, G.obedit->obmat);
|
||||
Mat3Inv(imat, mat);
|
||||
|
||||
v1= em->verts.first;
|
||||
while(v1) {
|
||||
if(v1->f & 1) break;
|
||||
v1= v1->next;
|
||||
}
|
||||
eve= v1; /* prevent there are more selected */
|
||||
while(eve) {
|
||||
eve->f&= ~1;
|
||||
eve= eve->next;
|
||||
}
|
||||
|
||||
eve= addvertlist(0);
|
||||
|
||||
curs= give_cursor();
|
||||
VECCOPY(eve->co, curs);
|
||||
eve->xs= G.vd->mx;
|
||||
eve->ys= G.vd->my;
|
||||
VecSubf(eve->co, eve->co, G.obedit->obmat[3]);
|
||||
|
||||
Mat3MulVecfl(imat, eve->co);
|
||||
eve->f= 1;
|
||||
|
||||
if(v1) {
|
||||
addedgelist(v1, eve, NULL);
|
||||
v1->f= 0;
|
||||
}
|
||||
countall();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
makeDispList(G.obedit);
|
||||
|
||||
while(get_mbut()&R_MOUSE);
|
||||
|
||||
}
|
||||
|
||||
void addedgeface_mesh(void)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVert *eve, *neweve[4];
|
||||
EditFace *efa;
|
||||
float con1, con2, con3;
|
||||
short aantal=0;
|
||||
|
||||
if( (G.vd->lay & G.obedit->lay)==0 ) return;
|
||||
|
||||
/* how many selected ? */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
if(eve->f & 1) {
|
||||
aantal++;
|
||||
if(aantal>4) break;
|
||||
neweve[aantal-1]= eve;
|
||||
}
|
||||
eve= eve->next;
|
||||
}
|
||||
if(aantal==2) {
|
||||
addedgelist(neweve[0], neweve[1], NULL);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
makeDispList(G.obedit);
|
||||
return;
|
||||
}
|
||||
if(aantal<2 || aantal>4) {
|
||||
error("Incorrect number of vertices to make edge/face");
|
||||
return;
|
||||
}
|
||||
|
||||
efa= NULL; // check later
|
||||
|
||||
if(aantal==3) {
|
||||
if(exist_face(neweve[0], neweve[1], neweve[2], 0)==0) {
|
||||
|
||||
efa= addfacelist(neweve[0], neweve[1], neweve[2], 0, NULL);
|
||||
|
||||
}
|
||||
else error("The selected vertices already form a face");
|
||||
}
|
||||
else if(aantal==4) {
|
||||
if(exist_face(neweve[0], neweve[1], neweve[2], neweve[3])==0) {
|
||||
|
||||
con1= convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co);
|
||||
con2= convex(neweve[0]->co, neweve[2]->co, neweve[3]->co, neweve[1]->co);
|
||||
con3= convex(neweve[0]->co, neweve[3]->co, neweve[1]->co, neweve[2]->co);
|
||||
|
||||
if(con1>=con2 && con1>=con3)
|
||||
efa= addfacelist(neweve[0], neweve[1], neweve[2], neweve[3], NULL);
|
||||
else if(con2>=con1 && con2>=con3)
|
||||
efa= addfacelist(neweve[0], neweve[2], neweve[3], neweve[1], NULL);
|
||||
else
|
||||
efa= addfacelist(neweve[0], neweve[2], neweve[1], neweve[3], NULL);
|
||||
|
||||
}
|
||||
else error("The selected vertices already form a face");
|
||||
}
|
||||
|
||||
if(efa) { // now we're calculating direction of normal
|
||||
float inp;
|
||||
/* dot product view mat with normal, should give info! */
|
||||
|
||||
CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
|
||||
|
||||
inp= efa->n[0]*G.vd->viewmat[0][2] + efa->n[1]*G.vd->viewmat[1][2] + efa->n[2]*G.vd->viewmat[2][2];
|
||||
|
||||
if(inp < 0.0) flipface(efa);
|
||||
}
|
||||
|
||||
countall();
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
makeDispList(G.obedit);
|
||||
}
|
||||
|
||||
void adduplicateflag(int flag)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
/* old verts have flag 128 set, and flag 'flag' cleared
|
||||
new verts have flag 'flag' set */
|
||||
EditVert *eve, *v1, *v2, *v3, *v4;
|
||||
EditEdge *eed;
|
||||
EditFace *efa;
|
||||
|
||||
/* vertices first */
|
||||
eve= em->verts.last;
|
||||
while(eve) {
|
||||
eve->f&= ~128;
|
||||
if(eve->f & flag) {
|
||||
v1= addvertlist(eve->co);
|
||||
v1->f= eve->f;
|
||||
eve->f-= flag;
|
||||
eve->f|= 128;
|
||||
eve->vn= v1;
|
||||
#ifdef __NLA
|
||||
/* >>>>> FIXME: Copy deformation weight ? */
|
||||
v1->totweight = eve->totweight;
|
||||
if (eve->totweight){
|
||||
v1->dw = MEM_mallocN (eve->totweight * sizeof(MDeformWeight), "deformWeight");
|
||||
memcpy (v1->dw, eve->dw, eve->totweight * sizeof(MDeformWeight));
|
||||
}
|
||||
else
|
||||
v1->dw=NULL;
|
||||
#endif
|
||||
}
|
||||
eve= eve->prev;
|
||||
}
|
||||
eed= em->edges.first;
|
||||
while(eed) {
|
||||
if( (eed->v1->f & 128) && (eed->v2->f & 128) ) {
|
||||
v1= eed->v1->vn;
|
||||
v2= eed->v2->vn;
|
||||
addedgelist(v1, v2, eed);
|
||||
}
|
||||
eed= eed->next;
|
||||
}
|
||||
|
||||
/* then dupicate faces */
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
if( (efa->v1->f & 128) && (efa->v2->f & 128) && (efa->v3->f & 128) ) {
|
||||
if(efa->v4) {
|
||||
if(efa->v4->f & 128) {
|
||||
v1= efa->v1->vn;
|
||||
v2= efa->v2->vn;
|
||||
v3= efa->v3->vn;
|
||||
v4= efa->v4->vn;
|
||||
addfacelist(v1, v2, v3, v4, efa);
|
||||
}
|
||||
}
|
||||
else {
|
||||
v1= efa->v1->vn;
|
||||
v2= efa->v2->vn;
|
||||
v3= efa->v3->vn;
|
||||
addfacelist(v1, v2, v3, 0, efa);
|
||||
}
|
||||
}
|
||||
efa= efa->next;
|
||||
}
|
||||
}
|
||||
|
||||
void adduplicate_mesh(void)
|
||||
{
|
||||
|
||||
TEST_EDITMESH
|
||||
|
||||
waitcursor(1);
|
||||
undo_push_mesh("Duplicate");
|
||||
adduplicateflag(1);
|
||||
waitcursor(0);
|
||||
countall(); /* for G.totvert in calc_meshverts() */
|
||||
transform('d');
|
||||
}
|
||||
|
||||
|
||||
|
||||
void add_primitiveMesh(int type)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
Mesh *me;
|
||||
EditVert *eve, *v1=NULL, *v2, *v3, *v4=NULL, *vtop, *vdown;
|
||||
float *curs, d, dia, phi, phid, cent[3], vec[3], imat[3][3], mat[3][3];
|
||||
float q[4], cmat[3][3];
|
||||
static short tot=32, seg=32, subdiv=2;
|
||||
short a, b, ext=0, fill=0, totoud, newob=0;
|
||||
|
||||
if(G.scene->id.lib) return;
|
||||
|
||||
/* this function also comes from an info window */
|
||||
if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return;
|
||||
if(G.vd==0) return;
|
||||
|
||||
/* if editmode exists for other type, it exits */
|
||||
check_editmode(OB_MESH);
|
||||
|
||||
if(G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT)) {
|
||||
G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT);
|
||||
setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
|
||||
}
|
||||
|
||||
/* if no obedit: new object and enter editmode */
|
||||
if(G.obedit==NULL) {
|
||||
/* add_object actually returns an object ! :-)
|
||||
But it also stores the added object struct in
|
||||
G.scene->basact->object (BASACT->object) */
|
||||
|
||||
add_object_draw(OB_MESH);
|
||||
|
||||
G.obedit= BASACT->object;
|
||||
|
||||
where_is_object(G.obedit);
|
||||
|
||||
make_editMesh();
|
||||
setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
|
||||
newob= 1;
|
||||
}
|
||||
me= G.obedit->data;
|
||||
|
||||
/* deselectall */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
if(eve->f & 1) eve->f&= ~1;
|
||||
eve= eve->next;
|
||||
}
|
||||
|
||||
totoud= tot; /* store, and restore when cube/plane */
|
||||
|
||||
/* imat and centre and size */
|
||||
Mat3CpyMat4(mat, G.obedit->obmat);
|
||||
|
||||
curs= give_cursor();
|
||||
VECCOPY(cent, curs);
|
||||
cent[0]-= G.obedit->obmat[3][0];
|
||||
cent[1]-= G.obedit->obmat[3][1];
|
||||
cent[2]-= G.obedit->obmat[3][2];
|
||||
|
||||
if(type!= 11) {
|
||||
Mat3CpyMat4(imat, G.vd->viewmat);
|
||||
Mat3MulVecfl(imat, cent);
|
||||
Mat3MulMat3(cmat, imat, mat);
|
||||
Mat3Inv(imat,cmat);
|
||||
} else {
|
||||
Mat3Inv(imat, mat);
|
||||
}
|
||||
|
||||
/* ext==extrudeflag, tot==amount of vertices in basis */
|
||||
|
||||
switch(type) {
|
||||
case 0: /* plane */
|
||||
tot= 4;
|
||||
ext= 0;
|
||||
fill= 1;
|
||||
if(newob) rename_id((ID *)G.obedit, "Plane");
|
||||
if(newob) rename_id((ID *)me, "Plane");
|
||||
break;
|
||||
case 1: /* cube */
|
||||
tot= 4;
|
||||
ext= 1;
|
||||
fill= 1;
|
||||
if(newob) rename_id((ID *)G.obedit, "Cube");
|
||||
if(newob) rename_id((ID *)me, "Cube");
|
||||
break;
|
||||
case 4: /* circle */
|
||||
if(button(&tot,3,100,"Vertices:")==0) return;
|
||||
ext= 0;
|
||||
fill= 0;
|
||||
if(newob) rename_id((ID *)G.obedit, "Circle");
|
||||
if(newob) rename_id((ID *)me, "Circle");
|
||||
break;
|
||||
case 5: /* cylinder */
|
||||
if(button(&tot,3,100,"Vertices:")==0) return;
|
||||
ext= 1;
|
||||
fill= 1;
|
||||
if(newob) rename_id((ID *)G.obedit, "Cylinder");
|
||||
if(newob) rename_id((ID *)me, "Cylinder");
|
||||
break;
|
||||
case 6: /* tube */
|
||||
if(button(&tot,3,100,"Vertices:")==0) return;
|
||||
ext= 1;
|
||||
fill= 0;
|
||||
if(newob) rename_id((ID *)G.obedit, "Tube");
|
||||
if(newob) rename_id((ID *)me, "Tube");
|
||||
break;
|
||||
case 7: /* cone */
|
||||
if(button(&tot,3,100,"Vertices:")==0) return;
|
||||
ext= 0;
|
||||
fill= 1;
|
||||
if(newob) rename_id((ID *)G.obedit, "Cone");
|
||||
if(newob) rename_id((ID *)me, "Cone");
|
||||
break;
|
||||
case 10: /* grid */
|
||||
if(button(&tot,2,100,"X res:")==0) return;
|
||||
if(button(&seg,2,100,"Y res:")==0) return;
|
||||
if(newob) rename_id((ID *)G.obedit, "Grid");
|
||||
if(newob) rename_id((ID *)me, "Grid");
|
||||
break;
|
||||
case 11: /* UVsphere */
|
||||
if(button(&seg,3,100,"Segments:")==0) return;
|
||||
if(button(&tot,3,100,"Rings:")==0) return;
|
||||
if(newob) rename_id((ID *)G.obedit, "Sphere");
|
||||
if(newob) rename_id((ID *)me, "Sphere");
|
||||
break;
|
||||
case 12: /* Icosphere */
|
||||
if(button(&subdiv,1,5,"Subdivision:")==0) return;
|
||||
if(newob) rename_id((ID *)G.obedit, "Sphere");
|
||||
if(newob) rename_id((ID *)me, "Sphere");
|
||||
break;
|
||||
case 13: /* Monkey */
|
||||
if(newob) rename_id((ID *)G.obedit, "Suzanne");
|
||||
if(newob) rename_id((ID *)me, "Suzanne");
|
||||
break;
|
||||
}
|
||||
|
||||
dia= sqrt(2.0)*G.vd->grid;
|
||||
d= -G.vd->grid;
|
||||
phid= 2*M_PI/tot;
|
||||
phi= .25*M_PI;
|
||||
|
||||
|
||||
if(type<10) { /* all types except grid, sphere... */
|
||||
if(ext==0 && type!=7) d= 0;
|
||||
|
||||
/* vertices */
|
||||
vtop= vdown= v1= v2= 0;
|
||||
for(b=0; b<=ext; b++) {
|
||||
for(a=0; a<tot; a++) {
|
||||
|
||||
vec[0]= cent[0]+dia*sin(phi);
|
||||
vec[1]= cent[1]+dia*cos(phi);
|
||||
vec[2]= cent[2]+d;
|
||||
|
||||
Mat3MulVecfl(imat, vec);
|
||||
eve= addvertlist(vec);
|
||||
eve->f= 1;
|
||||
if(a==0) {
|
||||
if(b==0) v1= eve;
|
||||
else v2= eve;
|
||||
}
|
||||
phi+=phid;
|
||||
}
|
||||
d= -d;
|
||||
}
|
||||
/* centre vertices */
|
||||
if(fill && type>1) {
|
||||
VECCOPY(vec,cent);
|
||||
vec[2]-= -d;
|
||||
Mat3MulVecfl(imat,vec);
|
||||
vdown= addvertlist(vec);
|
||||
if(ext || type==7) {
|
||||
VECCOPY(vec,cent);
|
||||
vec[2]-= d;
|
||||
Mat3MulVecfl(imat,vec);
|
||||
vtop= addvertlist(vec);
|
||||
}
|
||||
} else {
|
||||
vdown= v1;
|
||||
vtop= v2;
|
||||
}
|
||||
if(vtop) vtop->f= 1;
|
||||
if(vdown) vdown->f= 1;
|
||||
|
||||
/* top and bottom face */
|
||||
if(fill) {
|
||||
if(tot==4 && (type==0 || type==1)) {
|
||||
v3= v1->next->next;
|
||||
if(ext) v4= v2->next->next;
|
||||
|
||||
addfacelist(v3, v1->next, v1, v3->next, NULL);
|
||||
if(ext) addfacelist(v2, v2->next, v4, v4->next, NULL);
|
||||
|
||||
}
|
||||
else {
|
||||
v3= v1;
|
||||
v4= v2;
|
||||
for(a=1; a<tot; a++) {
|
||||
addfacelist(vdown, v3, v3->next, 0, NULL);
|
||||
v3= v3->next;
|
||||
if(ext) {
|
||||
addfacelist(vtop, v4, v4->next, 0, NULL);
|
||||
v4= v4->next;
|
||||
}
|
||||
}
|
||||
if(type>1) {
|
||||
addfacelist(vdown, v3, v1, 0, NULL);
|
||||
if(ext) addfacelist(vtop, v4, v2, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(type==4) { /* we need edges for a circle */
|
||||
v3= v1;
|
||||
for(a=1;a<tot;a++) {
|
||||
addedgelist(v3, v3->next, NULL);
|
||||
v3= v3->next;
|
||||
}
|
||||
addedgelist(v3, v1, NULL);
|
||||
}
|
||||
/* side faces */
|
||||
if(ext) {
|
||||
v3= v1;
|
||||
v4= v2;
|
||||
for(a=1; a<tot; a++) {
|
||||
addfacelist(v3, v3->next, v4->next, v4, NULL);
|
||||
v3= v3->next;
|
||||
v4= v4->next;
|
||||
}
|
||||
addfacelist(v3, v1, v2, v4, NULL);
|
||||
}
|
||||
else if(type==7) { /* cone */
|
||||
v3= v1;
|
||||
for(a=1; a<tot; a++) {
|
||||
addfacelist(vtop, v3->next, v3, 0, NULL);
|
||||
v3= v3->next;
|
||||
}
|
||||
addfacelist(vtop, v1, v3, 0, NULL);
|
||||
}
|
||||
|
||||
if(type<2) tot= totoud;
|
||||
|
||||
}
|
||||
else if(type==10) { /* grid */
|
||||
/* clear flags */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
eve->f= 0;
|
||||
eve= eve->next;
|
||||
}
|
||||
dia= G.vd->grid;
|
||||
/* one segment first: de X as */
|
||||
phi= -1.0;
|
||||
phid= 2.0/((float)tot-1);
|
||||
for(a=0;a<tot;a++) {
|
||||
vec[0]= cent[0]+dia*phi;
|
||||
vec[1]= cent[1]- dia;
|
||||
vec[2]= cent[2];
|
||||
Mat3MulVecfl(imat,vec);
|
||||
eve= addvertlist(vec);
|
||||
eve->f= 1+2+4;
|
||||
if (a) addedgelist(eve->prev, eve, NULL);
|
||||
phi+=phid;
|
||||
}
|
||||
/* extrude and translate */
|
||||
vec[0]= vec[2]= 0.0;
|
||||
vec[1]= dia*phid;
|
||||
Mat3MulVecfl(imat, vec);
|
||||
for(a=0;a<seg-1;a++) {
|
||||
extrudeflag(2,0);
|
||||
translateflag(2, vec);
|
||||
}
|
||||
}
|
||||
else if(type==11) { /* UVsphere */
|
||||
float tmat[3][3];
|
||||
|
||||
/* clear all flags */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
eve->f= 0;
|
||||
eve= eve->next;
|
||||
}
|
||||
|
||||
/* one segment first */
|
||||
phi= 0;
|
||||
phid/=2;
|
||||
for(a=0; a<=tot; a++) {
|
||||
vec[0]= cent[0]+dia*sin(phi);
|
||||
vec[1]= cent[1];
|
||||
vec[2]= cent[2]+dia*cos(phi);
|
||||
Mat3MulVecfl(imat,vec);
|
||||
eve= addvertlist(vec);
|
||||
eve->f= 1+2+4;
|
||||
if(a==0) v1= eve;
|
||||
else addedgelist(eve->prev, eve, NULL);
|
||||
phi+= phid;
|
||||
}
|
||||
|
||||
/* extrude and rotate */
|
||||
phi= M_PI/seg;
|
||||
q[0]= cos(phi);
|
||||
q[3]= sin(phi);
|
||||
q[1]=q[2]= 0;
|
||||
QuatToMat3(q, cmat);
|
||||
Mat3MulMat3(tmat, cmat, mat);
|
||||
Mat3MulMat3(cmat, imat, tmat);
|
||||
|
||||
for(a=0; a<seg; a++) {
|
||||
extrudeflag(2, 0);
|
||||
rotateflag(2, v1->co, cmat);
|
||||
}
|
||||
removedoublesflag(4, 0.0001);
|
||||
}
|
||||
else if(type==12) { /* Icosphere */
|
||||
EditVert *eva[12];
|
||||
|
||||
/* clear all flags */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
eve->f= 0;
|
||||
eve= eve->next;
|
||||
}
|
||||
dia/=200;
|
||||
for(a=0;a<12;a++) {
|
||||
vec[0]= dia*icovert[a][0];
|
||||
vec[1]= dia*icovert[a][1];
|
||||
vec[2]= dia*icovert[a][2];
|
||||
eva[a]= addvertlist(vec);
|
||||
eva[a]->f= 1+2;
|
||||
}
|
||||
for(a=0;a<20;a++) {
|
||||
v1= eva[ icoface[a][0] ];
|
||||
v2= eva[ icoface[a][1] ];
|
||||
v3= eva[ icoface[a][2] ];
|
||||
addfacelist(v1, v2, v3, 0, NULL);
|
||||
}
|
||||
|
||||
dia*=200;
|
||||
for(a=1; a<subdiv; a++) subdivideflag(2, dia, 0);
|
||||
/* and now do imat */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
if(eve->f & 2) {
|
||||
VecAddf(eve->co,eve->co,cent);
|
||||
Mat3MulVecfl(imat,eve->co);
|
||||
}
|
||||
eve= eve->next;
|
||||
}
|
||||
} else if (type==13) { /* Monkey */
|
||||
extern int monkeyo, monkeynv, monkeynf;
|
||||
extern signed char monkeyf[][4];
|
||||
extern signed char monkeyv[][3];
|
||||
EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv");
|
||||
int i;
|
||||
|
||||
for (i=0; i<monkeynv; i++) {
|
||||
float v[3];
|
||||
v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0;
|
||||
tv[i]= addvertlist(v);
|
||||
tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(v);
|
||||
}
|
||||
for (i=0; i<monkeynf; i++) {
|
||||
addfacelist(tv[monkeyf[i][0]+i-monkeyo], tv[monkeyf[i][1]+i-monkeyo], tv[monkeyf[i][2]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeyf[i][3]+i-monkeyo]:NULL, NULL);
|
||||
addfacelist(tv[monkeynv+monkeyf[i][2]+i-monkeyo], tv[monkeynv+monkeyf[i][1]+i-monkeyo], tv[monkeynv+monkeyf[i][0]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeynv+monkeyf[i][3]+i-monkeyo]:NULL, NULL);
|
||||
}
|
||||
|
||||
MEM_freeN(tv);
|
||||
}
|
||||
|
||||
if(type!=0 && type!=10) righthandfaces(1);
|
||||
countall();
|
||||
|
||||
allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
|
||||
allqueue(REDRAWALL, 0);
|
||||
makeDispList(G.obedit);
|
||||
|
||||
if (type==13) notice("Oooh Oooh Oooh");
|
||||
}
|
||||
|
736
source/blender/src/editmesh_lib.c
Normal file
736
source/blender/src/editmesh_lib.c
Normal file
@ -0,0 +1,736 @@
|
||||
/**
|
||||
* $Id:
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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) 2004 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
editmesh_lib: generic (no UI, no menus) operations/evaluators for editmesh data
|
||||
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_editVert.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BIF_editmesh.h"
|
||||
|
||||
#include "editmesh.h"
|
||||
|
||||
|
||||
/* ********************* */
|
||||
|
||||
int editmesh_nfaces_selected(void)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditFace *efa;
|
||||
int count= 0;
|
||||
|
||||
for (efa= em->faces.first; efa; efa= efa->next)
|
||||
if (faceselectedAND(efa, SELECT))
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int editmesh_nvertices_selected(void)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVert *eve;
|
||||
int count= 0;
|
||||
|
||||
for (eve= em->verts.first; eve; eve= eve->next)
|
||||
if (eve->f & SELECT)
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* ***************** */
|
||||
|
||||
short extrudeflag(short flag,short type)
|
||||
{
|
||||
/* when type=1 old extrusion faces are removed (for spin etc) */
|
||||
/* all verts with (flag & 'flag'): extrude */
|
||||
/* from old verts, 'flag' is cleared, in new ones it is set */
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVert *eve, *v1, *v2, *v3, *v4, *nextve;
|
||||
EditEdge *eed, *e1, *e2, *e3, *e4, *nexted;
|
||||
EditFace *efa, *efa2, *nextvl;
|
||||
short sel=0, deloud= 0, smooth= 0;
|
||||
|
||||
if(G.obedit==0 || get_mesh(G.obedit)==0) return 0;
|
||||
|
||||
/* clear vert flag f1, we use this to detext a loose selected vertice */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
if(eve->f & flag) eve->f1= 1;
|
||||
else eve->f1= 0;
|
||||
eve= eve->next;
|
||||
}
|
||||
/* clear edges counter flag, if selected we set it at 1 */
|
||||
eed= em->edges.first;
|
||||
while(eed) {
|
||||
if( (eed->v1->f & flag) && (eed->v2->f & flag) ) {
|
||||
eed->f= 1;
|
||||
eed->v1->f1= 0;
|
||||
eed->v2->f1= 0;
|
||||
}
|
||||
else eed->f= 0;
|
||||
|
||||
eed->f1= 1; /* this indicates it is an 'old' edge (in this routine we make new ones) */
|
||||
|
||||
eed= eed->next;
|
||||
}
|
||||
|
||||
/* we set a flag in all selected faces, and increase the associated edge counters */
|
||||
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
efa->f= 0;
|
||||
|
||||
if (efa->flag & ME_SMOOTH) {
|
||||
if (faceselectedOR(efa, 1)) smooth= 1;
|
||||
}
|
||||
|
||||
if(faceselectedAND(efa, flag)) {
|
||||
e1= efa->e1;
|
||||
e2= efa->e2;
|
||||
e3= efa->e3;
|
||||
e4= efa->e4;
|
||||
|
||||
if(e1->f < 3) e1->f++;
|
||||
if(e2->f < 3) e2->f++;
|
||||
if(e3->f < 3) e3->f++;
|
||||
if(e4 && e4->f < 3) e4->f++;
|
||||
efa->f= 1;
|
||||
}
|
||||
else if(faceselectedOR(efa, flag)) {
|
||||
e1= efa->e1;
|
||||
e2= efa->e2;
|
||||
e3= efa->e3;
|
||||
e4= efa->e4;
|
||||
|
||||
if( (e1->v1->f & flag) && (e1->v2->f & flag) ) e1->f1= 2;
|
||||
if( (e2->v1->f & flag) && (e2->v2->f & flag) ) e2->f1= 2;
|
||||
if( (e3->v1->f & flag) && (e3->v2->f & flag) ) e3->f1= 2;
|
||||
if( e4 && (e4->v1->f & flag) && (e4->v2->f & flag) ) e4->f1= 2;
|
||||
}
|
||||
|
||||
efa= efa->next;
|
||||
}
|
||||
|
||||
/* set direction of edges */
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
if(efa->f== 0) {
|
||||
if(efa->e1->f==2) {
|
||||
if(efa->e1->v1 == efa->v1) efa->e1->dir= 0;
|
||||
else efa->e1->dir= 1;
|
||||
}
|
||||
if(efa->e2->f==2) {
|
||||
if(efa->e2->v1 == efa->v2) efa->e2->dir= 0;
|
||||
else efa->e2->dir= 1;
|
||||
}
|
||||
if(efa->e3->f==2) {
|
||||
if(efa->e3->v1 == efa->v3) efa->e3->dir= 0;
|
||||
else efa->e3->dir= 1;
|
||||
}
|
||||
if(efa->e4 && efa->e4->f==2) {
|
||||
if(efa->e4->v1 == efa->v4) efa->e4->dir= 0;
|
||||
else efa->e4->dir= 1;
|
||||
}
|
||||
}
|
||||
efa= efa->next;
|
||||
}
|
||||
|
||||
|
||||
/* the current state now is:
|
||||
eve->f1==1: loose selected vertex
|
||||
|
||||
eed->f==0 : edge is not selected, no extrude
|
||||
eed->f==1 : edge selected, is not part of a face, extrude
|
||||
eed->f==2 : edge selected, is part of 1 face, extrude
|
||||
eed->f==3 : edge selected, is part of more faces, no extrude
|
||||
|
||||
eed->f1==0: new edge
|
||||
eed->f1==1: edge selected, is part of selected face, when eed->f==3: remove
|
||||
eed->f1==2: edge selected, is not part of a selected face
|
||||
|
||||
efa->f==1 : duplicate this face
|
||||
*/
|
||||
|
||||
/* copy all selected vertices, */
|
||||
/* write pointer to new vert in old struct at eve->vn */
|
||||
eve= em->verts.last;
|
||||
while(eve) {
|
||||
eve->f&= ~128; /* clear, for later test for loose verts */
|
||||
if(eve->f & flag) {
|
||||
sel= 1;
|
||||
v1= addvertlist(0);
|
||||
|
||||
VECCOPY(v1->co, eve->co);
|
||||
v1->f= eve->f;
|
||||
eve->f-= flag;
|
||||
eve->vn= v1;
|
||||
}
|
||||
else eve->vn= 0;
|
||||
eve= eve->prev;
|
||||
}
|
||||
|
||||
if(sel==0) return 0;
|
||||
|
||||
/* all edges with eed->f==1 or eed->f==2 become faces */
|
||||
/* if deloud==1 then edges with eed->f>2 are removed */
|
||||
eed= em->edges.last;
|
||||
while(eed) {
|
||||
nexted= eed->prev;
|
||||
if( eed->f<3) {
|
||||
eed->v1->f|=128; /* = no loose vert! */
|
||||
eed->v2->f|=128;
|
||||
}
|
||||
if( (eed->f==1 || eed->f==2) ) {
|
||||
if(eed->f1==2) deloud=1;
|
||||
|
||||
if(eed->dir==1) efa2= addfacelist(eed->v1, eed->v2, eed->v2->vn, eed->v1->vn, NULL);
|
||||
else efa2= addfacelist(eed->v2, eed->v1, eed->v1->vn, eed->v2->vn, NULL);
|
||||
if (smooth) efa2->flag |= ME_SMOOTH;
|
||||
|
||||
/* Needs smarter adaption of existing creases.
|
||||
* If addedgelist is used, make sure seams are set to 0 on these
|
||||
* new edges, since we do not want to add any seams on extrusion.
|
||||
*/
|
||||
efa2->e1->crease= eed->crease;
|
||||
efa2->e2->crease= eed->crease;
|
||||
efa2->e3->crease= eed->crease;
|
||||
if(efa2->e4) efa2->e4->crease= eed->crease;
|
||||
}
|
||||
|
||||
eed= nexted;
|
||||
}
|
||||
if(deloud) {
|
||||
eed= em->edges.first;
|
||||
while(eed) {
|
||||
nexted= eed->next;
|
||||
if(eed->f==3 && eed->f1==1) {
|
||||
remedge(eed);
|
||||
free_editedge(eed);
|
||||
}
|
||||
eed= nexted;
|
||||
}
|
||||
}
|
||||
/* duplicate faces, if necessart remove old ones */
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
nextvl= efa->next;
|
||||
if(efa->f & 1) {
|
||||
|
||||
v1= efa->v1->vn;
|
||||
v2= efa->v2->vn;
|
||||
v3= efa->v3->vn;
|
||||
if(efa->v4) v4= efa->v4->vn; else v4= 0;
|
||||
|
||||
efa2= addfacelist(v1, v2, v3, v4, efa);
|
||||
|
||||
if(deloud) {
|
||||
BLI_remlink(&em->faces, efa);
|
||||
free_editface(efa);
|
||||
}
|
||||
if (smooth) efa2->flag |= ME_SMOOTH;
|
||||
}
|
||||
efa= nextvl;
|
||||
}
|
||||
/* for all vertices with eve->vn!=0
|
||||
if eve->f1==1: make edge
|
||||
if flag!=128 : if deloud==1: remove
|
||||
*/
|
||||
eve= em->verts.last;
|
||||
while(eve) {
|
||||
nextve= eve->prev;
|
||||
if(eve->vn) {
|
||||
if(eve->f1==1) addedgelist(eve, eve->vn, NULL);
|
||||
else if( (eve->f & 128)==0) {
|
||||
if(deloud) {
|
||||
BLI_remlink(&em->verts,eve);
|
||||
free_editvert(eve);
|
||||
eve= NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(eve) eve->f&= ~128;
|
||||
|
||||
eve= nextve;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rotateflag(short flag, float *cent, float rotmat[][3])
|
||||
{
|
||||
/* all verts with (flag & 'flag') rotate */
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVert *eve;
|
||||
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
if(eve->f & flag) {
|
||||
eve->co[0]-=cent[0];
|
||||
eve->co[1]-=cent[1];
|
||||
eve->co[2]-=cent[2];
|
||||
Mat3MulVecfl(rotmat,eve->co);
|
||||
eve->co[0]+=cent[0];
|
||||
eve->co[1]+=cent[1];
|
||||
eve->co[2]+=cent[2];
|
||||
}
|
||||
eve= eve->next;
|
||||
}
|
||||
}
|
||||
|
||||
void translateflag(short flag, float *vec)
|
||||
{
|
||||
/* all verts with (flag & 'flag') translate */
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVert *eve;
|
||||
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
if(eve->f & flag) {
|
||||
eve->co[0]+=vec[0];
|
||||
eve->co[1]+=vec[1];
|
||||
eve->co[2]+=vec[2];
|
||||
}
|
||||
eve= eve->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void delfaceflag(int flag)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
/* delete all faces with 'flag', including edges and loose vertices */
|
||||
/* in vertices the 'flag' is cleared */
|
||||
EditVert *eve,*nextve;
|
||||
EditEdge *eed, *nexted;
|
||||
EditFace *efa,*nextvl;
|
||||
|
||||
eed= em->edges.first;
|
||||
while(eed) {
|
||||
eed->f= 0;
|
||||
eed= eed->next;
|
||||
}
|
||||
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
nextvl= efa->next;
|
||||
if(faceselectedAND(efa, flag)) {
|
||||
|
||||
efa->e1->f= 1;
|
||||
efa->e2->f= 1;
|
||||
efa->e3->f= 1;
|
||||
if(efa->e4) {
|
||||
efa->e4->f= 1;
|
||||
}
|
||||
|
||||
BLI_remlink(&em->faces, efa);
|
||||
free_editface(efa);
|
||||
}
|
||||
efa= nextvl;
|
||||
}
|
||||
/* all faces with 1, 2 (3) vertices selected: make sure we keep the edges */
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
efa->e1->f= 0;
|
||||
efa->e2->f= 0;
|
||||
efa->e3->f= 0;
|
||||
if(efa->e4) {
|
||||
efa->e4->f= 0;
|
||||
}
|
||||
|
||||
efa= efa->next;
|
||||
}
|
||||
|
||||
/* test all edges for vertices with 'flag', and clear */
|
||||
eed= em->edges.first;
|
||||
while(eed) {
|
||||
nexted= eed->next;
|
||||
if(eed->f==1) {
|
||||
remedge(eed);
|
||||
free_editedge(eed);
|
||||
}
|
||||
else if( (eed->v1->f & flag) || (eed->v2->f & flag) ) {
|
||||
eed->v1->f&= ~flag;
|
||||
eed->v2->f&= ~flag;
|
||||
}
|
||||
eed= nexted;
|
||||
}
|
||||
/* vertices with 'flag' now are the loose ones, and will be removed */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
nextve= eve->next;
|
||||
if(eve->f & flag) {
|
||||
BLI_remlink(&em->verts, eve);
|
||||
free_editvert(eve);
|
||||
}
|
||||
eve= nextve;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ********************* */
|
||||
|
||||
static int contrpuntnorm(float *n, float *puno) /* dutch: check vertex normal */
|
||||
{
|
||||
float inp;
|
||||
|
||||
inp= n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2];
|
||||
|
||||
/* angles 90 degrees: dont flip */
|
||||
if(inp> -0.000001) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void vertexnormals(int testflip)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
Mesh *me;
|
||||
EditVert *eve;
|
||||
EditFace *efa;
|
||||
float n1[3], n2[3], n3[3], n4[3], co[4], fac1, fac2, fac3, fac4, *temp;
|
||||
float *f1, *f2, *f3, *f4, xn, yn, zn;
|
||||
float len;
|
||||
|
||||
if(G.obedit && G.obedit->type==OB_MESH) {
|
||||
me= G.obedit->data;
|
||||
if((me->flag & ME_TWOSIDED)==0) testflip= 0;
|
||||
}
|
||||
|
||||
if(G.totvert==0) return;
|
||||
|
||||
if(G.totface==0) {
|
||||
/* fake vertex normals for 'halo puno'! */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
VECCOPY(eve->no, eve->co);
|
||||
Normalise( (float *)eve->no);
|
||||
eve= eve->next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* clear normals */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
eve->no[0]= eve->no[1]= eve->no[2]= 0.0;
|
||||
eve= eve->next;
|
||||
}
|
||||
|
||||
/* calculate cosine angles and add to vertex normal */
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
VecSubf(n1, efa->v2->co, efa->v1->co);
|
||||
VecSubf(n2, efa->v3->co, efa->v2->co);
|
||||
Normalise(n1);
|
||||
Normalise(n2);
|
||||
|
||||
if(efa->v4==0) {
|
||||
VecSubf(n3, efa->v1->co, efa->v3->co);
|
||||
Normalise(n3);
|
||||
|
||||
co[0]= saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2]);
|
||||
co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
|
||||
co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
|
||||
|
||||
}
|
||||
else {
|
||||
VecSubf(n3, efa->v4->co, efa->v3->co);
|
||||
VecSubf(n4, efa->v1->co, efa->v4->co);
|
||||
Normalise(n3);
|
||||
Normalise(n4);
|
||||
|
||||
co[0]= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
|
||||
co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
|
||||
co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
|
||||
co[3]= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
|
||||
}
|
||||
|
||||
temp= efa->v1->no;
|
||||
if(testflip && contrpuntnorm(efa->n, temp) ) co[0]= -co[0];
|
||||
temp[0]+= co[0]*efa->n[0];
|
||||
temp[1]+= co[0]*efa->n[1];
|
||||
temp[2]+= co[0]*efa->n[2];
|
||||
|
||||
temp= efa->v2->no;
|
||||
if(testflip && contrpuntnorm(efa->n, temp) ) co[1]= -co[1];
|
||||
temp[0]+= co[1]*efa->n[0];
|
||||
temp[1]+= co[1]*efa->n[1];
|
||||
temp[2]+= co[1]*efa->n[2];
|
||||
|
||||
temp= efa->v3->no;
|
||||
if(testflip && contrpuntnorm(efa->n, temp) ) co[2]= -co[2];
|
||||
temp[0]+= co[2]*efa->n[0];
|
||||
temp[1]+= co[2]*efa->n[1];
|
||||
temp[2]+= co[2]*efa->n[2];
|
||||
|
||||
if(efa->v4) {
|
||||
temp= efa->v4->no;
|
||||
if(testflip && contrpuntnorm(efa->n, temp) ) co[3]= -co[3];
|
||||
temp[0]+= co[3]*efa->n[0];
|
||||
temp[1]+= co[3]*efa->n[1];
|
||||
temp[2]+= co[3]*efa->n[2];
|
||||
}
|
||||
|
||||
efa= efa->next;
|
||||
}
|
||||
|
||||
/* normalise vertex normals */
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
len= Normalise(eve->no);
|
||||
if(len==0.0) {
|
||||
VECCOPY(eve->no, eve->co);
|
||||
Normalise( eve->no);
|
||||
}
|
||||
eve= eve->next;
|
||||
}
|
||||
|
||||
/* vertex normal flip-flags for shade (render) */
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
efa->f=0;
|
||||
|
||||
if(testflip) {
|
||||
f1= efa->v1->no;
|
||||
f2= efa->v2->no;
|
||||
f3= efa->v3->no;
|
||||
|
||||
fac1= efa->n[0]*f1[0] + efa->n[1]*f1[1] + efa->n[2]*f1[2];
|
||||
if(fac1<0.0) {
|
||||
efa->f = ME_FLIPV1;
|
||||
}
|
||||
fac2= efa->n[0]*f2[0] + efa->n[1]*f2[1] + efa->n[2]*f2[2];
|
||||
if(fac2<0.0) {
|
||||
efa->f += ME_FLIPV2;
|
||||
}
|
||||
fac3= efa->n[0]*f3[0] + efa->n[1]*f3[1] + efa->n[2]*f3[2];
|
||||
if(fac3<0.0) {
|
||||
efa->f += ME_FLIPV3;
|
||||
}
|
||||
if(efa->v4) {
|
||||
f4= efa->v4->no;
|
||||
fac4= efa->n[0]*f4[0] + efa->n[1]*f4[1] + efa->n[2]*f4[2];
|
||||
if(fac4<0.0) {
|
||||
efa->f += ME_FLIPV4;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* projection for cubemap! */
|
||||
xn= fabs(efa->n[0]);
|
||||
yn= fabs(efa->n[1]);
|
||||
zn= fabs(efa->n[2]);
|
||||
|
||||
if(zn>xn && zn>yn) efa->f += ME_PROJXY;
|
||||
else if(yn>xn && yn>zn) efa->f += ME_PROJXZ;
|
||||
else efa->f += ME_PROJYZ;
|
||||
|
||||
efa= efa->next;
|
||||
}
|
||||
}
|
||||
|
||||
void flipface(EditFace *efa)
|
||||
{
|
||||
if(efa->v4) {
|
||||
SWAP(EditVert *, efa->v2, efa->v4);
|
||||
SWAP(EditEdge *, efa->e1, efa->e4);
|
||||
SWAP(EditEdge *, efa->e2, efa->e3);
|
||||
SWAP(unsigned int, efa->tf.col[1], efa->tf.col[3]);
|
||||
SWAP(float, efa->tf.uv[1][0], efa->tf.uv[3][0]);
|
||||
SWAP(float, efa->tf.uv[1][1], efa->tf.uv[3][1]);
|
||||
}
|
||||
else {
|
||||
SWAP(EditVert *, efa->v2, efa->v3);
|
||||
SWAP(EditEdge *, efa->e1, efa->e3);
|
||||
SWAP(unsigned int, efa->tf.col[1], efa->tf.col[2]);
|
||||
efa->e2->dir= 1-efa->e2->dir;
|
||||
SWAP(float, efa->tf.uv[1][0], efa->tf.uv[2][0]);
|
||||
SWAP(float, efa->tf.uv[1][1], efa->tf.uv[2][1]);
|
||||
}
|
||||
if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
|
||||
else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
|
||||
}
|
||||
|
||||
|
||||
void flip_editnormals(void)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditFace *efa;
|
||||
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
if( faceselectedAND(efa, 1) ) {
|
||||
flipface(efa);
|
||||
}
|
||||
efa= efa->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void recalc_editnormals(void)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditFace *efa;
|
||||
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
|
||||
else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
|
||||
efa= efa->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int faceselectedOR(EditFace *efa, int flag)
|
||||
{
|
||||
|
||||
if(efa->v1->f & flag) return 1;
|
||||
if(efa->v2->f & flag) return 1;
|
||||
if(efa->v3->f & flag) return 1;
|
||||
if(efa->v4 && (efa->v4->f & 1)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int faceselectedAND(EditFace *efa, int flag)
|
||||
{
|
||||
if(efa->v1->f & flag) {
|
||||
if(efa->v2->f & flag) {
|
||||
if(efa->v3->f & flag) {
|
||||
if(efa->v4) {
|
||||
if(efa->v4->f & flag) return 1;
|
||||
}
|
||||
else return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compareface(EditFace *vl1, EditFace *vl2)
|
||||
{
|
||||
EditVert *v1, *v2, *v3, *v4;
|
||||
|
||||
if(vl1->v4 && vl2->v4) {
|
||||
v1= vl2->v1;
|
||||
v2= vl2->v2;
|
||||
v3= vl2->v3;
|
||||
v4= vl2->v4;
|
||||
|
||||
if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1 || vl1->v4==v1) {
|
||||
if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2 || vl1->v4==v2) {
|
||||
if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3 || vl1->v4==v3) {
|
||||
if(vl1->v1==v4 || vl1->v2==v4 || vl1->v3==v4 || vl1->v4==v4) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(vl1->v4==0 && vl2->v4==0) {
|
||||
v1= vl2->v1;
|
||||
v2= vl2->v2;
|
||||
v3= vl2->v3;
|
||||
|
||||
if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1) {
|
||||
if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2) {
|
||||
if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exist_face(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditFace *efa, efatest;
|
||||
|
||||
efatest.v1= v1;
|
||||
efatest.v2= v2;
|
||||
efatest.v3= v3;
|
||||
efatest.v4= v4;
|
||||
|
||||
efa= em->faces.first;
|
||||
while(efa) {
|
||||
if(compareface(&efatest, efa)) return 1;
|
||||
efa= efa->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
float convex(float *v1, float *v2, float *v3, float *v4)
|
||||
{
|
||||
float cross[3], test[3];
|
||||
float inpr;
|
||||
|
||||
CalcNormFloat(v1, v2, v3, cross);
|
||||
CalcNormFloat(v1, v3, v4, test);
|
||||
|
||||
inpr= cross[0]*test[0]+cross[1]*test[1]+cross[2]*test[2];
|
||||
|
||||
return inpr;
|
||||
}
|
||||
|
||||
|
1843
source/blender/src/editmesh_loop.c
Normal file
1843
source/blender/src/editmesh_loop.c
Normal file
File diff suppressed because it is too large
Load Diff
1447
source/blender/src/editmesh_mods.c
Normal file
1447
source/blender/src/editmesh_mods.c
Normal file
File diff suppressed because it is too large
Load Diff
3446
source/blender/src/editmesh_tools.c
Normal file
3446
source/blender/src/editmesh_tools.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -95,6 +95,7 @@
|
||||
#include "BIF_editview.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_mainqueue.h"
|
||||
#include "BIF_meshtools.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_renderwin.h"
|
||||
#include "BIF_resources.h"
|
||||
|
883
source/blender/src/meshtools.c
Normal file
883
source/blender/src/meshtools.c
Normal file
@ -0,0 +1,883 @@
|
||||
/**
|
||||
* $Id:
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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) 2004 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
meshtools.c: no editmode, tools operating on meshes
|
||||
|
||||
void join_mesh(void);
|
||||
void make_sticky(void);
|
||||
|
||||
void fasterdraw(void);
|
||||
void slowerdraw(void);
|
||||
|
||||
void vertexnormals_mesh(Mesh *me, float *extverts);
|
||||
void sort_faces(void);
|
||||
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_arithb.h"
|
||||
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BIF_editmesh.h"
|
||||
#include "BIF_graphics.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_screen.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_toolbox.h"
|
||||
|
||||
#include "BDR_editobject.h"
|
||||
|
||||
#include "mydevice.h"
|
||||
#include "blendef.h"
|
||||
|
||||
#include "render.h" // bad level call (ton)
|
||||
|
||||
/* * ********************** no editmode!!! *********** */
|
||||
|
||||
|
||||
/** tests whether selected mesh objects have tfaces */
|
||||
static int testSelected_TfaceMesh(void)
|
||||
{
|
||||
Base *base;
|
||||
Mesh *me;
|
||||
|
||||
base = FIRSTBASE;
|
||||
while (base) {
|
||||
if TESTBASE(base) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
me= base->object->data;
|
||||
if (me->tface)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void join_mesh(void)
|
||||
{
|
||||
Base *base, *nextb;
|
||||
Object *ob;
|
||||
Material **matar, *ma;
|
||||
Mesh *me;
|
||||
MVert *mvert, *mvertmain;
|
||||
MEdge *medge = NULL, *medgemain;
|
||||
MFace *mface = NULL, *mfacemain;
|
||||
TFace *tface = NULL, *tfacemain;
|
||||
unsigned int *mcol=NULL, *mcolmain;
|
||||
float imat[4][4], cmat[4][4];
|
||||
int a, b, totcol, totedge=0, totvert=0, totface=0, ok=0, vertofs, map[MAXMAT];
|
||||
int hasedges=0;
|
||||
int i, j, index, haskey=0;
|
||||
bDeformGroup *dg, *odg;
|
||||
MDeformVert *dvert, *dvertmain;
|
||||
|
||||
if(G.obedit) return;
|
||||
|
||||
ob= OBACT;
|
||||
if(!ob || ob->type!=OB_MESH) return;
|
||||
|
||||
/* count */
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if TESTBASE(base) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
me= base->object->data;
|
||||
totvert+= me->totvert;
|
||||
totface+= me->totface;
|
||||
if(me->medge) hasedges= 1;
|
||||
|
||||
if(base->object == ob) ok= 1;
|
||||
|
||||
if(me->key) {
|
||||
haskey= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
|
||||
if(haskey) {
|
||||
error("Can't join meshes with vertex keys");
|
||||
return;
|
||||
}
|
||||
/* that way the active object is always selected */
|
||||
if(ok==0) return;
|
||||
|
||||
if(totvert==0 || totvert>MESH_MAX_VERTS) return;
|
||||
|
||||
if(okee("Join selected meshes")==0) return;
|
||||
|
||||
|
||||
/* if needed add edges to other meshes */
|
||||
if(hasedges) {
|
||||
for(base= FIRSTBASE; base; base= base->next) {
|
||||
if TESTBASE(base) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
me= base->object->data;
|
||||
if(me->medge==NULL) make_edges(me);
|
||||
totedge += me->totedge;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* new material indices and material array */
|
||||
matar= MEM_callocN(sizeof(void *)*MAXMAT, "join_mesh");
|
||||
totcol= ob->totcol;
|
||||
|
||||
/* obact materials in new main array, is nicer start! */
|
||||
for(a=1; a<=ob->totcol; a++) {
|
||||
matar[a-1]= give_current_material(ob, a);
|
||||
id_us_plus((ID *)matar[a-1]);
|
||||
/* increase id->us : will be lowered later */
|
||||
}
|
||||
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if TESTBASE(base) {
|
||||
if(ob!=base->object && base->object->type==OB_MESH) {
|
||||
me= base->object->data;
|
||||
|
||||
// Join this object's vertex groups to the base one's
|
||||
for (dg=base->object->defbase.first; dg; dg=dg->next){
|
||||
/* See if this group exists in the object */
|
||||
for (odg=ob->defbase.first; odg; odg=odg->next){
|
||||
if (!strcmp(odg->name, dg->name)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!odg){
|
||||
odg = MEM_callocN (sizeof(bDeformGroup), "deformGroup");
|
||||
memcpy (odg, dg, sizeof(bDeformGroup));
|
||||
BLI_addtail(&ob->defbase, odg);
|
||||
}
|
||||
|
||||
}
|
||||
if (ob->defbase.first && ob->actdef==0)
|
||||
ob->actdef=1;
|
||||
|
||||
if(me->totvert) {
|
||||
for(a=1; a<=base->object->totcol; a++) {
|
||||
ma= give_current_material(base->object, a);
|
||||
if(ma) {
|
||||
for(b=0; b<totcol; b++) {
|
||||
if(ma == matar[b]) break;
|
||||
}
|
||||
if(b==totcol) {
|
||||
matar[b]= ma;
|
||||
ma->id.us++;
|
||||
totcol++;
|
||||
}
|
||||
if(totcol>=MAXMAT-1) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(totcol>=MAXMAT-1) break;
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
|
||||
me= ob->data;
|
||||
mvert= mvertmain= MEM_mallocN(totvert*sizeof(MVert), "joinmesh vert");
|
||||
|
||||
if(totedge) medge= medgemain= MEM_callocN(totedge*sizeof(MEdge), "joinmesh edge");
|
||||
else medgemain= NULL;
|
||||
|
||||
if (totface) mface= mfacemain= MEM_mallocN(totface*sizeof(MFace), "joinmesh face");
|
||||
else mfacemain= NULL;
|
||||
|
||||
if(me->mcol) mcol= mcolmain= MEM_callocN(totface*4*sizeof(int), "joinmesh mcol");
|
||||
else mcolmain= NULL;
|
||||
|
||||
/* if active object doesn't have Tfaces, but one in the selection does,
|
||||
make TFaces for active, so we don't lose texture information in the
|
||||
join process */
|
||||
if(me->tface || testSelected_TfaceMesh()) tface= tfacemain= MEM_callocN(totface*4*sizeof(TFace), "joinmesh4");
|
||||
else tfacemain= NULL;
|
||||
|
||||
if(me->dvert)
|
||||
dvert= dvertmain= MEM_callocN(totvert*sizeof(MDeformVert), "joinmesh5");
|
||||
else dvert=dvertmain= NULL;
|
||||
|
||||
vertofs= 0;
|
||||
|
||||
/* inverse transorm all selected meshes in this object */
|
||||
Mat4Invert(imat, ob->obmat);
|
||||
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
nextb= base->next;
|
||||
if TESTBASE(base) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
|
||||
me= base->object->data;
|
||||
|
||||
if(me->totvert) {
|
||||
|
||||
memcpy(mvert, me->mvert, me->totvert*sizeof(MVert));
|
||||
|
||||
copy_dverts(dvert, me->dvert, me->totvert);
|
||||
|
||||
/* NEW VERSION */
|
||||
if (dvertmain){
|
||||
for (i=0; i<me->totvert; i++){
|
||||
for (j=0; j<dvert[i].totweight; j++){
|
||||
// Find the old vertex group
|
||||
odg = BLI_findlink (&base->object->defbase, dvert[i].dw[j].def_nr);
|
||||
if(odg) {
|
||||
// Search for a match in the new object
|
||||
for (dg=ob->defbase.first, index=0; dg; dg=dg->next, index++){
|
||||
if (!strcmp(dg->name, odg->name)){
|
||||
dvert[i].dw[j].def_nr = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dvert+=me->totvert;
|
||||
}
|
||||
|
||||
if(base->object != ob) {
|
||||
/* watch this: switch matmul order really goes wrong */
|
||||
Mat4MulMat4(cmat, base->object->obmat, imat);
|
||||
|
||||
a= me->totvert;
|
||||
while(a--) {
|
||||
Mat4MulVecfl(cmat, mvert->co);
|
||||
mvert++;
|
||||
}
|
||||
}
|
||||
else mvert+= me->totvert;
|
||||
|
||||
if(mcolmain) {
|
||||
if(me->mcol) memcpy(mcol, me->mcol, me->totface*4*4);
|
||||
mcol+= 4*me->totface;
|
||||
}
|
||||
}
|
||||
if(me->totface) {
|
||||
|
||||
/* make mapping for materials */
|
||||
memset(map, 0, 4*MAXMAT);
|
||||
for(a=1; a<=base->object->totcol; a++) {
|
||||
ma= give_current_material(base->object, a);
|
||||
if(ma) {
|
||||
for(b=0; b<totcol; b++) {
|
||||
if(ma == matar[b]) {
|
||||
map[a-1]= b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(mface, me->mface, me->totface*sizeof(MFace));
|
||||
|
||||
a= me->totface;
|
||||
while(a--) {
|
||||
mface->v1+= vertofs;
|
||||
mface->v2+= vertofs;
|
||||
if(mface->v3) mface->v3+= vertofs;
|
||||
if(mface->v4) mface->v4+= vertofs;
|
||||
|
||||
mface->mat_nr= map[(int)mface->mat_nr];
|
||||
|
||||
mface++;
|
||||
}
|
||||
|
||||
if(tfacemain) {
|
||||
if(me->tface) memcpy(tface, me->tface, me->totface*sizeof(TFace));
|
||||
tface+= me->totface;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(me->totedge) {
|
||||
memcpy(medge, me->medge, me->totedge*sizeof(MEdge));
|
||||
|
||||
a= me->totedge;
|
||||
while(a--) {
|
||||
medge->v1+= vertofs;
|
||||
medge->v2+= vertofs;
|
||||
medge++;
|
||||
}
|
||||
}
|
||||
|
||||
vertofs+= me->totvert;
|
||||
|
||||
if(base->object!=ob) {
|
||||
free_and_unlink_base(base);
|
||||
}
|
||||
}
|
||||
}
|
||||
base= nextb;
|
||||
}
|
||||
|
||||
me= ob->data;
|
||||
|
||||
if(me->mvert) MEM_freeN(me->mvert);
|
||||
me->mvert= mvertmain;
|
||||
|
||||
if(me->medge) MEM_freeN(me->medge);
|
||||
me->medge= medgemain;
|
||||
|
||||
if(me->mface) MEM_freeN(me->mface);
|
||||
me->mface= mfacemain;
|
||||
|
||||
if(me->dvert) free_dverts(me->dvert, me->totvert);
|
||||
me->dvert = dvertmain;
|
||||
|
||||
if(me->mcol) MEM_freeN(me->mcol);
|
||||
me->mcol= (MCol *)mcolmain;
|
||||
|
||||
if(me->tface) MEM_freeN(me->tface);
|
||||
me->tface= tfacemain;
|
||||
|
||||
me->totvert= totvert;
|
||||
me->totedge= totedge;
|
||||
me->totface= totface;
|
||||
|
||||
/* old material array */
|
||||
for(a=1; a<=ob->totcol; a++) {
|
||||
ma= ob->mat[a-1];
|
||||
if(ma) ma->id.us--;
|
||||
}
|
||||
for(a=1; a<=me->totcol; a++) {
|
||||
ma= me->mat[a-1];
|
||||
if(ma) ma->id.us--;
|
||||
}
|
||||
if(ob->mat) MEM_freeN(ob->mat);
|
||||
if(me->mat) MEM_freeN(me->mat);
|
||||
ob->mat= me->mat= 0;
|
||||
|
||||
if(totcol) {
|
||||
me->mat= matar;
|
||||
ob->mat= MEM_callocN(sizeof(void *)*totcol, "join obmatar");
|
||||
}
|
||||
else MEM_freeN(matar);
|
||||
|
||||
ob->totcol= me->totcol= totcol;
|
||||
ob->colbits= 0;
|
||||
|
||||
/* other mesh users */
|
||||
test_object_materials((ID *)me);
|
||||
|
||||
enter_editmode();
|
||||
exit_editmode(1); // freedata, but no undo
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSSHADING, 0);
|
||||
makeDispList(ob);
|
||||
|
||||
BIF_undo_push("Join Mesh");
|
||||
}
|
||||
|
||||
|
||||
void make_sticky(void)
|
||||
{
|
||||
Object *ob;
|
||||
Base *base;
|
||||
MVert *mvert;
|
||||
Mesh *me;
|
||||
MSticky *ms;
|
||||
float ho[4], mat[4][4];
|
||||
int a;
|
||||
|
||||
if(G.scene->camera==0) return;
|
||||
|
||||
if(G.obedit) {
|
||||
error("Unable to make sticky in Edit Mode");
|
||||
return;
|
||||
}
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if TESTBASELIB(base) {
|
||||
if(base->object->type==OB_MESH) {
|
||||
ob= base->object;
|
||||
|
||||
me= ob->data;
|
||||
mvert= me->mvert;
|
||||
if(me->msticky) MEM_freeN(me->msticky);
|
||||
me->msticky= MEM_mallocN(me->totvert*sizeof(MSticky), "sticky");
|
||||
|
||||
/* like convert to render data */
|
||||
R.r= G.scene->r;
|
||||
R.r.xsch= (R.r.size*R.r.xsch)/100;
|
||||
R.r.ysch= (R.r.size*R.r.ysch)/100;
|
||||
|
||||
R.afmx= R.r.xsch/2;
|
||||
R.afmy= R.r.ysch/2;
|
||||
|
||||
R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
|
||||
|
||||
R.rectx= R.r.xsch;
|
||||
R.recty= R.r.ysch;
|
||||
R.xstart= -R.afmx;
|
||||
R.ystart= -R.afmy;
|
||||
R.xend= R.xstart+R.rectx-1;
|
||||
R.yend= R.ystart+R.recty-1;
|
||||
|
||||
where_is_object(G.scene->camera);
|
||||
Mat4CpyMat4(R.viewinv, G.scene->camera->obmat);
|
||||
Mat4Ortho(R.viewinv);
|
||||
Mat4Invert(R.viewmat, R.viewinv);
|
||||
|
||||
RE_setwindowclip(1, -1);
|
||||
|
||||
where_is_object(ob);
|
||||
Mat4MulMat4(mat, ob->obmat, R.viewmat);
|
||||
|
||||
ms= me->msticky;
|
||||
for(a=0; a<me->totvert; a++, ms++, mvert++) {
|
||||
VECCOPY(ho, mvert->co);
|
||||
Mat4MulVecfl(mat, ho);
|
||||
RE_projectverto(ho, ho);
|
||||
ms->co[0]= ho[0]/ho[3];
|
||||
ms->co[1]= ho[1]/ho[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
}
|
||||
|
||||
void fasterdraw(void)
|
||||
{
|
||||
Base *base;
|
||||
Mesh *me;
|
||||
MFace *mface;
|
||||
int toggle, a;
|
||||
|
||||
if(G.obedit) return;
|
||||
|
||||
/* reset flags */
|
||||
me= G.main->mesh.first;
|
||||
while(me) {
|
||||
me->flag &= ~ME_ISDONE;
|
||||
me= me->id.next;
|
||||
}
|
||||
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if( TESTBASELIB(base) && (base->object->type==OB_MESH)) {
|
||||
me= base->object->data;
|
||||
if(me->id.lib==0 && (me->flag & ME_ISDONE)==0) {
|
||||
me->flag |= ME_ISDONE;
|
||||
mface= me->mface;
|
||||
toggle= 0;
|
||||
for(a=0; a<me->totface; a++) {
|
||||
if( (mface->edcode & ME_V1V2) && ( (toggle++) & 1) ) {
|
||||
mface->edcode-= ME_V1V2;
|
||||
}
|
||||
if( (mface->edcode & ME_V2V3) && ( (toggle++) & 1)) {
|
||||
mface->edcode-= ME_V2V3;
|
||||
}
|
||||
if( (mface->edcode & ME_V3V1) && ( (toggle++) & 1)) {
|
||||
mface->edcode-= ME_V3V1;
|
||||
}
|
||||
if( (mface->edcode & ME_V4V1) && ( (toggle++) & 1)) {
|
||||
mface->edcode-= ME_V4V1;
|
||||
}
|
||||
if( (mface->edcode & ME_V3V4) && ( (toggle++) & 1)) {
|
||||
mface->edcode-= ME_V3V4;
|
||||
}
|
||||
mface++;
|
||||
}
|
||||
}
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
|
||||
/* important?: reset flags again */
|
||||
me= G.main->mesh.first;
|
||||
while(me) {
|
||||
me->flag &= ~ME_ISDONE;
|
||||
me= me->id.next;
|
||||
}
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
|
||||
void slowerdraw(void) /* reset fasterdraw */
|
||||
{
|
||||
Base *base;
|
||||
Mesh *me;
|
||||
MFace *mface;
|
||||
int a;
|
||||
|
||||
if(G.obedit) return;
|
||||
|
||||
base= FIRSTBASE;
|
||||
while(base) {
|
||||
if( TESTBASELIB(base) && (base->object->type==OB_MESH)) {
|
||||
me= base->object->data;
|
||||
if(me->id.lib==0) {
|
||||
|
||||
mface= me->mface;
|
||||
|
||||
for(a=0; a<me->totface; a++) {
|
||||
|
||||
mface->edcode |= ME_V1V2|ME_V2V3;
|
||||
mface++;
|
||||
}
|
||||
}
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
|
||||
/* ***************** */
|
||||
|
||||
/* this one for NOT in editmode
|
||||
|
||||
(only used by external modules, that is, until now by the
|
||||
python NMesh module)
|
||||
|
||||
TODO: Probably it's better to convert the mesh into a EditMesh, call
|
||||
vertexnormals() and convert it back to a Mesh again.
|
||||
|
||||
*/
|
||||
|
||||
static int contrpuntnorm(float *n, float *puno) /* dutch: check vertex normal */
|
||||
{
|
||||
float inp;
|
||||
|
||||
inp= n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2];
|
||||
|
||||
/* angles 90 degrees: dont flip */
|
||||
if(inp> -0.000001) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void vertexnormals_mesh(Mesh *me, float *extverts)
|
||||
{
|
||||
MVert *mvert;
|
||||
MFace *mface;
|
||||
float n1[3], n2[3], n3[3], n4[3], co[4], fac1, fac2, fac3, fac4, *temp;
|
||||
float *f1, *f2, *f3, *f4, xn, yn, zn, *normals;
|
||||
float *v1, *v2, *v3, *v4, len, vnor[3];
|
||||
int a, testflip;
|
||||
|
||||
if(me->totvert==0) return;
|
||||
|
||||
testflip= (me->flag & ME_NOPUNOFLIP)==0;
|
||||
if((me->flag & ME_TWOSIDED)==0) testflip= 0; /* large angles */
|
||||
|
||||
if(me->totface==0) {
|
||||
/* fake vertex normals for 'halopuno' (render option) */
|
||||
mvert= me->mvert;
|
||||
for(a=0; a<me->totvert; a++, mvert++) {
|
||||
VECCOPY(n1, mvert->co);
|
||||
Normalise(n1);
|
||||
mvert->no[0]= 32767.0*n1[0];
|
||||
mvert->no[1]= 32767.0*n1[1];
|
||||
mvert->no[2]= 32767.0*n1[2];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
normals= MEM_callocN(me->totvert*3*sizeof(float), "normals");
|
||||
|
||||
/* calculate cosine angles, and add to vertex normal */
|
||||
mface= me->mface;
|
||||
mvert= me->mvert;
|
||||
for(a=0; a<me->totface; a++, mface++) {
|
||||
|
||||
if(mface->v3==0) continue;
|
||||
|
||||
if(extverts) {
|
||||
v1= extverts+3*mface->v1;
|
||||
v2= extverts+3*mface->v2;
|
||||
v3= extverts+3*mface->v3;
|
||||
v4= extverts+3*mface->v4;
|
||||
}
|
||||
else {
|
||||
v1= (mvert+mface->v1)->co;
|
||||
v2= (mvert+mface->v2)->co;
|
||||
v3= (mvert+mface->v3)->co;
|
||||
v4= (mvert+mface->v4)->co;
|
||||
}
|
||||
|
||||
VecSubf(n1, v2, v1);
|
||||
VecSubf(n2, v3, v2);
|
||||
Normalise(n1);
|
||||
Normalise(n2);
|
||||
|
||||
if(mface->v4==0) {
|
||||
VecSubf(n3, v1, v3);
|
||||
Normalise(n3);
|
||||
|
||||
co[0]= saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2]);
|
||||
co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
|
||||
co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
|
||||
|
||||
}
|
||||
else {
|
||||
VecSubf(n3, v4, v3);
|
||||
VecSubf(n4, v1, v4);
|
||||
Normalise(n3);
|
||||
Normalise(n4);
|
||||
|
||||
co[0]= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
|
||||
co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
|
||||
co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
|
||||
co[3]= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
|
||||
}
|
||||
|
||||
CalcNormFloat(v1, v2, v3, vnor);
|
||||
|
||||
temp= normals+3*mface->v1;
|
||||
if(testflip && contrpuntnorm(vnor, temp) ) co[0]= -co[0];
|
||||
temp[0]+= co[0]*vnor[0];
|
||||
temp[1]+= co[0]*vnor[1];
|
||||
temp[2]+= co[0]*vnor[2];
|
||||
|
||||
temp= normals+3*mface->v2;
|
||||
if(testflip && contrpuntnorm(vnor, temp) ) co[1]= -co[1];
|
||||
temp[0]+= co[1]*vnor[0];
|
||||
temp[1]+= co[1]*vnor[1];
|
||||
temp[2]+= co[1]*vnor[2];
|
||||
|
||||
temp= normals+3*mface->v3;
|
||||
if(testflip && contrpuntnorm(vnor, temp) ) co[2]= -co[2];
|
||||
temp[0]+= co[2]*vnor[0];
|
||||
temp[1]+= co[2]*vnor[1];
|
||||
temp[2]+= co[2]*vnor[2];
|
||||
|
||||
if(mface->v4) {
|
||||
temp= normals+3*mface->v4;
|
||||
if(testflip && contrpuntnorm(vnor, temp) ) co[3]= -co[3];
|
||||
temp[0]+= co[3]*vnor[0];
|
||||
temp[1]+= co[3]*vnor[1];
|
||||
temp[2]+= co[3]*vnor[2];
|
||||
}
|
||||
}
|
||||
|
||||
/* normalize vertex normals */
|
||||
mvert= me->mvert;
|
||||
for(a=0; a<me->totvert; a++, mvert++) {
|
||||
len= Normalise(normals+3*a);
|
||||
if(len!=0.0) {
|
||||
VECCOPY(n1, normals+3*a);
|
||||
Normalise(n1);
|
||||
|
||||
mvert->no[0]= 32767.0*n1[0];
|
||||
mvert->no[1]= 32767.0*n1[1];
|
||||
mvert->no[2]= 32767.0*n1[2];
|
||||
}
|
||||
}
|
||||
|
||||
/* vertex normal flipping flags, for during render */
|
||||
mface= me->mface;
|
||||
mvert= me->mvert;
|
||||
for(a=0; a<me->totface; a++, mface++) {
|
||||
mface->puno=0;
|
||||
|
||||
if(mface->v3==0) continue;
|
||||
|
||||
if(extverts) {
|
||||
v1= extverts+3*mface->v1;
|
||||
v2= extverts+3*mface->v2;
|
||||
v3= extverts+3*mface->v3;
|
||||
}
|
||||
else {
|
||||
v1= (mvert+mface->v1)->co;
|
||||
v2= (mvert+mface->v2)->co;
|
||||
v3= (mvert+mface->v3)->co;
|
||||
}
|
||||
|
||||
CalcNormFloat(v1, v2, v3, vnor);
|
||||
|
||||
if(testflip) {
|
||||
f1= normals + 3*mface->v1;
|
||||
f2= normals + 3*mface->v2;
|
||||
f3= normals + 3*mface->v3;
|
||||
|
||||
fac1= vnor[0]*f1[0] + vnor[1]*f1[1] + vnor[2]*f1[2];
|
||||
if(fac1<0.0) {
|
||||
mface->puno = ME_FLIPV1;
|
||||
}
|
||||
fac2= vnor[0]*f2[0] + vnor[1]*f2[1] + vnor[2]*f2[2];
|
||||
if(fac2<0.0) {
|
||||
mface->puno += ME_FLIPV2;
|
||||
}
|
||||
fac3= vnor[0]*f3[0] + vnor[1]*f3[1] + vnor[2]*f3[2];
|
||||
if(fac3<0.0) {
|
||||
mface->puno += ME_FLIPV3;
|
||||
}
|
||||
if(mface->v4) {
|
||||
f4= normals + 3*mface->v4;
|
||||
fac4= vnor[0]*f4[0] + vnor[1]*f4[1] + vnor[2]*f4[2];
|
||||
if(fac4<0.0) {
|
||||
mface->puno += ME_FLIPV4;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* proj for cubemap! */
|
||||
xn= fabs(vnor[0]);
|
||||
yn= fabs(vnor[1]);
|
||||
zn= fabs(vnor[2]);
|
||||
|
||||
if(zn>xn && zn>yn) mface->puno += ME_PROJXY;
|
||||
else if(yn>xn && yn>zn) mface->puno += ME_PROJXZ;
|
||||
else mface->puno += ME_PROJYZ;
|
||||
|
||||
}
|
||||
|
||||
MEM_freeN(normals);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ********************** SORT FACES ******************* */
|
||||
|
||||
static void permutate(void *list, int num, int size, int *index)
|
||||
{
|
||||
void *buf;
|
||||
int len;
|
||||
int i;
|
||||
|
||||
len = num * size;
|
||||
|
||||
buf = MEM_mallocN(len, "permutate");
|
||||
memcpy(buf, list, len);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size);
|
||||
}
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
|
||||
static MVert *mvertbase;
|
||||
static MFace *mfacebase;
|
||||
|
||||
static int verg_mface(const void *v1, const void *v2)
|
||||
{
|
||||
MFace *x1, *x2;
|
||||
|
||||
MVert *ve1, *ve2;
|
||||
int i1, i2;
|
||||
|
||||
i1 = ((int *) v1)[0];
|
||||
i2 = ((int *) v2)[0];
|
||||
|
||||
x1 = mfacebase + i1;
|
||||
x2 = mfacebase + i2;
|
||||
|
||||
ve1= mvertbase+x1->v1;
|
||||
ve2= mvertbase+x2->v1;
|
||||
|
||||
if( ve1->co[2] > ve2->co[2] ) return 1;
|
||||
else if( ve1->co[2] < ve2->co[2]) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void sort_faces(void)
|
||||
{
|
||||
Object *ob= OBACT;
|
||||
Mesh *me;
|
||||
|
||||
int i, *index;
|
||||
|
||||
if(ob==0) return;
|
||||
if(G.obedit) return;
|
||||
if(ob->type!=OB_MESH) return;
|
||||
|
||||
if(okee("Sort faces in Z axis")==0) return;
|
||||
me= ob->data;
|
||||
if(me->totface==0) return;
|
||||
|
||||
/* create index list */
|
||||
index = (int *) MEM_mallocN(sizeof(int) * me->totface, "sort faces");
|
||||
for (i = 0; i < me->totface; i++) {
|
||||
index[i] = i;
|
||||
}
|
||||
mvertbase= me->mvert;
|
||||
mfacebase = me->mface;
|
||||
|
||||
/* sort index list instead of faces itself
|
||||
and apply this permutation to the face list plus
|
||||
to the texture faces */
|
||||
qsort(index, me->totface, sizeof(int), verg_mface);
|
||||
|
||||
permutate(mfacebase, me->totface, sizeof(MFace), index);
|
||||
if (me->tface)
|
||||
permutate(me->tface, me->totface, sizeof(TFace), index);
|
||||
|
||||
MEM_freeN(index);
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
makeDispList(G.obedit);
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,7 @@
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_imasel.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_meshtools.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_oops.h"
|
||||
#include "BIF_resources.h"
|
||||
|
@ -564,7 +564,6 @@ void exit_usiblender(void)
|
||||
free_posebuf();
|
||||
|
||||
free_blender(); /* blender.c, does entire library */
|
||||
free_hashedgetab();
|
||||
free_matcopybuf();
|
||||
free_ipocopybuf();
|
||||
freefastshade();
|
||||
|
Loading…
Reference in New Issue
Block a user