Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Albert Gräf
Gem
Commits
3a46c56d
Commit
3a46c56d
authored
Jan 31, 2019
by
IOhannes m zmölnig
Browse files
draft of [modelfiler]
parent
ca84e120
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/Controls/Makefile.am
View file @
3a46c56d
...
...
@@ -34,6 +34,8 @@ libControls_la_SOURCES= \
gemmanager.h
\
gemreceive.cpp
\
gemreceive.h
\
modelfiler.cpp
\
modelfiler.h
\
render_trigger.cpp
\
render_trigger.h
...
...
src/Controls/modelfiler.cpp
0 → 100644
View file @
3a46c56d
////////////////////////////////////////////////////////
//
// GEM - Graphics Environment for Multimedia
//
// zmoelnig@iem.at
//
// Implementation file
//
// Copyright (c) 1997-1999 Mark Danks.
// Copyright (c) Günther Geiger.
// Copyright (c) 2001-2011 IOhannes m zmölnig. forum::für::umläute. IEM. zmoelnig@iem.at
// For information on usage and redistribution, and for a DISCLAIMER OF ALL
// WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
//
/////////////////////////////////////////////////////////
#include "modelfiler.h"
#include "plugins/modelloader.h"
#include <algorithm> // std::min
#include "RTE/Array.h"
CPPEXTERN_NEW_WITH_GIMME
(
modelfiler
);
namespace
{
std
::
string
checkArrays
(
const
std
::
string
*
tablenames
,
size_t
count
)
{
gem
::
RTE
::
Array
a
;
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
if
(
!
a
.
name
(
tablenames
[
i
]))
return
tablenames
[
i
];
}
return
std
::
string
();
}
size_t
copyArrays
(
const
std
::
vector
<
std
::
vector
<
float
>
>&
data
,
const
std
::
string
*
tablenames
,
size_t
count
)
{
std
::
vector
<
gem
::
RTE
::
Array
>
tabs
;
size_t
size
=
data
.
size
();
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
gem
::
RTE
::
Array
a
(
tablenames
[
i
]);
a
.
resize
(
size
);
tabs
.
push_back
(
a
);
}
for
(
size_t
i
=
0
;
i
<
size
;
i
++
)
{
for
(
size_t
j
=
0
;
j
<
count
;
j
++
)
{
tabs
[
j
][
i
]
=
data
[
i
][
j
];
}
}
return
size
;
}
};
/////////////////////////////////////////////////////////
//
// modelfiler
//
/////////////////////////////////////////////////////////
// Constructor
//
/////////////////////////////////////////////////////////
modelfiler
::
modelfiler
(
int
argc
,
t_atom
*
argv
)
:
m_loader
(
gem
::
plugins
::
modelloader
::
getInstance
())
,
m_infoOut
(
gem
::
RTE
::
Outlet
(
this
))
{
}
/////////////////////////////////////////////////////////
// Destructor
//
/////////////////////////////////////////////////////////
modelfiler
::
~
modelfiler
(
void
)
{
if
(
m_loader
)
{
delete
m_loader
;
m_loader
=
NULL
;
}
}
static
gem
::
any
atom2any
(
t_atom
*
ap
)
{
gem
::
any
result
;
if
(
ap
)
{
switch
(
ap
->
a_type
)
{
case
A_FLOAT
:
result
=
atom_getfloat
(
ap
);
break
;
case
A_SYMBOL
:
result
=
std
::
string
(
atom_getsymbol
(
ap
)
->
s_name
);
break
;
default:
result
=
ap
->
a_w
.
w_gpointer
;
}
}
return
result
;
}
static
void
addProperties
(
gem
::
Properties
&
props
,
int
argc
,
t_atom
*
argv
)
{
if
(
!
argc
)
{
return
;
}
if
(
argv
->
a_type
!=
A_SYMBOL
)
{
error
(
"no key given..."
);
return
;
}
std
::
string
key
=
std
::
string
(
atom_getsymbol
(
argv
)
->
s_name
);
std
::
vector
<
gem
::
any
>
values
;
argc
--
;
argv
++
;
while
(
argc
-->
0
)
{
values
.
push_back
(
atom2any
(
argv
++
));
}
switch
(
values
.
size
())
{
default:
props
.
set
(
key
,
values
);
break
;
case
1
:
props
.
set
(
key
,
values
[
0
]);
break
;
case
0
:
{
gem
::
any
dummy
;
props
.
set
(
key
,
dummy
);
}
break
;
}
}
void
modelfiler
::
setPropertyMess
(
t_symbol
*
,
int
argc
,
t_atom
*
argv
)
{
if
(
!
argc
)
{
error
(
"no property specified!"
);
return
;
}
addProperties
(
m_readprops
,
argc
,
argv
);
if
(
m_loader
)
{
m_loader
->
setProperties
(
m_readprops
);
}
}
void
modelfiler
::
getPropertyMess
(
t_symbol
*
,
int
argc
,
t_atom
*
argv
)
{
if
(
argc
)
{
int
i
=
0
;
m_readprops
.
clear
();
for
(
i
=
0
;
i
<
argc
;
i
++
)
{
addProperties
(
m_readprops
,
1
,
argv
+
i
);
}
}
else
{
/* LATER: read all properties */
}
if
(
m_loader
)
{
m_loader
->
getProperties
(
m_readprops
);
std
::
vector
<
std
::
string
>
keys
=
m_readprops
.
keys
();
unsigned
int
i
=
0
;
for
(
i
=
0
;
i
<
keys
.
size
();
i
++
)
{
std
::
vector
<
gem
::
any
>
atoms
;
gem
::
any
value
;
std
::
string
key
=
keys
[
i
];
atoms
.
push_back
(
value
=
key
);
switch
(
m_readprops
.
type
(
key
))
{
default:
case
gem
::
Properties
::
UNSET
:
post
(
"oops: %s"
,
key
.
c_str
());
continue
;
case
gem
::
Properties
::
NONE
:
break
;
case
gem
::
Properties
::
DOUBLE
:
do
{
double
d
=
0
;
if
(
m_readprops
.
get
(
key
,
d
))
{
atoms
.
push_back
(
value
=
d
);
}
}
while
(
0
);
break
;
case
gem
::
Properties
::
STRING
:
do
{
std
::
string
s
;
if
(
m_readprops
.
get
(
key
,
s
))
{
atoms
.
push_back
(
value
=
s
);
}
}
while
(
0
);
break
;
}
m_infoOut
.
send
(
"prop"
,
atoms
);
}
}
else
{
verbose
(
1
,
"no open model loader...remembering properties..."
);
}
}
void
modelfiler
::
enumPropertyMess
()
{
if
(
m_loader
)
{
gem
::
Properties
readable
,
writeable
;
std
::
vector
<
std
::
string
>
readkeys
,
writekeys
;
std
::
vector
<
gem
::
any
>
data
;
gem
::
any
value
;
m_loader
->
enumProperties
(
readable
,
writeable
);
readkeys
=
readable
.
keys
();
data
.
clear
();
data
.
push_back
(
value
=
std
::
string
(
"numread"
));
data
.
push_back
(
value
=
(
int
)
readkeys
.
size
());
m_infoOut
.
send
(
"proplist"
,
data
);
unsigned
int
i
=
0
;
for
(
i
=
0
;
i
<
readkeys
.
size
();
i
++
)
{
std
::
string
key
=
readkeys
[
i
];
data
.
clear
();
data
.
push_back
(
value
=
std
::
string
(
"read"
));
data
.
push_back
(
key
);
switch
(
readable
.
type
(
key
))
{
case
gem
::
Properties
::
NONE
:
data
.
push_back
(
value
=
std
::
string
(
"bang"
));
break
;
case
gem
::
Properties
::
DOUBLE
:
{
double
d
=-
1
;
data
.
push_back
(
value
=
std
::
string
(
"float"
));
/* LATER: get and show ranges */
if
(
readable
.
get
(
key
,
d
))
{
data
.
push_back
(
value
=
d
);
}
}
break
;
case
gem
::
Properties
::
STRING
:
{
data
.
push_back
(
value
=
std
::
string
(
"symbol"
));
std
::
string
s
;
if
(
readable
.
get
(
key
,
s
))
{
data
.
push_back
(
value
=
s
);
}
}
break
;
default:
data
.
push_back
(
value
=
std
::
string
(
"unknown"
));
break
;
}
m_infoOut
.
send
(
"proplist"
,
data
);
}
writekeys
=
writeable
.
keys
();
data
.
clear
();
data
.
push_back
(
value
=
std
::
string
(
"numwrite"
));
data
.
push_back
(
value
=
(
int
)
writekeys
.
size
());
m_infoOut
.
send
(
"proplist"
,
data
);
for
(
i
=
0
;
i
<
writekeys
.
size
();
i
++
)
{
data
.
clear
();
data
.
push_back
(
value
=
std
::
string
(
"write"
));
std
::
string
key
=
writekeys
[
i
];
data
.
push_back
(
value
=
key
);
switch
(
writeable
.
type
(
key
))
{
case
gem
::
Properties
::
NONE
:
data
.
push_back
(
value
=
std
::
string
(
"bang"
));
break
;
case
gem
::
Properties
::
DOUBLE
:
{
double
d
=-
1
;
data
.
push_back
(
value
=
std
::
string
(
"float"
));
/* LATER: get and show ranges */
if
(
writeable
.
get
(
key
,
d
))
{
data
.
push_back
(
value
=
d
);
}
}
break
;
case
gem
::
Properties
::
STRING
:
{
data
.
push_back
(
value
=
std
::
string
(
"symbol"
));
std
::
string
s
;
if
(
writeable
.
get
(
key
,
s
))
{
data
.
push_back
(
value
=
s
);
}
}
break
;
default:
data
.
push_back
(
value
=
std
::
string
(
"unknown"
));
break
;
}
m_infoOut
.
send
(
"proplist"
,
data
);
}
}
else
{
error
(
"cannot enumerate properties without a valid model loader"
);
}
}
void
modelfiler
::
setPropertiesMess
(
t_symbol
*
,
int
argc
,
t_atom
*
argv
)
{
addProperties
(
m_readprops
,
argc
,
argv
);
}
void
modelfiler
::
applyProperties
()
{
if
(
m_loader
)
{
m_loader
->
setProperties
(
m_readprops
);
}
else
{
verbose
(
1
,
"no open model loader...remembering properties..."
);
}
}
void
modelfiler
::
clearPropertiesMess
()
{
m_readprops
.
clear
();
}
/////////////////////////////////////////////////////////
// backendMess
//
/////////////////////////////////////////////////////////
void
modelfiler
::
backendMess
(
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
)
{
m_backends
.
clear
();
if
(
argc
)
{
for
(
int
i
=
0
;
i
<
argc
;
i
++
)
{
if
(
A_SYMBOL
==
argv
->
a_type
)
{
t_symbol
*
b
=
atom_getsymbol
(
argv
+
i
);
m_backends
.
push_back
(
b
->
s_name
);
}
else
{
error
(
"%s must be symbolic"
,
s
->
s_name
);
}
}
}
else
{
/* no backend requested, just enumerate them */
if
(
m_loader
)
{
std
::
vector
<
gem
::
any
>
atoms
;
gem
::
any
value
;
t_atom
at
;
t_atom
*
ap
=&
at
;
gem
::
Properties
props
;
std
::
vector
<
std
::
string
>
backends
;
props
.
set
(
"backends"
,
value
);
m_loader
->
getProperties
(
props
);
if
(
props
.
type
(
"backends"
)
!=
gem
::
Properties
::
UNSET
)
{
props
.
get
(
"backends"
,
backends
);
}
atoms
.
clear
();
atoms
.
push_back
(
value
=
(
int
)(
backends
.
size
()));
m_infoOut
.
send
(
"loaders"
,
atoms
);
if
(
!
backends
.
empty
())
{
for
(
int
i
=
0
;
i
<
backends
.
size
();
i
++
)
{
atoms
.
clear
();
atoms
.
push_back
(
value
=
backends
[
i
]);
post
(
"loader[%d] %s"
,
i
,
backends
[
i
].
c_str
());
m_infoOut
.
send
(
"loader"
,
atoms
);
}
}
else
{
post
(
"no model-loading backends found!"
);
}
}
}
}
/////////////////////////////////////////////////////////
// openMess
//
/////////////////////////////////////////////////////////
void
modelfiler
::
openMess
(
const
std
::
string
&
filename
)
{
gem
::
Properties
wantProps
=
m_readprops
;
if
(
!
m_loader
)
{
error
(
"no model loader backends found"
);
return
;
}
if
(
!
m_backends
.
empty
())
{
wantProps
.
set
(
"backends"
,
m_backends
);
}
char
buf
[
MAXPDSTRING
];
canvas_makefilename
(
const_cast
<
t_canvas
*>
(
getCanvas
()),
const_cast
<
char
*>
(
filename
.
c_str
()),
buf
,
MAXPDSTRING
);
if
(
!
m_loader
->
open
(
buf
,
wantProps
))
{
error
(
"unable to read model '%s'"
,
buf
);
return
;
}
copyArrays
(
m_loader
->
getVector
(
"vertices"
),
m_position
,
3
);
copyArrays
(
m_loader
->
getVector
(
"texcoords"
),
m_texture
,
2
);
copyArrays
(
m_loader
->
getVector
(
"normals"
),
m_normal
,
3
);
copyArrays
(
m_loader
->
getVector
(
"colors"
),
m_color
,
4
);
m_loader
->
close
();
}
#if 0
void modelfiler :: copyArray(const std::vector<std::vector<float> >&tab,
std::string*tables)
{
unsigned int size(0), i(0), npts(0);
//~std::vector<std::vector<float> > tab = m_loader->getVector(vectorName);
if ( tab.empty() ) {
return;
}
size=tab.size();
if(size!=vb.size) {
vb.resize(size);
m_size_change_flag=true;
}
for ( i = 0 ; i < size ; i++ ) {
for ( int j=0 ; j< std::min(vb.dimen,(unsigned int)tab[i].size()) ; j++) {
vb.array[i*vb.dimen + j] = tab[i][j];
}
}
vb.dirty=true;
vb.enabled=true;
}
void modelfiler :: copyAllArrays()
{
if (m_loader && m_loader->needRefresh()) {
copyArray(m_loader->getVector("vertices"), m_position);
copyArray(m_loader->getVector("texcoords"), m_texture);
copyArray(m_loader->getVector("normals"), m_normal);
copyArray(m_loader->getVector("colors"), m_color);
m_loader->unsetRefresh();
}
}
#endif
/////////////////////////////////////////////////////////
// static member function
//
/////////////////////////////////////////////////////////
void
modelfiler
::
obj_setupCallback
(
t_class
*
classPtr
)
{
CPPEXTERN_MSG1
(
classPtr
,
"open"
,
openMess
,
std
::
string
);
CPPEXTERN_MSG
(
classPtr
,
"loader"
,
backendMess
);
CPPEXTERN_MSG
(
classPtr
,
"set"
,
setPropertyMess
);
CPPEXTERN_MSG
(
classPtr
,
"get"
,
getPropertyMess
);
CPPEXTERN_MSG
(
classPtr
,
"setProps"
,
setPropertiesMess
);
CPPEXTERN_MSG0
(
classPtr
,
"enumProps"
,
enumPropertyMess
);
CPPEXTERN_MSG0
(
classPtr
,
"clearProps"
,
clearPropertiesMess
);
}
src/Controls/modelfiler.h
0 → 100644
View file @
3a46c56d
/*-----------------------------------------------------------------
LOG
GEM - Graphics Environment for Multimedia
read in a model file
Copyright (c) 2019 IOhannes m zmölnig. forum::für::umläute. IEM. zmoelnig@iem.at
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
-----------------------------------------------------------------*/
#ifndef _INCLUDE__GEM_GEOS_MODELFILER_H_
#define _INCLUDE__GEM_GEOS_MODELFILER_H_
#include "Base/CPPExtern.h"
#include "Gem/Properties.h"
#include "RTE/Outlet.h"
#include <map>
/*-----------------------------------------------------------------
-------------------------------------------------------------------
CLASS
modelfiler
read in a model file
DESCRIPTION
Inlet for a list - "model"
"open" - the RGB model to set the object to
-----------------------------------------------------------------*/
namespace
gem
{
namespace
plugins
{
class
modelloader
;
};
};
class
GEM_EXTERN
modelfiler
:
public
CPPExtern
{
CPPEXTERN_HEADER
(
modelfiler
,
CPPExtern
);
public:
//////////
// Constructor
modelfiler
(
int
argc
,
t_atom
*
argv
);
protected:
//////////
// Destructor
virtual
~
modelfiler
(
void
);
//////////
// When an open is received
virtual
void
openMess
(
const
std
::
string
&
filename
);
virtual
void
enumPropertyMess
(
void
);
virtual
void
clearPropertiesMess
(
void
);
virtual
void
getPropertyMess
(
t_symbol
*
s
,
int
,
t_atom
*
);
virtual
void
setPropertyMess
(
t_symbol
*
s
,
int
,
t_atom
*
);
virtual
void
setPropertiesMess
(
t_symbol
*
,
int
,
t_atom
*
);
virtual
void
applyProperties
(
void
);
//////////
// Set backend to use
virtual
void
backendMess
(
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
);
gem
::
plugins
::
modelloader
*
m_loader
;
gem
::
Properties
m_readprops
;
std
::
string
m_position
[
3
];
std
::
string
m_texture
[
2
];
std
::
string
m_color
[
4
];
std
::
string
m_normal
[
3
];
gem
::
RTE
::
Outlet
m_infoOut
;
std
::
vector
<
std
::
string
>
m_backends
;
};
#endif // for header file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment