mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
pandatool: Delete softegg/softprogs
These depend on "SAA" - a Softimage library so long gone I can't even find references to it on Google.
This commit is contained in:
parent
466a68a985
commit
43142e4e80
@ -1,55 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file config_softegg.cxx
|
|
||||||
* @author masad
|
|
||||||
* @date 2003-09-25
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config_softegg.h"
|
|
||||||
#include "softEggGroupUserData.h"
|
|
||||||
#include "softNodeDesc.h"
|
|
||||||
|
|
||||||
#include "dconfig.h"
|
|
||||||
|
|
||||||
Configure(config_softegg);
|
|
||||||
NotifyCategoryDef(softegg, ":soft");
|
|
||||||
|
|
||||||
ConfigureFn(config_softegg) {
|
|
||||||
init_libsoftegg();
|
|
||||||
}
|
|
||||||
|
|
||||||
// These control the default behavior of the softegg converter, but not
|
|
||||||
// necessarily the default behavior of the soft2egg command-line tool (which
|
|
||||||
// has its own defaults).
|
|
||||||
|
|
||||||
// Should we respect the Soft? double-sided flag (true) or ignore it and
|
|
||||||
// assume everything is single-sided (false)?
|
|
||||||
ConfigVariableBool soft_default_double_sided("soft-default-double-sided", false);
|
|
||||||
|
|
||||||
// Should we apply vertex color even when a texture is applied (true) or only
|
|
||||||
// when no texture is applied or the vertex-color egg flag is set (false)?
|
|
||||||
ConfigVariableBool soft_default_vertex_color("soft-default-vertex-color", true);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the library. This must be called at least once before any of
|
|
||||||
* the functions or classes in this library can be used. Normally it will be
|
|
||||||
* called by the static initializers and need not be called explicitly, but
|
|
||||||
* special cases exist.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init_libsoftegg() {
|
|
||||||
static bool initialized = false;
|
|
||||||
if (initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
initialized = true;
|
|
||||||
|
|
||||||
SoftEggGroupUserData::init_type();
|
|
||||||
SoftNodeDesc::init_type();
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file config_softegg.h
|
|
||||||
* @author masad
|
|
||||||
* @date 2003-09-25
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CONFIG_SOFTEGG_H
|
|
||||||
#define CONFIG_SOFTEGG_H
|
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
|
||||||
#include "notifyCategoryProxy.h"
|
|
||||||
#include "configVariableBool.h"
|
|
||||||
|
|
||||||
NotifyCategoryDeclNoExport(softegg);
|
|
||||||
|
|
||||||
extern ConfigVariableBool soft_default_double_sided;
|
|
||||||
extern ConfigVariableBool soft_default_vertex_color;
|
|
||||||
|
|
||||||
extern void init_libsoftegg();
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softEggGroupUserData.I
|
|
||||||
* @author masad
|
|
||||||
* @date 2003-09-25
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
INLINE SoftEggGroupUserData::
|
|
||||||
SoftEggGroupUserData() {
|
|
||||||
_vertex_color = false;
|
|
||||||
_double_sided = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
INLINE SoftEggGroupUserData::
|
|
||||||
SoftEggGroupUserData(const SoftEggGroupUserData ©) :
|
|
||||||
EggUserData(copy),
|
|
||||||
_vertex_color(copy._vertex_color),
|
|
||||||
_double_sided(copy._double_sided)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
INLINE void SoftEggGroupUserData::
|
|
||||||
operator = (const SoftEggGroupUserData ©) {
|
|
||||||
EggUserData::operator = (copy);
|
|
||||||
_vertex_color = copy._vertex_color;
|
|
||||||
_double_sided = copy._double_sided;
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softEggGroupUserData.cxx
|
|
||||||
* @author masad
|
|
||||||
* @date 2003-09-25
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "softEggGroupUserData.h"
|
|
||||||
|
|
||||||
TypeHandle SoftEggGroupUserData::_type_handle;
|
|
@ -1,53 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softEggGroupUserData.h
|
|
||||||
* @author masad
|
|
||||||
* @date 2003-09-25
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOFTEGGGROUPUSERDATA_H
|
|
||||||
#define SOFTEGGGROUPUSERDATA_H
|
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
|
||||||
#include "eggUserData.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class contains extra user data which is piggybacked onto EggGroup
|
|
||||||
* objects for the purpose of the softimage converter.
|
|
||||||
*/
|
|
||||||
class SoftEggGroupUserData : public EggUserData {
|
|
||||||
public:
|
|
||||||
INLINE SoftEggGroupUserData();
|
|
||||||
INLINE SoftEggGroupUserData(const SoftEggGroupUserData ©);
|
|
||||||
INLINE void operator = (const SoftEggGroupUserData ©);
|
|
||||||
|
|
||||||
bool _vertex_color;
|
|
||||||
bool _double_sided;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static TypeHandle get_class_type() {
|
|
||||||
return _type_handle;
|
|
||||||
}
|
|
||||||
static void init_type() {
|
|
||||||
EggUserData::init_type();
|
|
||||||
register_type(_type_handle, "SoftEggGroupUserData",
|
|
||||||
EggUserData::get_class_type());
|
|
||||||
}
|
|
||||||
virtual TypeHandle get_type() const {
|
|
||||||
return get_class_type();
|
|
||||||
}
|
|
||||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static TypeHandle _type_handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "softEggGroupUserData.I"
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@ -1,159 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softNodeDesc.h
|
|
||||||
* @author masad
|
|
||||||
* @date 2003-10-03
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOFTNODEDESC_H
|
|
||||||
#define SOFTNODEDESC_H
|
|
||||||
|
|
||||||
#ifdef _MIN
|
|
||||||
#undef _MIN
|
|
||||||
#endif
|
|
||||||
#ifdef _MAX
|
|
||||||
#undef _MAX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
|
||||||
|
|
||||||
#include "eggVertex.h"
|
|
||||||
#include "eggVertexPool.h"
|
|
||||||
#include "referenceCount.h"
|
|
||||||
#include "pointerTo.h"
|
|
||||||
#include "namable.h"
|
|
||||||
|
|
||||||
#include <SAA.h>
|
|
||||||
|
|
||||||
class EggGroup;
|
|
||||||
class EggTable;
|
|
||||||
class EggXfmSAnim;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes a single instance of a node aka element in the Soft scene graph,
|
|
||||||
* relating it to the corresponding egg structures (e.g. node, group, or
|
|
||||||
* table entry) that will be created.
|
|
||||||
*/
|
|
||||||
class SoftNodeDesc : public ReferenceCount, public Namable {
|
|
||||||
public:
|
|
||||||
SoftNodeDesc(SoftNodeDesc *parent=nullptr, const std::string &name = std::string());
|
|
||||||
~SoftNodeDesc();
|
|
||||||
|
|
||||||
void set_parent(SoftNodeDesc *parent);
|
|
||||||
void force_set_parent(SoftNodeDesc *parent);
|
|
||||||
void set_model(SAA_Elem *model);
|
|
||||||
bool has_model() const;
|
|
||||||
SAA_Elem *get_model() const;
|
|
||||||
|
|
||||||
bool is_joint() const;
|
|
||||||
bool is_junk() const;
|
|
||||||
void set_joint();
|
|
||||||
bool is_joint_parent() const;
|
|
||||||
bool is_partial(char *search_prefix);
|
|
||||||
|
|
||||||
SoftNodeDesc *_parent;
|
|
||||||
SoftNodeDesc *_parentJoint; // keep track of who is your parent joint
|
|
||||||
typedef pvector< PT(SoftNodeDesc) > Children;
|
|
||||||
Children _children;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void clear_egg();
|
|
||||||
void mark_joint_parent();
|
|
||||||
void check_joint_parent();
|
|
||||||
void check_junk(bool parent_junk);
|
|
||||||
void check_pseudo_joints(bool joint_above);
|
|
||||||
|
|
||||||
void set_parentJoint(SAA_Scene *scene, SoftNodeDesc *lastJoint);
|
|
||||||
|
|
||||||
SAA_ModelType type;
|
|
||||||
|
|
||||||
SAA_Elem *_model;
|
|
||||||
|
|
||||||
EggGroup *_egg_group;
|
|
||||||
EggTable *_egg_table;
|
|
||||||
EggXfmSAnim *_anim;
|
|
||||||
|
|
||||||
enum JointType {
|
|
||||||
JT_none, // Not a joint.
|
|
||||||
JT_joint, // An actual joint in Soft.
|
|
||||||
JT_pseudo_joint, // Not a joint in Soft, but treated just like a
|
|
||||||
// joint for the purposes of the converter.
|
|
||||||
JT_joint_parent, // A parent or ancestor of a joint or pseudo joint.
|
|
||||||
JT_junk, // originated from con-/fly-/car_rig/bars etc.
|
|
||||||
};
|
|
||||||
JointType _joint_type;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
char **texNameArray;
|
|
||||||
int *uRepeat, *vRepeat;
|
|
||||||
PN_stdfloat matrix[4][4];
|
|
||||||
|
|
||||||
const char *fullname;
|
|
||||||
|
|
||||||
int numTri;
|
|
||||||
// int numShapes;
|
|
||||||
int numTexLoc;
|
|
||||||
int numTexGlb;
|
|
||||||
int *numTexTri;
|
|
||||||
|
|
||||||
// if the node is a MNSRF
|
|
||||||
int numNurbTexLoc;
|
|
||||||
int numNurbTexGlb;
|
|
||||||
int numNurbMats;
|
|
||||||
|
|
||||||
PN_stdfloat *uScale;
|
|
||||||
PN_stdfloat *vScale;
|
|
||||||
PN_stdfloat *uOffset;
|
|
||||||
PN_stdfloat *vOffset;
|
|
||||||
|
|
||||||
SAA_Boolean valid;
|
|
||||||
SAA_Boolean uv_swap;
|
|
||||||
// SAA_Boolean visible;
|
|
||||||
SAA_Elem *textures;
|
|
||||||
SAA_Elem *materials;
|
|
||||||
SAA_SubElem *triangles;
|
|
||||||
SAA_GeomType gtype;
|
|
||||||
|
|
||||||
EggGroup *get_egg_group()const {return _egg_group;}
|
|
||||||
|
|
||||||
void get_transform(SAA_Scene *scene, EggGroup *egg_group, bool global);
|
|
||||||
void get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim, bool global);
|
|
||||||
void load_poly_model(SAA_Scene *scene, SAA_ModelType type);
|
|
||||||
void load_nurbs_model(SAA_Scene *scene, SAA_ModelType type);
|
|
||||||
|
|
||||||
void make_morph_table(PN_stdfloat time);
|
|
||||||
void make_linear_morph_table(int numShapes, PN_stdfloat time);
|
|
||||||
void make_weighted_morph_table(int numShapes, PN_stdfloat time);
|
|
||||||
void make_expression_morph_table(int numShapes, PN_stdfloat time);
|
|
||||||
|
|
||||||
void make_vertex_offsets(int numShapes);
|
|
||||||
int find_shape_vert(LPoint3d p3d, SAA_DVector *vertices, int numVert);
|
|
||||||
|
|
||||||
static TypeHandle get_class_type() {
|
|
||||||
return _type_handle;
|
|
||||||
}
|
|
||||||
static void init_type() {
|
|
||||||
ReferenceCount::init_type();
|
|
||||||
Namable::init_type();
|
|
||||||
register_type(_type_handle, "SoftNodeDesc",
|
|
||||||
ReferenceCount::get_class_type(),
|
|
||||||
Namable::get_class_type());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static TypeHandle _type_handle;
|
|
||||||
|
|
||||||
friend class SoftNodeTree;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SoftToEggConverter;
|
|
||||||
extern SoftToEggConverter stec;
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,561 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softNodeTree.cxx
|
|
||||||
* @author masad
|
|
||||||
* @date 2003-09-26
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Includes
|
|
||||||
|
|
||||||
#include "softNodeTree.h"
|
|
||||||
#include "softEggGroupUserData.h"
|
|
||||||
#include "config_softegg.h"
|
|
||||||
#include "eggGroup.h"
|
|
||||||
#include "eggTable.h"
|
|
||||||
#include "eggXfmSAnim.h"
|
|
||||||
#include "eggData.h"
|
|
||||||
#include "softToEggConverter.h"
|
|
||||||
#include "dcast.h"
|
|
||||||
|
|
||||||
#include <SAA.h>
|
|
||||||
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SoftNodeTree::
|
|
||||||
SoftNodeTree() {
|
|
||||||
_root = new SoftNodeDesc(nullptr, "----root");
|
|
||||||
_root->fullname = "----root";
|
|
||||||
_fps = 0.0;
|
|
||||||
_use_prefix = 0;
|
|
||||||
_search_prefix = nullptr;
|
|
||||||
_egg_data = nullptr;
|
|
||||||
_egg_root = nullptr;
|
|
||||||
_skeleton_node = nullptr;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Given an element, return a copy of the element's name WITHOUT prefix.
|
|
||||||
*/
|
|
||||||
char *SoftNodeTree::
|
|
||||||
GetName( SAA_Scene *scene, SAA_Elem *element ) {
|
|
||||||
int nameLen;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
// get the name
|
|
||||||
SAA_elementGetNameLength( scene, element, &nameLen );
|
|
||||||
name = new char[++nameLen];
|
|
||||||
SAA_elementGetName( scene, element, nameLen, name );
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given an element, return a copy of the element's name complete with prefix.
|
|
||||||
*/
|
|
||||||
char *SoftNodeTree::
|
|
||||||
GetFullName( SAA_Scene *scene, SAA_Elem *element )
|
|
||||||
{
|
|
||||||
int nameLen, prefixLen;
|
|
||||||
char *name, *prefix;
|
|
||||||
|
|
||||||
// get the name length
|
|
||||||
SAA_elementGetNameLength( scene, element, &nameLen );
|
|
||||||
// get the prefix length
|
|
||||||
SAA_elementGetPrefixLength( scene, element, &prefixLen );
|
|
||||||
// allocate the array to hold name
|
|
||||||
name = new char[++nameLen];
|
|
||||||
// allocate the array to hold prefix and length + hyphen
|
|
||||||
prefix = new char[++prefixLen + nameLen + 4];
|
|
||||||
// get the name
|
|
||||||
SAA_elementGetName( scene, element, nameLen, name );
|
|
||||||
// get the prefix
|
|
||||||
SAA_elementGetPrefix( scene, element, prefixLen, prefix );
|
|
||||||
// add 'em together
|
|
||||||
strcat(prefix, "-");
|
|
||||||
strcat(prefix, name);
|
|
||||||
|
|
||||||
// return string
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given an element, return a string containing the contents of its MODEL NOTE
|
|
||||||
* entry
|
|
||||||
*/
|
|
||||||
char *SoftNodeTree::
|
|
||||||
GetModelNoteInfo( SAA_Scene *scene, SAA_Elem *model ) {
|
|
||||||
int size;
|
|
||||||
char *modelNote = nullptr;
|
|
||||||
SAA_Boolean bigEndian;
|
|
||||||
|
|
||||||
SAA_elementGetUserDataSize( scene, model, "MNOT", &size );
|
|
||||||
|
|
||||||
if ( size != 0 ) {
|
|
||||||
// allocate modelNote string
|
|
||||||
modelNote = new char[size + 1];
|
|
||||||
|
|
||||||
// get ModelNote data from this model
|
|
||||||
SAA_elementGetUserData( scene, model, "MNOT", size,
|
|
||||||
&bigEndian, (void *)modelNote );
|
|
||||||
|
|
||||||
// strip off newline, if present
|
|
||||||
char *eol = (char *)memchr( modelNote, '\n', size );
|
|
||||||
if ( eol != nullptr)
|
|
||||||
*eol = '\0';
|
|
||||||
else
|
|
||||||
modelNote[size] = '\0';
|
|
||||||
|
|
||||||
softegg_cat.spam() << "\nmodelNote = " << modelNote << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return modelNote;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a string, return a copy of the string up to the first occurence of
|
|
||||||
* '-'.
|
|
||||||
*/
|
|
||||||
char *SoftNodeTree::
|
|
||||||
GetRootName( const char *name ) {
|
|
||||||
const char *hyphen;
|
|
||||||
char *root;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
hyphen = strchr( name, '-' );
|
|
||||||
len = hyphen-name;
|
|
||||||
|
|
||||||
if ( (hyphen != nullptr) && len ) {
|
|
||||||
root = new char[len+1];
|
|
||||||
strncpy( root, name, len );
|
|
||||||
root[len] = '\0';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
root = new char[strlen(name)+1];
|
|
||||||
strcpy( root, name );
|
|
||||||
}
|
|
||||||
return( root );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Walks through the complete Soft hierarchy and builds up the corresponding
|
|
||||||
* tree.
|
|
||||||
*/
|
|
||||||
bool SoftNodeTree::
|
|
||||||
build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database) {
|
|
||||||
SI_Error status;
|
|
||||||
SoftNodeDesc *node;
|
|
||||||
|
|
||||||
// Get the entire Soft scene.
|
|
||||||
int numModels;
|
|
||||||
SAA_Elem *models;
|
|
||||||
|
|
||||||
SAA_sceneGetNbModels( &scene, &numModels );
|
|
||||||
softegg_cat.spam() << "Scene has " << numModels << " model(s)...\n";
|
|
||||||
|
|
||||||
// This while loop walks through the entire Soft hierarchy, one node at a
|
|
||||||
// time.
|
|
||||||
bool all_ok = true;
|
|
||||||
if ( numModels ) {
|
|
||||||
// allocate array of models
|
|
||||||
models = (SAA_Elem *) new SAA_Elem[numModels];
|
|
||||||
if ( models != nullptr ) {
|
|
||||||
if ((status = SAA_sceneGetModels( &scene, numModels, models )) != SI_SUCCESS) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for ( int i = 0; i < numModels; i++ ) {
|
|
||||||
int level;
|
|
||||||
status = SAA_elementGetHierarchyLevel( &scene, &models[i], &level );
|
|
||||||
softegg_cat.spam() << "model[" << i << "]" << endl;
|
|
||||||
softegg_cat.spam() << " level " << level << endl;
|
|
||||||
softegg_cat.spam() << " status is " << status << "\n";
|
|
||||||
|
|
||||||
node = build_node(&scene, &models[i]);
|
|
||||||
if (!level && node)
|
|
||||||
node->set_parent(_root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
softegg_cat.spam() << "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj\n";
|
|
||||||
|
|
||||||
// check the nodes that are junk for animationartist control purposes
|
|
||||||
_root->check_junk(false);
|
|
||||||
|
|
||||||
softegg_cat.spam() << "jpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjp\n";
|
|
||||||
|
|
||||||
// check the nodes that are parent of ancestors of a joint
|
|
||||||
_root->check_joint_parent();
|
|
||||||
|
|
||||||
softegg_cat.spam() << "pppppppppppppppppppppppppppppppppppppppppppppppppppppppp\n";
|
|
||||||
|
|
||||||
// check the nodes that are pseudo joints
|
|
||||||
_root->check_pseudo_joints(false);
|
|
||||||
|
|
||||||
softegg_cat.spam() << "========================================================\n";
|
|
||||||
|
|
||||||
// find _parentJoint for each node
|
|
||||||
_root->set_parentJoint(&scene, nullptr);
|
|
||||||
|
|
||||||
return all_ok;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
/**
|
|
||||||
* Walks through the selected subset of the Soft hierarchy (or the complete
|
|
||||||
* hierarchy, if nothing is selected) and builds up the corresponding tree.
|
|
||||||
*/
|
|
||||||
bool SoftNodeTree::
|
|
||||||
build_selected_hierarchy(char *scene_name) {
|
|
||||||
MStatus status;
|
|
||||||
|
|
||||||
MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
|
|
||||||
if (!status) {
|
|
||||||
status.perror("MItDag constructor");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get only the selected geometry.
|
|
||||||
MSelectionList selection;
|
|
||||||
status = MGlobal::getActiveSelectionList(selection);
|
|
||||||
if (!status) {
|
|
||||||
status.perror("MGlobal::getActiveSelectionList");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the selected geometry only if the selection is nonempty; otherwise,
|
|
||||||
// get the whole scene anyway.
|
|
||||||
if (selection.isEmpty()) {
|
|
||||||
softegg_cat.info()
|
|
||||||
<< "Selection list is empty.\n";
|
|
||||||
return build_complete_hierarchy();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool all_ok = true;
|
|
||||||
unsigned int length = selection.length();
|
|
||||||
for (unsigned int i = 0; i < length; i++) {
|
|
||||||
MDagPath root_path;
|
|
||||||
status = selection.getDagPath(i, root_path);
|
|
||||||
if (!status) {
|
|
||||||
status.perror("MSelectionList::getDagPath");
|
|
||||||
} else {
|
|
||||||
// Now traverse through the selected dag path and all nested dag paths.
|
|
||||||
dag_iterator.reset(root_path);
|
|
||||||
while (!dag_iterator.isDone()) {
|
|
||||||
MDagPath dag_path;
|
|
||||||
status = dag_iterator.getPath(dag_path);
|
|
||||||
if (!status) {
|
|
||||||
status.perror("MItDag::getPath");
|
|
||||||
} else {
|
|
||||||
build_node(dag_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
dag_iterator.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (all_ok) {
|
|
||||||
_root->check_pseudo_joints(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return all_ok;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* Returns the total number of nodes in the hierarchy, not counting the root
|
|
||||||
* node.
|
|
||||||
*/
|
|
||||||
int SoftNodeTree::
|
|
||||||
get_num_nodes() const {
|
|
||||||
return _nodes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the nth node in the hierarchy, in an arbitrary ordering.
|
|
||||||
*/
|
|
||||||
SoftNodeDesc *SoftNodeTree::
|
|
||||||
get_node(int n) const {
|
|
||||||
nassertr(n >= 0 && n < (int)_nodes.size(), nullptr);
|
|
||||||
return _nodes[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the node named 'name' in the hierarchy, in an arbitrary ordering.
|
|
||||||
*/
|
|
||||||
SoftNodeDesc *SoftNodeTree::
|
|
||||||
get_node(std::string name) const {
|
|
||||||
NodesByName::const_iterator ni = _nodes_by_name.find(name);
|
|
||||||
if (ni != _nodes_by_name.end())
|
|
||||||
return (*ni).second;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all of the references to generated egg structures from the tree,
|
|
||||||
* and prepares the tree for generating new egg structures.
|
|
||||||
*/
|
|
||||||
void SoftNodeTree::
|
|
||||||
clear_egg(EggData *egg_data, EggGroupNode *egg_root,
|
|
||||||
EggGroupNode *skeleton_node) {
|
|
||||||
_root->clear_egg();
|
|
||||||
_egg_data = egg_data;
|
|
||||||
_egg_root = egg_root;
|
|
||||||
_skeleton_node = skeleton_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the EggGroupNode corresponding to the group or joint for the
|
|
||||||
* indicated node. Creates the group node if it has not already been created.
|
|
||||||
*/
|
|
||||||
EggGroup *SoftNodeTree::
|
|
||||||
get_egg_group(SoftNodeDesc *node_desc) {
|
|
||||||
nassertr(_egg_root != nullptr, nullptr);
|
|
||||||
|
|
||||||
// lets print some relationship
|
|
||||||
softegg_cat.spam() << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
|
|
||||||
if (node_desc->_parent)
|
|
||||||
softegg_cat.spam() << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
|
|
||||||
else
|
|
||||||
softegg_cat.spam() << " parent " << node_desc->_parent;
|
|
||||||
softegg_cat.spam() << endl;
|
|
||||||
|
|
||||||
if (node_desc->_egg_group == nullptr) {
|
|
||||||
// We need to make a new group node.
|
|
||||||
EggGroup *egg_group;
|
|
||||||
|
|
||||||
egg_group = new EggGroup(node_desc->get_name());
|
|
||||||
if (node_desc->is_joint()) {
|
|
||||||
egg_group->set_group_type(EggGroup::GT_joint);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stec.flatten || (!node_desc->_parentJoint || node_desc->_parentJoint == _root)) {
|
|
||||||
// The parent is the root.
|
|
||||||
softegg_cat.spam() << "came hereeeee\n";
|
|
||||||
_egg_root->add_child(egg_group);
|
|
||||||
} else {
|
|
||||||
// The parent is another node.
|
|
||||||
EggGroup *parent_egg_group = get_egg_group(node_desc->_parentJoint);
|
|
||||||
parent_egg_group->add_child(egg_group);
|
|
||||||
}
|
|
||||||
|
|
||||||
node_desc->_egg_group = egg_group;
|
|
||||||
}
|
|
||||||
|
|
||||||
return node_desc->_egg_group;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the EggTable corresponding to the joint for the indicated node.
|
|
||||||
* Creates the table node if it has not already been created.
|
|
||||||
*/
|
|
||||||
EggTable *SoftNodeTree::
|
|
||||||
get_egg_table(SoftNodeDesc *node_desc) {
|
|
||||||
nassertr(_skeleton_node != nullptr, nullptr);
|
|
||||||
nassertr(node_desc->is_joint(), nullptr);
|
|
||||||
|
|
||||||
// lets print some relationship
|
|
||||||
softegg_cat.spam() << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
|
|
||||||
if (node_desc->_parent)
|
|
||||||
softegg_cat.spam() << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
|
|
||||||
else
|
|
||||||
softegg_cat.spam() << " parent " << node_desc->_parent;
|
|
||||||
softegg_cat.spam() << endl;
|
|
||||||
|
|
||||||
if (node_desc->_egg_table == nullptr) {
|
|
||||||
softegg_cat.spam() << "creating a new table\n";
|
|
||||||
// We need to make a new table node. nassertr(node_desc->_parent !=
|
|
||||||
// (SoftNodeDesc *)NULL, NULL);
|
|
||||||
|
|
||||||
EggTable *egg_table = new EggTable(node_desc->get_name());
|
|
||||||
node_desc->_anim = new EggXfmSAnim("xform", _egg_data->get_coordinate_system());
|
|
||||||
node_desc->_anim->set_fps(_fps);
|
|
||||||
egg_table->add_child(node_desc->_anim);
|
|
||||||
|
|
||||||
if (stec.flatten || (!node_desc->_parentJoint || node_desc->_parentJoint == _root)) {
|
|
||||||
// if (!node_desc->_parent->is_joint()) { The parent is not a joint; put
|
|
||||||
// it at the top.
|
|
||||||
_skeleton_node->add_child(egg_table);
|
|
||||||
} else {
|
|
||||||
// The parent is another joint.
|
|
||||||
EggTable *parent_egg_table = get_egg_table(node_desc->_parentJoint);
|
|
||||||
parent_egg_table->add_child(egg_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
node_desc->_egg_table = egg_table;
|
|
||||||
}
|
|
||||||
|
|
||||||
return node_desc->_egg_table;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the anim table corresponding to the joint for the indicated node.
|
|
||||||
* Creates the table node if it has not already been created.
|
|
||||||
*/
|
|
||||||
EggXfmSAnim *SoftNodeTree::
|
|
||||||
get_egg_anim(SoftNodeDesc *node_desc) {
|
|
||||||
get_egg_table(node_desc);
|
|
||||||
return node_desc->_anim;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets joint information for MNILL node
|
|
||||||
*/
|
|
||||||
void SoftNodeTree::
|
|
||||||
handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, const char *node_name) {
|
|
||||||
const char *name = node_name;
|
|
||||||
SAA_AlgorithmType algo;
|
|
||||||
SAA_Elem *model = node_desc->get_model();
|
|
||||||
|
|
||||||
SAA_modelGetAlgorithm( scene, model, &algo );
|
|
||||||
softegg_cat.spam() << " null algorithm: " << algo << endl;
|
|
||||||
|
|
||||||
if ( algo == SAA_ALG_INV_KIN ) {
|
|
||||||
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
|
|
||||||
node_desc->set_joint();
|
|
||||||
softegg_cat.spam() << " encountered IK root: " << name << endl;
|
|
||||||
}
|
|
||||||
else if ( algo == SAA_ALG_INV_KIN_LEAF ) {
|
|
||||||
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
|
|
||||||
node_desc->set_joint();
|
|
||||||
softegg_cat.spam() << " encountered IK leaf: " << name << endl;
|
|
||||||
}
|
|
||||||
else if ( algo == SAA_ALG_STANDARD ) {
|
|
||||||
SAA_Boolean isSkeleton = FALSE;
|
|
||||||
softegg_cat.spam() << " encountered Standard null: " << name << endl;
|
|
||||||
|
|
||||||
SAA_modelIsSkeleton( scene, model, &isSkeleton );
|
|
||||||
|
|
||||||
// check to see if this NULL is used as a skeleton or is animated via
|
|
||||||
// constraint only ( these nodes are tagged by the animator with the
|
|
||||||
// keyword "joint" somewhere in the nodes name)
|
|
||||||
if ( isSkeleton || (strstr( name, "joint" ) != nullptr) ) {
|
|
||||||
// MakeJoint( &scene, lastJoint, lastAnim, model, name );
|
|
||||||
node_desc->set_joint();
|
|
||||||
softegg_cat.spam() << " animating Standard null!!!\n";
|
|
||||||
softegg_cat.spam() << "isSkeleton: " << isSkeleton << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
softegg_cat.spam() << " encountered some other NULL: " << algo << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a pointer to the node corresponding to the indicated dag_path
|
|
||||||
* object, creating it first if necessary.
|
|
||||||
*/
|
|
||||||
SoftNodeDesc *SoftNodeTree::
|
|
||||||
build_node(SAA_Scene *scene, SAA_Elem *model) {
|
|
||||||
char *name, *fullname;
|
|
||||||
std::string node_name;
|
|
||||||
int numChildren;
|
|
||||||
int thisChild;
|
|
||||||
SAA_Elem *children;
|
|
||||||
SAA_ModelType type;
|
|
||||||
SAA_Boolean isSkeleton = FALSE;
|
|
||||||
|
|
||||||
fullname = GetFullName(scene, model);
|
|
||||||
if (_use_prefix)
|
|
||||||
name = fullname;
|
|
||||||
else
|
|
||||||
name = GetName(scene, model);
|
|
||||||
|
|
||||||
node_name = name;
|
|
||||||
|
|
||||||
SoftNodeDesc *node_desc = r_build_node(nullptr, node_name);
|
|
||||||
|
|
||||||
node_desc->fullname = fullname;
|
|
||||||
node_desc->set_model(model);
|
|
||||||
SAA_modelIsSkeleton( scene, model, &isSkeleton );
|
|
||||||
|
|
||||||
// find out what type of node we're dealing with
|
|
||||||
SAA_modelGetType( scene, node_desc->get_model(), &type );
|
|
||||||
|
|
||||||
if (type == SAA_MJNT || isSkeleton || (strstr(node_desc->get_name().c_str(), "joint") != nullptr))
|
|
||||||
node_desc->set_joint();
|
|
||||||
|
|
||||||
// treat the MNILL differently, because it needs to detect and set some
|
|
||||||
// joints
|
|
||||||
if (type == SAA_MNILL)
|
|
||||||
handle_null(scene, node_desc, name);
|
|
||||||
|
|
||||||
if (node_desc->is_joint())
|
|
||||||
softegg_cat.spam() << "type: " << type << " isSkeleton: " << isSkeleton << endl;
|
|
||||||
|
|
||||||
// get to the children
|
|
||||||
SAA_modelGetNbChildren( scene, model, &numChildren );
|
|
||||||
softegg_cat.spam() << " Model " << node_name << " children: " << numChildren << endl;
|
|
||||||
|
|
||||||
if ( numChildren ) {
|
|
||||||
children = new SAA_Elem[numChildren];
|
|
||||||
SAA_modelGetChildren( scene, model, numChildren, children );
|
|
||||||
if (!children)
|
|
||||||
softegg_cat.info() << "Not enough Memory for children...\n";
|
|
||||||
|
|
||||||
for ( thisChild = 0; thisChild < numChildren; thisChild++ ) {
|
|
||||||
fullname = GetFullName(scene, &children[thisChild]);
|
|
||||||
if (_use_prefix)
|
|
||||||
node_name = fullname;
|
|
||||||
else
|
|
||||||
node_name = GetName(scene, &children[thisChild]);
|
|
||||||
|
|
||||||
softegg_cat.spam() << " building child " << thisChild << "...";
|
|
||||||
|
|
||||||
SoftNodeDesc *node_child = r_build_node(node_desc, node_name);
|
|
||||||
|
|
||||||
node_child->fullname = fullname;
|
|
||||||
node_child->set_model(&children[thisChild]);
|
|
||||||
SAA_modelIsSkeleton( scene, &children[thisChild], &isSkeleton );
|
|
||||||
|
|
||||||
// find out what type of node we're dealing with
|
|
||||||
SAA_modelGetType( scene, node_child->get_model(), &type );
|
|
||||||
|
|
||||||
if (type == SAA_MJNT || isSkeleton || (strstr(node_child->get_name().c_str(), "joint") != nullptr))
|
|
||||||
node_child->set_joint();
|
|
||||||
|
|
||||||
// treat the MNILL differently, because it needs to detect and set some
|
|
||||||
// joints
|
|
||||||
if (type == SAA_MNILL)
|
|
||||||
handle_null(scene, node_child, node_name.c_str());
|
|
||||||
|
|
||||||
if (node_child->is_joint())
|
|
||||||
softegg_cat.spam() << "type: " << type << " isSkeleton: " << isSkeleton << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return node_desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The recursive implementation of build_node().
|
|
||||||
*/
|
|
||||||
SoftNodeDesc *SoftNodeTree::
|
|
||||||
r_build_node(SoftNodeDesc *parent_node, const std::string &name) {
|
|
||||||
SoftNodeDesc *node_desc;
|
|
||||||
|
|
||||||
// If we have already encountered this pathname, return the corresponding
|
|
||||||
// SoftNodeDesc immediately.
|
|
||||||
NodesByName::const_iterator ni = _nodes_by_name.find(name);
|
|
||||||
if (ni != _nodes_by_name.end()) {
|
|
||||||
softegg_cat.spam() << " already built node " << (*ni).first;
|
|
||||||
node_desc = (*ni).second;
|
|
||||||
node_desc->set_parent(parent_node);
|
|
||||||
return node_desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, we have to create it. Do this recursively, so we create each
|
|
||||||
// node along the path.
|
|
||||||
node_desc = new SoftNodeDesc(parent_node, name);
|
|
||||||
|
|
||||||
softegg_cat.spam() << " node name : " << name << endl;
|
|
||||||
_nodes.push_back(node_desc);
|
|
||||||
|
|
||||||
_nodes_by_name.insert(NodesByName::value_type(name, node_desc));
|
|
||||||
|
|
||||||
return node_desc;
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softNodeTree.h
|
|
||||||
* @author masad
|
|
||||||
* @date 2003-10-03
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOFTNODETREE_H
|
|
||||||
#define SOFTNODETREE_H
|
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
|
||||||
#include "softNodeDesc.h"
|
|
||||||
|
|
||||||
#include <SAA.h>
|
|
||||||
|
|
||||||
class EggGroup;
|
|
||||||
class EggTable;
|
|
||||||
class EggXfmSAnim;
|
|
||||||
class EggData;
|
|
||||||
class EggGroupNode;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes a complete tree of soft nodes for conversion.
|
|
||||||
*/
|
|
||||||
class SoftNodeTree {
|
|
||||||
public:
|
|
||||||
SoftNodeTree();
|
|
||||||
SoftNodeDesc *build_node(SAA_Scene *scene, SAA_Elem *model);
|
|
||||||
bool build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database);
|
|
||||||
void handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, const char *node_name);
|
|
||||||
// bool build_selected_hierarchy(SAA_Scene *s, SAA_Database *d, char
|
|
||||||
// *scene_name);
|
|
||||||
|
|
||||||
int get_num_nodes() const;
|
|
||||||
SoftNodeDesc *get_node(int n) const;
|
|
||||||
SoftNodeDesc *get_node(std::string name) const;
|
|
||||||
|
|
||||||
char *GetRootName(const char *);
|
|
||||||
char *GetModelNoteInfo(SAA_Scene *, SAA_Elem *);
|
|
||||||
char *GetName(SAA_Scene *scene, SAA_Elem *element);
|
|
||||||
char *GetFullName(SAA_Scene *scene, SAA_Elem *element);
|
|
||||||
|
|
||||||
EggGroupNode *get_egg_root() {return _egg_root;}
|
|
||||||
EggGroup *get_egg_group(SoftNodeDesc *node_desc);
|
|
||||||
EggTable *get_egg_table(SoftNodeDesc *node_desc);
|
|
||||||
EggXfmSAnim *get_egg_anim(SoftNodeDesc *node_desc);
|
|
||||||
|
|
||||||
void clear_egg(EggData *egg_data, EggGroupNode *egg_root, EggGroupNode *skeleton_node);
|
|
||||||
|
|
||||||
PT(SoftNodeDesc) _root;
|
|
||||||
PN_stdfloat _fps;
|
|
||||||
int _use_prefix;
|
|
||||||
char *_search_prefix;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
EggData *_egg_data;
|
|
||||||
EggGroupNode *_egg_root;
|
|
||||||
EggGroupNode *_skeleton_node;
|
|
||||||
|
|
||||||
SoftNodeDesc *r_build_node(SoftNodeDesc *parent_node, const std::string &path);
|
|
||||||
|
|
||||||
typedef pmap<std::string, SoftNodeDesc *> NodesByName;
|
|
||||||
NodesByName _nodes_by_name;
|
|
||||||
|
|
||||||
typedef pvector<SoftNodeDesc *> Nodes;
|
|
||||||
Nodes _nodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@ -1,179 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softToEggConverter.h
|
|
||||||
* @author masad
|
|
||||||
* @date 2003-09-25
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOFTTOEGGCONVERTER_H
|
|
||||||
#define SOFTTOEGGCONVERTER_H
|
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
|
||||||
#include "somethingToEggConverter.h"
|
|
||||||
#include "softNodeTree.h"
|
|
||||||
|
|
||||||
#include "eggTextureCollection.h"
|
|
||||||
#include "distanceUnit.h"
|
|
||||||
#include "coordinateSystem.h"
|
|
||||||
|
|
||||||
#ifdef _MIN
|
|
||||||
#undef _MIN
|
|
||||||
#endif
|
|
||||||
#ifdef _MAX
|
|
||||||
#undef _MAX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <SAA.h>
|
|
||||||
#include <SI_macros.h>
|
|
||||||
|
|
||||||
class EggData;
|
|
||||||
class EggGroup;
|
|
||||||
class EggTable;
|
|
||||||
class EggVertexPool;
|
|
||||||
class EggNurbsCurve;
|
|
||||||
class EggPrimitive;
|
|
||||||
class EggXfmSAnim;
|
|
||||||
class EggSAnimData;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class supervises the construction of an EggData structure from a
|
|
||||||
* single Softimage file, or from the data already in th cout << "egg name
|
|
||||||
* = " << eggFilename << endl;e global Softimage model space.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class SoftToEggConverter : public SomethingToEggConverter {
|
|
||||||
public:
|
|
||||||
SoftToEggConverter(const std::string &program_name = "");
|
|
||||||
SoftToEggConverter(const SoftToEggConverter ©);
|
|
||||||
virtual ~SoftToEggConverter();
|
|
||||||
|
|
||||||
void Help();
|
|
||||||
void Usage();
|
|
||||||
void ShowOpts();
|
|
||||||
|
|
||||||
bool HandleGetopts(int &idx, int argc, char **argv);
|
|
||||||
bool DoGetopts(int &argc, char **&argv);
|
|
||||||
|
|
||||||
SoftNodeDesc *find_node(std::string name);
|
|
||||||
int *FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert );
|
|
||||||
|
|
||||||
virtual SomethingToEggConverter *make_copy();
|
|
||||||
virtual std::string get_name() const;
|
|
||||||
virtual std::string get_extension() const;
|
|
||||||
|
|
||||||
virtual bool convert_file(const Filename &filename);
|
|
||||||
bool convert_soft(bool from_selection);
|
|
||||||
bool open_api();
|
|
||||||
void close_api();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool convert_flip(double start_frame, double end_frame,
|
|
||||||
double frame_inc, double output_frame_rate);
|
|
||||||
|
|
||||||
bool make_soft_skin();
|
|
||||||
bool cleanup_soft_skin();
|
|
||||||
bool convert_char_chan();
|
|
||||||
bool convert_char_model();
|
|
||||||
bool convert_hierarchy(EggGroupNode *egg_root);
|
|
||||||
bool process_model_node(SoftNodeDesc *node_desc);
|
|
||||||
|
|
||||||
void make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type);
|
|
||||||
void make_nurb_surface(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type);
|
|
||||||
void add_knots( vector <double> &eggKnots, double *knots, int numKnots, SAA_Boolean closed, int degree );
|
|
||||||
|
|
||||||
void set_shader_attributes(SoftNodeDesc *node_desc, EggPrimitive &primitive, int idx);
|
|
||||||
void apply_texture_properties(EggTexture &tex, int uRepeat, int vRepeat);
|
|
||||||
|
|
||||||
bool reparent_decals(EggGroupNode *egg_parent);
|
|
||||||
|
|
||||||
std::string _program_name;
|
|
||||||
bool _from_selection;
|
|
||||||
|
|
||||||
SI_Error result;
|
|
||||||
SAA_Elem model;
|
|
||||||
SAA_Database database;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
SoftNodeTree _tree;
|
|
||||||
|
|
||||||
SAA_Scene scene;
|
|
||||||
|
|
||||||
char *_getopts;
|
|
||||||
|
|
||||||
// This is argv[0].
|
|
||||||
const char *_commandName;
|
|
||||||
|
|
||||||
// This is the entire command line.
|
|
||||||
char _commandLine[4096];
|
|
||||||
|
|
||||||
char *rsrc_path;
|
|
||||||
char *database_name;
|
|
||||||
char *scene_name;
|
|
||||||
char *model_name;
|
|
||||||
char *eggFileName;
|
|
||||||
char *animFileName;
|
|
||||||
char *eggGroupName;
|
|
||||||
char *tex_path;
|
|
||||||
char *tex_filename;
|
|
||||||
char *search_prefix;
|
|
||||||
|
|
||||||
int nurbs_step;
|
|
||||||
int anim_start;
|
|
||||||
int anim_end;
|
|
||||||
int anim_rate;
|
|
||||||
int pose_frame;
|
|
||||||
int verbose;
|
|
||||||
int flatten;
|
|
||||||
int shift_textures;
|
|
||||||
int ignore_tex_offsets;
|
|
||||||
int use_prefix;
|
|
||||||
|
|
||||||
bool foundRoot;
|
|
||||||
bool geom_as_joint;
|
|
||||||
bool make_anim;
|
|
||||||
bool make_nurbs;
|
|
||||||
bool make_poly;
|
|
||||||
bool make_soft;
|
|
||||||
bool make_morph;
|
|
||||||
bool make_duv;
|
|
||||||
bool make_dart;
|
|
||||||
bool has_morph;
|
|
||||||
bool make_pose;
|
|
||||||
|
|
||||||
|
|
||||||
char *GetTextureName( SAA_Scene *scene, SAA_Elem *texture );
|
|
||||||
|
|
||||||
EggTextureCollection _textures;
|
|
||||||
|
|
||||||
bool _polygon_output;
|
|
||||||
double _polygon_tolerance;
|
|
||||||
|
|
||||||
enum TransformType {
|
|
||||||
TT_invalid,
|
|
||||||
TT_all,
|
|
||||||
TT_model,
|
|
||||||
TT_dcs,
|
|
||||||
TT_none,
|
|
||||||
};
|
|
||||||
TransformType _transform_type;
|
|
||||||
|
|
||||||
static TransformType string_transform_type(const std::string &arg);
|
|
||||||
|
|
||||||
typedef pvector<EggSAnimData *> MorphTable;
|
|
||||||
MorphTable _morph_table;
|
|
||||||
|
|
||||||
EggTable *morph_node;
|
|
||||||
EggSAnimData *find_morph_table(char *name);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const int TEX_PER_MAT;
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,588 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softCVS.cxx
|
|
||||||
* @author drose
|
|
||||||
* @date 2000-11-10
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "softCVS.h"
|
|
||||||
|
|
||||||
#include "pnotify.h"
|
|
||||||
#include "multifile.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SoftCVS::
|
|
||||||
SoftCVS() {
|
|
||||||
_cvs_binary = "cvs";
|
|
||||||
|
|
||||||
set_program_brief("prepare a SoftImage database directory for adding to CVS");
|
|
||||||
set_program_description
|
|
||||||
("softcvs is designed to prepare a directory hierarchy "
|
|
||||||
"representing a SoftImage database for adding to CVS. "
|
|
||||||
"First, it eliminates SoftImage's silly filename-based "
|
|
||||||
"versioning system by renaming versioned filenames higher "
|
|
||||||
"than 1-0 back to version 1-0. Then, it rolls up all the "
|
|
||||||
"files for each scene except the texture images into a Panda "
|
|
||||||
"multifile, which is added to CVS; the texture images are "
|
|
||||||
"directly added to CVS where they are.\n\n"
|
|
||||||
|
|
||||||
"The reduction of hundreds of SoftImage files per scene down to one "
|
|
||||||
"multifile and a handle of texture images should greatly improve "
|
|
||||||
"the update and commit times of CVS.\n\n"
|
|
||||||
|
|
||||||
"You must run this from within the root of a SoftImage database "
|
|
||||||
"directory; e.g. the directory that contains SCENES, PICTURES, MODELS, "
|
|
||||||
"and so on.");
|
|
||||||
|
|
||||||
clear_runlines();
|
|
||||||
add_runline("[opts]");
|
|
||||||
|
|
||||||
add_option
|
|
||||||
("nc", "", 80,
|
|
||||||
"Do not attempt to add newly-created files to CVS. The default "
|
|
||||||
"is to add them.",
|
|
||||||
&SoftCVS::dispatch_none, &_no_cvs);
|
|
||||||
|
|
||||||
add_option
|
|
||||||
("cvs", "cvs_binary", 80,
|
|
||||||
"Specify how to run the cvs program for adding newly-created files. "
|
|
||||||
"The default is simply \"cvs\".",
|
|
||||||
&SoftCVS::dispatch_string, nullptr, &_cvs_binary);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SoftCVS::
|
|
||||||
run() {
|
|
||||||
// First, check for the scenes directory. If it doesn't exist, we must not
|
|
||||||
// be in the root of a soft database.
|
|
||||||
Filename scenes = "SCENES/.";
|
|
||||||
if (!scenes.exists()) {
|
|
||||||
nout << "No SCENES directory found; you are not in the root of a "
|
|
||||||
"SoftImage database.\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also, if we're expecting to use CVS, make sure the CVS directory exists.
|
|
||||||
Filename cvs_entries = "CVS/Entries";
|
|
||||||
if (!_no_cvs && !cvs_entries.exists()) {
|
|
||||||
nout << "You do not appear to be within a CVS-controlled source "
|
|
||||||
"directory.\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan all the files in the database.
|
|
||||||
traverse_root();
|
|
||||||
|
|
||||||
// Collapse out the higher-versioned scene files.
|
|
||||||
collapse_scene_files();
|
|
||||||
|
|
||||||
// Now determine which element files are actually referenced by at least one
|
|
||||||
// of the scene files.
|
|
||||||
if (!get_scenes()) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, remove all the element files that are no longer referenced by
|
|
||||||
// any scenes.
|
|
||||||
remove_unused_elements();
|
|
||||||
|
|
||||||
// Now do all the cvs adding and removing we need.
|
|
||||||
if (!_no_cvs) {
|
|
||||||
cvs_add_or_remove("remove", _cvs_remove);
|
|
||||||
cvs_add_or_remove("add -kb", _cvs_add);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads all of the toplevel directory names, e.g. SCENES, MATERIALS, etc.,
|
|
||||||
* and traverses them.
|
|
||||||
*/
|
|
||||||
void SoftCVS::
|
|
||||||
traverse_root() {
|
|
||||||
Filename root(".");
|
|
||||||
|
|
||||||
// Get the list of subdirectories.
|
|
||||||
vector_string subdirs;
|
|
||||||
if (!root.scan_directory(subdirs)) {
|
|
||||||
nout << "Unable to scan directory.\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector_string::const_iterator di;
|
|
||||||
for (di = subdirs.begin(); di != subdirs.end(); ++di) {
|
|
||||||
Filename subdir = (*di);
|
|
||||||
if (subdir.is_directory() && subdir != "CVS") {
|
|
||||||
traverse_subdir(subdir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the directory indicated by prefix and identifies all of the SoftImage
|
|
||||||
* files stored there.
|
|
||||||
*/
|
|
||||||
void SoftCVS::
|
|
||||||
traverse_subdir(const Filename &directory) {
|
|
||||||
// Get the list of files in the directory.
|
|
||||||
vector_string files;
|
|
||||||
if (!directory.scan_directory(files)) {
|
|
||||||
nout << "Unable to scan directory " << directory << "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to know the set of files in this directory that are CVS elements.
|
|
||||||
pset<string> cvs_elements;
|
|
||||||
bool in_cvs = false;
|
|
||||||
if (!_no_cvs) {
|
|
||||||
in_cvs = scan_cvs(directory, cvs_elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_scenes = false;
|
|
||||||
bool keep_all = false;
|
|
||||||
bool wants_cvs = false;
|
|
||||||
|
|
||||||
// Now make some special-case behavior based on the particular SoftImage
|
|
||||||
// subdirectory we're in.
|
|
||||||
string dirname = directory.get_basename();
|
|
||||||
if (dirname == "SCENES") {
|
|
||||||
is_scenes = true;
|
|
||||||
|
|
||||||
} else if (dirname == "CAMERAS") {
|
|
||||||
// We don't want anything in the cameras directory. These may change
|
|
||||||
// arbitrarily and have no bearing on the model or animation that we will
|
|
||||||
// extract, so avoid them altogether.
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (dirname == "PICTURES") {
|
|
||||||
// In the pictures directory, we must keep everything, since the scene
|
|
||||||
// files don't explicitly reference these but they're still important.
|
|
||||||
// Textures that are no longer used will pile up; we leave this as the
|
|
||||||
// user's problem.
|
|
||||||
|
|
||||||
// We not only keep the textures, but we also move them into CVS, since
|
|
||||||
// (again) they're not part of the scene files and thus won't get added to
|
|
||||||
// the multifiles. Also, some textures are shared between different
|
|
||||||
// scenes, and it would be wasteful to add them to each scene multifile;
|
|
||||||
// furthermore, some scenes are used for animation only, and we don't want
|
|
||||||
// to modify these multifiles when the textures change.
|
|
||||||
|
|
||||||
keep_all = true;
|
|
||||||
wants_cvs = !_no_cvs;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector_string::const_iterator fi;
|
|
||||||
for (fi = files.begin(); fi != files.end(); ++fi) {
|
|
||||||
const string &filename = (*fi);
|
|
||||||
if (filename == "CVS") {
|
|
||||||
// This special filename is not to be considered.
|
|
||||||
|
|
||||||
} else if (filename == "Chapter.rsrc") {
|
|
||||||
// This special filename should not be considered, except to add it to
|
|
||||||
// the multifiles.
|
|
||||||
_global_files.push_back(Filename(directory, filename));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
SoftFilename soft(directory, filename);
|
|
||||||
|
|
||||||
if (cvs_elements.count(filename) != 0) {
|
|
||||||
// This file is known to be in CVS.
|
|
||||||
soft.set_in_cvs(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keep_all) {
|
|
||||||
soft.increment_use_count();
|
|
||||||
}
|
|
||||||
if (wants_cvs && !in_cvs) {
|
|
||||||
// Try to CVSify the directory.
|
|
||||||
cvs_add(directory);
|
|
||||||
in_cvs = true;
|
|
||||||
}
|
|
||||||
soft.set_wants_cvs(wants_cvs);
|
|
||||||
|
|
||||||
if (is_scenes && soft.has_version() && soft.get_extension() == ".dsc") {
|
|
||||||
_scene_files.push_back(soft);
|
|
||||||
} else {
|
|
||||||
_element_files.insert(soft);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Walks through the list of scene files found, and renames the higher-
|
|
||||||
* versioned ones to version 1-0, removing the intervening versions.
|
|
||||||
*/
|
|
||||||
void SoftCVS::
|
|
||||||
collapse_scene_files() {
|
|
||||||
// Get a copy of the scene files vector so we can modify it. Also empty out
|
|
||||||
// the _scene_files at the same time so we can fill it up again.
|
|
||||||
SceneFiles versions;
|
|
||||||
versions.swap(_scene_files);
|
|
||||||
|
|
||||||
// And sort them into order so we can easily compare higher and lower
|
|
||||||
// versions.
|
|
||||||
sort(versions.begin(), versions.end());
|
|
||||||
|
|
||||||
SceneFiles::iterator vi;
|
|
||||||
vi = versions.begin();
|
|
||||||
while (vi != versions.end()) {
|
|
||||||
SoftFilename &file = (*vi);
|
|
||||||
|
|
||||||
if (!file.is_1_0()) {
|
|
||||||
// Here's a file that needs to be renamed. But first, identify all the
|
|
||||||
// other versions of the same file.
|
|
||||||
SceneFiles::iterator start_vi;
|
|
||||||
start_vi = vi;
|
|
||||||
while (vi != versions.end() && (*vi).is_same_file(file)) {
|
|
||||||
++vi;
|
|
||||||
}
|
|
||||||
|
|
||||||
rename_file(start_vi, vi);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
++vi;
|
|
||||||
}
|
|
||||||
|
|
||||||
file.make_1_0();
|
|
||||||
_scene_files.push_back(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Walks through the list of scene files and looks for the set of element
|
|
||||||
* files referenced by each one, updating multifile accordingly.
|
|
||||||
*/
|
|
||||||
bool SoftCVS::
|
|
||||||
get_scenes() {
|
|
||||||
bool okflag = true;
|
|
||||||
|
|
||||||
// We will be added the multifiles to CVS if they're not already added, so
|
|
||||||
// we have to know which files are in CVS already.
|
|
||||||
pset<string> cvs_elements;
|
|
||||||
if (!_no_cvs) {
|
|
||||||
scan_cvs(".", cvs_elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneFiles::const_iterator vi;
|
|
||||||
for (vi = _scene_files.begin(); vi != _scene_files.end(); ++vi) {
|
|
||||||
const SoftFilename &sf = (*vi);
|
|
||||||
Filename file(sf.get_dirname(), sf.get_filename());
|
|
||||||
|
|
||||||
file.set_text();
|
|
||||||
std::ifstream in;
|
|
||||||
if (!file.open_read(in)) {
|
|
||||||
nout << "Unable to read " << file << "\n";
|
|
||||||
} else {
|
|
||||||
nout << "Scanning " << file << "\n";
|
|
||||||
|
|
||||||
Multifile multifile;
|
|
||||||
Filename multifile_name = sf.get_base() + "mf";
|
|
||||||
|
|
||||||
if (!multifile.open_read_write(multifile_name)) {
|
|
||||||
nout << "Unable to open " << multifile_name << " for updating.\n";
|
|
||||||
okflag = false;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (!scan_scene_file(in, multifile)) {
|
|
||||||
okflag = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add all the global files to the multifile too. These probably
|
|
||||||
// can't take compression (since in SoftImage they're just the
|
|
||||||
// Chapter.rsrc files, each very tiny).
|
|
||||||
vector_string::const_iterator gi;
|
|
||||||
for (gi = _global_files.begin(); gi != _global_files.end(); ++gi) {
|
|
||||||
if (multifile.update_subfile((*gi), (*gi), 0).empty()) {
|
|
||||||
nout << "Unable to add " << (*gi) << "\n";
|
|
||||||
okflag = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also add the scene file itself.
|
|
||||||
if (multifile.update_subfile(file, file, 6).empty()) {
|
|
||||||
nout << "Unable to add " << file << "\n";
|
|
||||||
okflag = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool flushed = false;
|
|
||||||
if (multifile.needs_repack()) {
|
|
||||||
flushed = multifile.repack();
|
|
||||||
} else {
|
|
||||||
flushed = multifile.flush();
|
|
||||||
}
|
|
||||||
if (!flushed) {
|
|
||||||
nout << "Failed to write " << multifile_name << ".\n";
|
|
||||||
okflag = false;
|
|
||||||
} else {
|
|
||||||
nout << "Wrote " << multifile_name << ".\n";
|
|
||||||
|
|
||||||
if (!_no_cvs && cvs_elements.count(multifile_name) == 0) {
|
|
||||||
// Add the multifile to CVS.
|
|
||||||
_cvs_add.push_back(multifile_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return okflag;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all the element files that weren't referenced by any scene file.
|
|
||||||
* Also plan to cvs add all those that were referenced.
|
|
||||||
*/
|
|
||||||
void SoftCVS::
|
|
||||||
remove_unused_elements() {
|
|
||||||
ElementFiles::const_iterator fi;
|
|
||||||
for (fi = _element_files.begin(); fi != _element_files.end(); ++fi) {
|
|
||||||
const SoftFilename &sf = (*fi);
|
|
||||||
Filename file(sf.get_dirname(), sf.get_filename());
|
|
||||||
|
|
||||||
if (sf.get_use_count() == 0) {
|
|
||||||
nout << file << " is unused.\n";
|
|
||||||
|
|
||||||
if (!file.unlink()) {
|
|
||||||
nout << "Unable to remove " << file << ".\n";
|
|
||||||
|
|
||||||
} else if (sf.get_in_cvs()) {
|
|
||||||
_cvs_remove.push_back(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (sf.get_wants_cvs() && !sf.get_in_cvs()) {
|
|
||||||
_cvs_add.push_back(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renames the first file in the indicated list to a version 1-0 filename,
|
|
||||||
* superceding all the other files in the list. Returns true if the file is
|
|
||||||
* renamed, false otherwise.
|
|
||||||
*/
|
|
||||||
bool SoftCVS::
|
|
||||||
rename_file(SoftCVS::SceneFiles::iterator begin,
|
|
||||||
SoftCVS::SceneFiles::iterator end) {
|
|
||||||
int length = end - begin;
|
|
||||||
nassertr(length > 0, false);
|
|
||||||
|
|
||||||
SoftFilename &orig = (*begin);
|
|
||||||
|
|
||||||
string dirname = orig.get_dirname();
|
|
||||||
string source_filename = orig.get_filename();
|
|
||||||
string dest_filename = orig.get_1_0_filename();
|
|
||||||
|
|
||||||
if (length > 2) {
|
|
||||||
nout << source_filename << " supercedes:\n";
|
|
||||||
SceneFiles::const_iterator p;
|
|
||||||
for (p = begin + 1; p != end; ++p) {
|
|
||||||
nout << " " << (*p).get_filename() << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (length == 2) {
|
|
||||||
nout << source_filename << " supercedes "
|
|
||||||
<< (*(begin + 1)).get_filename() << ".\n";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
nout << source_filename << " renamed.\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now remove all of the "wrong" files.
|
|
||||||
|
|
||||||
SceneFiles::const_iterator p;
|
|
||||||
for (p = begin + 1; p != end; ++p) {
|
|
||||||
Filename file((*p).get_dirname(), (*p).get_filename());
|
|
||||||
if (!file.unlink()) {
|
|
||||||
nout << "Unable to remove " << file << ".\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// And rename the good one.
|
|
||||||
Filename source(dirname, source_filename);
|
|
||||||
Filename dest(dirname, dest_filename);
|
|
||||||
|
|
||||||
if (!source.rename_to(dest)) {
|
|
||||||
nout << "Unable to rename " << source << " to " << dest_filename << ".\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scans the CVS repository in the indicated directory to determine which
|
|
||||||
* files are already versioned elements. Returns true if the directory is
|
|
||||||
* CVS-controlled, false otherwise.
|
|
||||||
*/
|
|
||||||
bool SoftCVS::
|
|
||||||
scan_cvs(const string &dirname, pset<string> &cvs_elements) {
|
|
||||||
Filename cvs_entries = dirname + "/CVS/Entries";
|
|
||||||
if (!cvs_entries.exists()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ifstream in;
|
|
||||||
cvs_entries.set_text();
|
|
||||||
if (!cvs_entries.open_read(in)) {
|
|
||||||
nout << "Unable to read CVS directory.\n";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
string line;
|
|
||||||
std::getline(in, line);
|
|
||||||
while (!in.fail() && !in.eof()) {
|
|
||||||
if (!line.empty() && line[0] == '/') {
|
|
||||||
size_t slash = line.find('/', 1);
|
|
||||||
if (slash != string::npos) {
|
|
||||||
string filename = line.substr(1, slash - 1);
|
|
||||||
|
|
||||||
if (line.substr(slash + 1, 2) == "-1") {
|
|
||||||
// If the first number after the slash is -1, the file used to be
|
|
||||||
// here but was recently cvs removed. It counts as no longer being
|
|
||||||
// an element.
|
|
||||||
} else {
|
|
||||||
cvs_elements.insert(filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::getline(in, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a scene file, looking for references to element files. For each
|
|
||||||
* reference found, increments the appropriate element file's reference count.
|
|
||||||
*/
|
|
||||||
bool SoftCVS::
|
|
||||||
scan_scene_file(std::istream &in, Multifile &multifile) {
|
|
||||||
bool okflag = true;
|
|
||||||
|
|
||||||
int c = in.get();
|
|
||||||
while (!in.eof() && !in.fail()) {
|
|
||||||
// Skip whitespace.
|
|
||||||
while (isspace(c) && !in.eof() && !in.fail()) {
|
|
||||||
c = in.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now begin a word.
|
|
||||||
string word;
|
|
||||||
while (!isspace(c) && !in.eof() && !in.fail()) {
|
|
||||||
word += c;
|
|
||||||
c = in.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!word.empty()) {
|
|
||||||
SoftFilename v("", word);
|
|
||||||
|
|
||||||
// Increment the use count on all matching elements of the multiset.
|
|
||||||
std::pair<ElementFiles::iterator, ElementFiles::iterator> range;
|
|
||||||
range = _element_files.equal_range(v);
|
|
||||||
|
|
||||||
ElementFiles::iterator ei;
|
|
||||||
for (ei = range.first; ei != range.second; ++ei) {
|
|
||||||
// We cheat and get a non-const reference to the filename out of the
|
|
||||||
// set. We can safely do this because incrementing the use count
|
|
||||||
// won't change its position in the set.
|
|
||||||
SoftFilename &sf = (SoftFilename &)(*ei);
|
|
||||||
sf.increment_use_count();
|
|
||||||
|
|
||||||
Filename file(sf.get_dirname(), sf.get_filename());
|
|
||||||
if (multifile.update_subfile(file, file, 6).empty()) {
|
|
||||||
nout << "Unable to add " << file << "\n";
|
|
||||||
okflag = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return okflag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invokes CVS to add just the named file to the repository. Returns true on
|
|
||||||
* success, false on failure.
|
|
||||||
*/
|
|
||||||
bool SoftCVS::
|
|
||||||
cvs_add(const string &path) {
|
|
||||||
string command = _cvs_binary + " add -kb " + path;
|
|
||||||
nout << command << "\n";
|
|
||||||
int result = system(command.c_str());
|
|
||||||
|
|
||||||
if (result != 0) {
|
|
||||||
nout << "Failure invoking cvs.\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invokes CVS to add (or remove) all of the files in the indicated vector.
|
|
||||||
* Returns true on success, false on failure.
|
|
||||||
*/
|
|
||||||
bool SoftCVS::
|
|
||||||
cvs_add_or_remove(const string &cvs_command, const vector_string &paths) {
|
|
||||||
static const int max_command = 4096;
|
|
||||||
|
|
||||||
if (!paths.empty()) {
|
|
||||||
string command = _cvs_binary + " " + cvs_command;
|
|
||||||
vector_string::const_iterator pi;
|
|
||||||
pi = paths.begin();
|
|
||||||
while (pi != paths.end()) {
|
|
||||||
const string &path = (*pi);
|
|
||||||
|
|
||||||
if ((int)command.length() + 1 + (int)path.length() >= max_command) {
|
|
||||||
// Fire off the command now.
|
|
||||||
nout << command << "\n";
|
|
||||||
int result = system(command.c_str());
|
|
||||||
|
|
||||||
if (result != 0) {
|
|
||||||
nout << "Failure invoking cvs.\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
command = _cvs_binary + " " + cvs_command;
|
|
||||||
}
|
|
||||||
|
|
||||||
command += ' ';
|
|
||||||
command += path;
|
|
||||||
|
|
||||||
++pi;
|
|
||||||
}
|
|
||||||
nout << command << "\n";
|
|
||||||
int result = system(command.c_str());
|
|
||||||
|
|
||||||
if (result != 0) {
|
|
||||||
nout << "Failure invoking cvs.\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
SoftCVS prog;
|
|
||||||
prog.parse_command_line(argc, argv);
|
|
||||||
prog.run();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softCVS.h
|
|
||||||
* @author drose
|
|
||||||
* @date 2000-11-10
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOFTCVS_H
|
|
||||||
#define SOFTCVS_H
|
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
|
||||||
|
|
||||||
#include "softFilename.h"
|
|
||||||
|
|
||||||
#include "programBase.h"
|
|
||||||
#include "vector_string.h"
|
|
||||||
#include "filename.h"
|
|
||||||
|
|
||||||
#include "pvector.h"
|
|
||||||
#include "pset.h"
|
|
||||||
|
|
||||||
class Multifile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This program prepares a SoftImage database for CVS by renaming everything
|
|
||||||
* to version 1-0, and adding new files to CVS.
|
|
||||||
*/
|
|
||||||
class SoftCVS : public ProgramBase {
|
|
||||||
public:
|
|
||||||
SoftCVS();
|
|
||||||
|
|
||||||
void run();
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef pvector<SoftFilename> SceneFiles;
|
|
||||||
typedef pmultiset<SoftFilename> ElementFiles;
|
|
||||||
|
|
||||||
void traverse_root();
|
|
||||||
void traverse_subdir(const Filename &directory);
|
|
||||||
|
|
||||||
void collapse_scene_files();
|
|
||||||
bool get_scenes();
|
|
||||||
void remove_unused_elements();
|
|
||||||
|
|
||||||
bool rename_file(SceneFiles::iterator begin, SceneFiles::iterator end);
|
|
||||||
bool scan_cvs(const std::string &dirname, pset<std::string> &cvs_elements);
|
|
||||||
bool scan_scene_file(std::istream &in, Multifile &multifile);
|
|
||||||
|
|
||||||
bool cvs_add(const std::string &path);
|
|
||||||
bool cvs_add_or_remove(const std::string &cvs_command,
|
|
||||||
const vector_string &paths);
|
|
||||||
|
|
||||||
SceneFiles _scene_files;
|
|
||||||
ElementFiles _element_files;
|
|
||||||
vector_string _global_files;
|
|
||||||
|
|
||||||
vector_string _cvs_add;
|
|
||||||
vector_string _cvs_remove;
|
|
||||||
|
|
||||||
bool _no_cvs;
|
|
||||||
std::string _cvs_binary;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,291 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softFilename.cxx
|
|
||||||
* @author drose
|
|
||||||
* @date 2000-11-10
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "softFilename.h"
|
|
||||||
|
|
||||||
#include "pnotify.h"
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SoftFilename::
|
|
||||||
SoftFilename(const string &dirname, const string &filename) :
|
|
||||||
_dirname(dirname),
|
|
||||||
_filename(filename)
|
|
||||||
{
|
|
||||||
_has_version = false;
|
|
||||||
_major = 0;
|
|
||||||
_minor = 0;
|
|
||||||
_in_cvs = false;
|
|
||||||
_wants_cvs = false;
|
|
||||||
_use_count = 0;
|
|
||||||
|
|
||||||
_base = _filename;
|
|
||||||
|
|
||||||
// Scan for a version number and an optional extension after each dot in the
|
|
||||||
// filename.
|
|
||||||
size_t dot = _filename.find('.');
|
|
||||||
while (dot != string::npos) {
|
|
||||||
size_t m = dot + 1;
|
|
||||||
const char *fstr = _filename.c_str();
|
|
||||||
char *endptr;
|
|
||||||
// Check for a numeric version number.
|
|
||||||
int major = strtol(fstr + m , &endptr, 10);
|
|
||||||
if (endptr != fstr + m && *endptr == '-') {
|
|
||||||
// We got a major number, is there a minor number?
|
|
||||||
m = (endptr - fstr) + 1;
|
|
||||||
int minor = strtol(fstr + m, &endptr, 10);
|
|
||||||
if (endptr != fstr + m && (*endptr == '.' || *endptr == '\0')) {
|
|
||||||
// We got a minor number too!
|
|
||||||
_has_version = true;
|
|
||||||
_base = _filename.substr(0, dot + 1);
|
|
||||||
_major = major;
|
|
||||||
_minor = minor;
|
|
||||||
_ext = endptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// That wasn't a version number. Is there more?
|
|
||||||
dot = _filename.find('.', dot + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SoftFilename::
|
|
||||||
SoftFilename(const SoftFilename ©) :
|
|
||||||
_dirname(copy._dirname),
|
|
||||||
_filename(copy._filename),
|
|
||||||
_has_version(copy._has_version),
|
|
||||||
_base(copy._base),
|
|
||||||
_major(copy._major),
|
|
||||||
_minor(copy._minor),
|
|
||||||
_ext(copy._ext),
|
|
||||||
_in_cvs(copy._in_cvs),
|
|
||||||
_wants_cvs(copy._wants_cvs),
|
|
||||||
_use_count(copy._use_count)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SoftFilename::
|
|
||||||
operator = (const SoftFilename ©) {
|
|
||||||
_dirname = copy._dirname;
|
|
||||||
_filename = copy._filename;
|
|
||||||
_has_version = copy._has_version;
|
|
||||||
_base = copy._base;
|
|
||||||
_major = copy._major;
|
|
||||||
_minor = copy._minor;
|
|
||||||
_ext = copy._ext;
|
|
||||||
_in_cvs = copy._in_cvs;
|
|
||||||
_wants_cvs = copy._wants_cvs;
|
|
||||||
_use_count = copy._use_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the directory this file was found in.
|
|
||||||
*/
|
|
||||||
const string &SoftFilename::
|
|
||||||
get_dirname() const {
|
|
||||||
return _dirname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the actual filename as found in the directory.
|
|
||||||
*/
|
|
||||||
const string &SoftFilename::
|
|
||||||
get_filename() const {
|
|
||||||
return _filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the filename had a version number, false otherwise.
|
|
||||||
*/
|
|
||||||
bool SoftFilename::
|
|
||||||
has_version() const {
|
|
||||||
return _has_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns what the filename would be if it were version 1-0.
|
|
||||||
*/
|
|
||||||
string SoftFilename::
|
|
||||||
get_1_0_filename() const {
|
|
||||||
nassertr(_has_version, string());
|
|
||||||
return _base + "1-0" + _ext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the base part of the filename. This is everything before the
|
|
||||||
* version number.
|
|
||||||
*/
|
|
||||||
const string &SoftFilename::
|
|
||||||
get_base() const {
|
|
||||||
nassertr(_has_version, _filename);
|
|
||||||
return _base;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the major version number.
|
|
||||||
*/
|
|
||||||
int SoftFilename::
|
|
||||||
get_major() const {
|
|
||||||
nassertr(_has_version, 0);
|
|
||||||
return _major;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the minor version number.
|
|
||||||
*/
|
|
||||||
int SoftFilename::
|
|
||||||
get_minor() const {
|
|
||||||
nassertr(_has_version, 0);
|
|
||||||
return _minor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the extension part of the filename. This is everything after the
|
|
||||||
* version number.
|
|
||||||
*/
|
|
||||||
const string &SoftFilename::
|
|
||||||
get_extension() const {
|
|
||||||
nassertr(_has_version, _ext);
|
|
||||||
return _ext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the filename part, without the extension.
|
|
||||||
*/
|
|
||||||
string SoftFilename::
|
|
||||||
get_non_extension() const {
|
|
||||||
nassertr(_has_version, _filename);
|
|
||||||
nassertr(_ext.length() < _filename.length(), _filename);
|
|
||||||
return _filename.substr(0, _filename.length() - _ext.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this is a version 1_0 filename, false otherwise.
|
|
||||||
*/
|
|
||||||
bool SoftFilename::
|
|
||||||
is_1_0() const {
|
|
||||||
nassertr(_has_version, false);
|
|
||||||
return (_major == 1 && _minor == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes this a 1_0 filename.
|
|
||||||
*/
|
|
||||||
void SoftFilename::
|
|
||||||
make_1_0() {
|
|
||||||
_has_version = true;
|
|
||||||
_major = 1;
|
|
||||||
_minor = 0;
|
|
||||||
_filename = get_1_0_filename();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this file has the same base and extension as the other,
|
|
||||||
* disregarding the version number; false otherwise.
|
|
||||||
*/
|
|
||||||
bool SoftFilename::
|
|
||||||
is_same_file(const SoftFilename &other) const {
|
|
||||||
return _base == other._base && _ext == other._ext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Puts filenames in order such that the files with the same base are sorted
|
|
||||||
* together, ignoring extension; and within files with the same base, files
|
|
||||||
* are sorted in decreasing version number order so that the most recent
|
|
||||||
* version appears first.
|
|
||||||
*/
|
|
||||||
bool SoftFilename::
|
|
||||||
operator < (const SoftFilename &other) const {
|
|
||||||
if (_base != other._base) {
|
|
||||||
return _base < other._base;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_has_version != other._has_version) {
|
|
||||||
// If one has a version and the other one doesn't, the one without a
|
|
||||||
// version comes first.
|
|
||||||
return _has_version < other._has_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_has_version) {
|
|
||||||
if (_major != other._major) {
|
|
||||||
return _major > other._major;
|
|
||||||
}
|
|
||||||
if (_minor != other._minor) {
|
|
||||||
return _minor > other._minor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the flag that indicates whether this file is known to be entered into
|
|
||||||
* the CVS database.
|
|
||||||
*/
|
|
||||||
void SoftFilename::
|
|
||||||
set_in_cvs(bool in_cvs) {
|
|
||||||
_in_cvs = in_cvs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this file is known to be entered in the CVS database, false
|
|
||||||
* if it is not.
|
|
||||||
*/
|
|
||||||
bool SoftFilename::
|
|
||||||
get_in_cvs() const {
|
|
||||||
return _in_cvs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the flag that indicates whether this file should be entered into the
|
|
||||||
* CVS database.
|
|
||||||
*/
|
|
||||||
void SoftFilename::
|
|
||||||
set_wants_cvs(bool wants_cvs) {
|
|
||||||
_wants_cvs = wants_cvs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this file should be entered into the CVS database, false
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
bool SoftFilename::
|
|
||||||
get_wants_cvs() const {
|
|
||||||
return _wants_cvs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that this filename is referenced by one more scene file.
|
|
||||||
*/
|
|
||||||
void SoftFilename::
|
|
||||||
increment_use_count() {
|
|
||||||
_use_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of scene files that referenced this filename.
|
|
||||||
*/
|
|
||||||
int SoftFilename::
|
|
||||||
get_use_count() const {
|
|
||||||
return _use_count;
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
/**
|
|
||||||
* PANDA 3D SOFTWARE
|
|
||||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
||||||
*
|
|
||||||
* All use of this software is subject to the terms of the revised BSD
|
|
||||||
* license. You should have received a copy of this license along
|
|
||||||
* with this source code in a file named "LICENSE."
|
|
||||||
*
|
|
||||||
* @file softFilename.h
|
|
||||||
* @author drose
|
|
||||||
* @date 2000-11-10
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOFTFILENAME_H
|
|
||||||
#define SOFTFILENAME_H
|
|
||||||
|
|
||||||
#include "pandatoolbase.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This encapsulates a SoftImage versioned filename, of the form base.v-v.ext:
|
|
||||||
* it consists of a directory name, a base, a major and minor version number,
|
|
||||||
* and an optional extension.
|
|
||||||
*
|
|
||||||
* It also keeps track of whether the named file has been added to CVS, and
|
|
||||||
* how many scene files it is referenced by,
|
|
||||||
*/
|
|
||||||
class SoftFilename {
|
|
||||||
public:
|
|
||||||
SoftFilename(const std::string &dirname, const std::string &filename);
|
|
||||||
SoftFilename(const SoftFilename ©);
|
|
||||||
void operator = (const SoftFilename ©);
|
|
||||||
|
|
||||||
const std::string &get_dirname() const;
|
|
||||||
const std::string &get_filename() const;
|
|
||||||
bool has_version() const;
|
|
||||||
|
|
||||||
std::string get_1_0_filename() const;
|
|
||||||
|
|
||||||
const std::string &get_base() const;
|
|
||||||
int get_major() const;
|
|
||||||
int get_minor() const;
|
|
||||||
const std::string &get_extension() const;
|
|
||||||
std::string get_non_extension() const;
|
|
||||||
|
|
||||||
bool is_1_0() const;
|
|
||||||
void make_1_0();
|
|
||||||
|
|
||||||
bool is_same_file(const SoftFilename &other) const;
|
|
||||||
bool operator < (const SoftFilename &other) const;
|
|
||||||
|
|
||||||
void set_in_cvs(bool in_cvs);
|
|
||||||
bool get_in_cvs() const;
|
|
||||||
|
|
||||||
void set_wants_cvs(bool wants_cvs);
|
|
||||||
bool get_wants_cvs() const;
|
|
||||||
|
|
||||||
void increment_use_count();
|
|
||||||
int get_use_count() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string _dirname;
|
|
||||||
std::string _filename;
|
|
||||||
bool _has_version;
|
|
||||||
std::string _base;
|
|
||||||
int _major;
|
|
||||||
int _minor;
|
|
||||||
std::string _ext;
|
|
||||||
bool _in_cvs;
|
|
||||||
bool _wants_cvs;
|
|
||||||
int _use_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
x
Reference in New Issue
Block a user