To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.cad.devOpen lugnet.cad.dev in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 CAD / Development / 9630
Subject: 
LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Mon, 15 Mar 2004 23:30:28 GMT
Viewed: 
4894 times
  
Here are my ideas of an API for accessing the LDrawIni settings.

The basic idea is that it should be very simple to use, there are only four functions
and a data structure declaration.

First you call LDrawIniGet to read and initialize all relevant ldraw.ini data,
the LDrawDir, the search directories, the LGEO directory.
The data is initialized from environment variables and/or ini files
suitable for the platform you are running and in the agreed order.

L3P, as an example, will now look for the model in each of the search dirs.
When found L3P calls LDrawIniComputeRealDirs with the directory of the model.
This will recalculate the search dirs in the data structure to include those with <MODELDIR>.
L3P will now (probably) have an extra search dir to look in for the remaining loading of parts.
(directories marked with <SKIP> will of course be excluded from the search dirs)

For each search dir there may be a number of flags. The known ones are parsed into bit-flags
to speed up testing (e.g. LDSDF_HIDE|LDSDF_DEFPRIM), the remaining are available
as a string, e.g "<MyFlag><UnknownFlag>".
(or would you like a NULL terminated array of strings?)

When finding a file in one of the search dirs and the file has no official header
L3P can quickly determine whether the default filetype is e.g. Primitive.

When done L3P calls LDrawIniFree to release the data structure.

L3Lab works the same way, only it calls LDrawIniComputeRealDirs
whenever a new model is loaded.

The last function is LDrawIniResetSearchDirs, only to be called from the
LDrawSetup program - or if you wish to override the search to be the
standard one.


In C (not C++ for greatest compatibility) it may look like this, LDrawIni.h:

struct LDrawSearchDirS
{
   int            Flags;        /* Parsed and known flags LDSDF_XXX          */
   char          *UnknownFlags; /* Any unknown flags <XXX>                   */
   char          *Dir;          /* The full path of a search dir             */
};

struct LDrawIniS
{
   /* The LDRAWDIR containing the P, PARTS and MODELS directories */
   char          *LDrawDir;

   /* The LDrawSearch directories ready to use */
   int            nSearchDirs;
   struct LDrawSearchDirS *SearchDirs;

   /* The LGEODIR (named LGEO) containing the LGEO .inc files */
   char          *LgeoDir;

   /* Private date for the LDrawIni routines */
   struct LDrawIniPrivateDataS *PrivateData;
};

/* LDrawSearchDir Flags */
#define LDSDF_HIDE     0x0001   /* Hide directory                            */
#define LDSDF_DEFPART  0x0002   /* Default filetype: Part                    */
#define LDSDF_DEFPRIM  0x0004   /* Default filetype: Primitive               */

#ifdef __cplusplus
extern "C" {
#endif

/*
Initialize and read all settings.
If the argument LDrawDir is not NULL
it will override the normal initialization of the LDraw directory.
If ErrorCode is not NULL it will return a code telling why
LDrawIniGet returned NULL.
If all is OK then a pointer to struct LDrawIniS is returned.
You should then call LDrawIniComputeRealDirs to obtain the search dirs.
Remember to free the struct by calling LDrawIniFree.
*/
struct LDrawIniS *LDrawIniGet(const char *LDrawDir, int *ErrorCode);
/*
Compute Real Dirs by substituting <LDRAWDIR> and <MODELDIR> in
the Symbolic Dirs read from the env vars or ini files.
If OnlyValidDirs is true then non-existing search dirs is skipped
If AddTrailingSlash is true then the search dirs will have a slash/backslash appended.
If ModelDir is NULL then search dir <MODELDIR> is skipped.
Returns 1 if OK, 0 on error
*/
int LDrawIniComputeRealDirs(struct LDrawIniS * LDrawIni,
                            int OnlyValidDirs,
                            int AddTrailingSlash,
                            const char *ModelDir);
/*
Reset search dirs to default if LDrawSearch is NULL
or to the dirs specified in LDrawSearch delimited by |.
Returns 1 if OK, 0 on error
*/
int LDrawIniResetSearchDirs(struct LDrawIniS * LDrawIni,
                            const char *LDrawSearch);
/*
Free the LDrawIni data
*/
   void LDrawIniFree(struct LDrawIniS * LDrawIni);

#ifdef __cplusplus
}
#endif

/* Error codes returned by LDrawIniGet */
#define LDRAWINI_ERROR_OUT_OF_MEMORY     1
#define LDRAWINI_ERROR_LDRAWDIR_NOT_SET  2

(end of LDrawIni.h)

The LDrawSetup program would like to have access to the private data
and to some internal (static) functions for reading ini files and parsing,
so I am thinking of an additional include file, LDrawIniP.h:

struct LDrawIniPrivateDataS
{
   /* The LDrawSearch directories as read */
   int            nSymbolicSearchDirs;
   char         **SymbolicSearchDirs;
};

some reading/parsing functions

(end of LDrawIniP.h)

I have currently tested the functions in L3P on Windows and will shortly test on Linux.
I had to rearrange some code in L3P now that you can't be sure
that the <MODELDIR> is the first search dir...

The L3P usage of the LDrawIni API is:

   LDrawIni = LDrawIniGet(NULL, &LDrawIniErrorCode);
   if (!LDrawIni)
   {
      if (LDrawIniErrorCode == LDRAWINI_ERROR_LDRAWDIR_NOT_SET)
      {
         /* Neither environment variable, nor ldraw.ini, simply try current dir */
         if (IsDir("P") && IsDir("PARTS") && IsDir("MODELS"))
            LDrawIni = LDrawIniGet(".", &LDrawIniErrorCode);
      }
   }
   if (!LDrawIni)
   {
      Exit("\
Environment variable LDRAWDIR must be set to directory with P,PARTS,MODELS.\n\
e.g.  'set LDRAWDIR=c:\\Lego\\LDraw'       (don't use long names)\n\
You may type the set command at the DOS prompt or put it into C:\\AUTOEXEC.BAT", NULL);
   }

   if (L3Pov.UseLgeoParts && !LDrawIni->LgeoDir)
   {
      Exit("\
Environment variable LGEODIR must be set to directory with LGEO parts.\n\
e.g.  'set LGEODIR=c:\\Lego\\LGEO'       (don't use long names)\n\
You may type the set command at the DOS prompt or put it into C:\\AUTOEXEC.BAT", NULL);
   }

   i = LDrawIniComputeRealDirs(LDrawIni, 1, 1, NULL);
   if (!i)
      Exit("Failed to compute search dirs", NULL);

   fp = OpenDatFile(ModelFilename, 1);
   if (!fp)
      Exit("Cannot find model file '%s'", ModelFilename);
   fclose(fp);

Preparing load of model:
   strcpy(ModelDir, lpszPathName);
   for (i = strlen(ModelDir); --i >= 0;)
      if (ModelDir[i] == '/' || ModelDir[i] == '\\')
         break;
   ModelDir[i<0? 0 : i] = '\0';     /* ModelDir may be empty.          */
   if (!LDrawIniComputeRealDirs(LDrawIni, 1, 1, ModelDir))
      return -1;

And when loading DAT files:

static int FileIsFromP;
static int FileIsFromPARTS;
static FILE *OpenDatFile2(char *DatName, char *Extension)
{
   FILE          *fp;
   register int   i;

   for (i = 0; i < LDrawIni->nSearchDirs; i++)
   {
      strcpy(DatPath, LDrawIni->SearchDirs[i].Dir); /* Has trailing \ */
      strcat(DatPath, DatName);
      strcat(DatPath, Extension);
      FileIsFromP = (LDrawIni->SearchDirs[i].Flags & LDSDF_DEFPRIM) ? 1 : 0;
      FileIsFromPARTS = (LDrawIni->SearchDirs[i].Flags & LDSDF_DEFPART) ? 1 : 0;
      fp = fopeni(DatPath, "rb");
      if (fp)
         return fp;
   }
   return NULL;
}
FILE *OpenDatFile(char *DatName, int IsModel)
{
   static char *Extensions[] = { "", ".ldr", ".dat", ".mpd" };
   int i;
   FILE          *fp;

   if (IsModel)
   {
      /* Be sure to load model; can't be sure <MODELDIR> is in search dirs */
      strcpy(DatPath, ModelDir); /* ModelDir may be "" */
      if (DatPath[0])
         strcat(DatPath, BACKSLASH_STRING);
      strcat(DatPath, DatName);
      FileIsFromP = 0;
      FileIsFromPARTS = 0;
      fp = fopeni(DatPath, "rb");
      if (fp)
         return fp;
   }
   for (i = 0; i < sizeof(Extensions)/sizeof(char *); i++)
   {
      fp = OpenDatFile2(DatName, Extensions[i]);
      if (fp)
         return fp;
   }
   return NULL;
}


I hope the above gives you an idea of how to use the LDrawIni API in your program.
Let me know if you have other wishes I haven't thought of.

After a little more testing I'll soon publish LDrawIni.c.
I'll make an HTML page describing the functionlity,
the env var and ini file order, the format and the API.
/Lars


Subject: 
Re: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Tue, 16 Mar 2004 16:43:15 GMT
Viewed: 
3765 times
  
In lugnet.cad.dev, Lars C. Hassing wrote:
Here are my ideas of an API for accessing the LDrawIni settings.

<Snip ideas>

Here are a few random thoughts on those ideas...

I haven't thought about it enough to decide if I have a preference
on the format of the UnknownFlags.  Either way seems ok to me.

If directories marked with <SKIP> are excluded from the search dirs,
how would I temporarily enable a <SKIP> directory?  It looks like I might
be able to go into the PrivateData struct to find it.  Then perhaps build
up a | delimited string from the SymbolicSearchDirs, except with the <SKIP>
tag removed from the newly enabled directory.  Finally pass this string to
LDrawIniResetSearchDirs() and rerun LDrawIniComputeRealDirs() on the
modified LdrawIniS struct.  So maybe the PrivateData really shouldn't
be all that private.

I mentioned this before but apparently nobody noticed. :^) How about
having LDrawIniComputeRealDirs() also substitute the value of
%USERPROFILE% or $HOME for a <HOMEDIR> tag?  That way I can have a
platform independent way of pointing to part directories in my home
directory from a centralized ldraw.ini file on the network.  Or a
single ldraw.ini file on a dual boot PC.

Perhaps the PrivateData should tell where the info came from:  what ini
file, environment vars, or LdrawIniResetSearchDirs().  (I'm not actually
sure I need to know unless I'm planning on saving ini modifications.)

Are you planning on making a similar API for creating or modifying and
saving the ini file?  I'll probably try to use the LdrawSetup program
as an LDDP style plugin, but others may want to incorporate it directly
into their programs.

I see you've included the LGEODIR.  Have you given any thought to
making this extensible beyond that?  We might someday like to be able
to locate some other ldraw part conversion library via the ldraw.ini
file.  For example the LDRAWPOV library.  Could LDrawIniGet() be
extended to handle this, or would a more generic function be better.

char *LDrawIniGetVar(const char *LdrawDir, char *VarName, int *ErrorCode);

LgeoDir = LdrawIniGetVar(NULL, "LgeoDirectory", &err);
ldrawpovDir = LdrawIniGetVar(NULL, "LdrawpovDir", &err);


Enjoy,

Don


Subject: 
Re: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Tue, 16 Mar 2004 22:57:16 GMT
Viewed: 
3673 times
  
In lugnet.cad.dev, Don Heyse wrote:
In lugnet.cad.dev, Lars C. Hassing wrote:
Here are my ideas of an API for accessing the LDrawIni settings.

<Snip ideas>

Here are a few random thoughts on those ideas...

I haven't thought about it enough to decide if I have a preference
on the format of the UnknownFlags.  Either way seems ok to me.

If directories marked with <SKIP> are excluded from the search dirs,
how would I temporarily enable a <SKIP> directory?

By modifying ldraw.ini or setting an env var.
Why would you want to enable a <SKIP> dir from within a program?

I mentioned this before but apparently nobody noticed. :^) How about
having LDrawIniComputeRealDirs() also substitute the value of
%USERPROFILE% or $HOME for a <HOMEDIR> tag?  That way I can have a
platform independent way of pointing to part directories in my home
directory from a centralized ldraw.ini file on the network.  Or a
single ldraw.ini file on a dual boot PC.

I did notice, but forgot it, sorry.
%USERPROFILE% or $HOME for <HOMEDIR>, OK fine with me.

Perhaps the PrivateData should tell where the info came from:  what ini
file, environment vars, or LdrawIniResetSearchDirs().  (I'm not actually
sure I need to know unless I'm planning on saving ini modifications.)

Yes, I actually thought of adding
   char          *LDrawDirSource;
   char          *SearchDirsSource;
   char          *LgeoDirSource;
strings you could use for e.g. debugging.
L3P could print them in the POV header.
Any interest?

Are you planning on making a similar API for creating or modifying and
saving the ini file?  I'll probably try to use the LdrawSetup program
as an LDDP style plugin, but others may want to incorporate it directly
into their programs.

You can copy'n'paste the dialog resources and the corresponding
.h and .cpp files from the LDrawSetup project (VC6) into your program,
or you can simply launch LDrawSetup.

I see you've included the LGEODIR.  Have you given any thought to
making this extensible beyond that?  We might someday like to be able
to locate some other ldraw part conversion library via the ldraw.ini
file.  For example the LDRAWPOV library.  Could LDrawIniGet() be
extended to handle this, or would a more generic function be better.

char *LDrawIniGetVar(const char *LdrawDir, char *VarName, int *ErrorCode);

LgeoDir = LdrawIniGetVar(NULL, "LgeoDirectory", &err);
ldrawpovDir = LdrawIniGetVar(NULL, "LdrawpovDir", &err);

I had my doubts about whether to include LgeoDir or not.
I know that probably only L3P uses it, but the structure could/should contain
all data found in ldraw.ini?
In that case you would simply publish an update of the LDrawIni source code
supporting the LdrawpovDir.
However, LDrawIniGetVar is a good idea for not very common variables.
More arguments could be: const char *EnvVar, char **Source

I'm open to both.
/Lars


Subject: 
Re: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Thu, 18 Mar 2004 19:57:49 GMT
Viewed: 
3750 times
  
"Lars C. Hassing" <sp.lars@am.hassings.dk> schrieb im Newsbeitrag
news:Hun57C.1xM8@lugnet.com...
Here are my ideas of an API for accessing the LDrawIni settings.

The basic idea is that it should be very simple to use, there are only • four functions
and a data structure declaration.

First you call LDrawIniGet to read and initialize all relevant ldraw.ini • data,
the LDrawDir, the search directories, the LGEO directory.
The data is initialized from environment variables and/or ini files
suitable for the platform you are running and in the agreed order.

L3P, as an example, will now look for the model in each of the search • dirs.
When found L3P calls LDrawIniComputeRealDirs with the directory of the • model.
This will recalculate the search dirs in the data structure to include • those with <MODELDIR>.
L3P will now (probably) have an extra search dir to look in for the • remaining loading of parts.
(directories marked with <SKIP> will of course be excluded from the search
dirs)

Don mentioned that already, it would be good to enable <SKIP> from the
programm. Imagine an
alternate set of files with <SKIP> flag before official ones. When the user
can enable/disable the SKIP
detection, the user can see the different view without to modify any ini
file - on some systems users
might not be able to modify these files (e.g. when running with a guest
account).


For each search dir there may be a number of flags. The known ones are • parsed into bit-flags
to speed up testing (e.g. LDSDF_HIDE|LDSDF_DEFPRIM), the remaining are • available
as a string, e.g "<MyFlag><UnknownFlag>".
(or would you like a NULL terminated array of strings?)

I would prefere the current variant, as this allows quick searching for
flags using just one standard function call.


When finding a file in one of the search dirs and the file has no official • header
L3P can quickly determine whether the default filetype is e.g. Primitive.

When done L3P calls LDrawIniFree to release the data structure.

L3Lab works the same way, only it calls LDrawIniComputeRealDirs
whenever a new model is loaded.

The last function is LDrawIniResetSearchDirs, only to be called from the
LDrawSetup program - or if you wish to override the search to be the
standard one.


Do we have to call LDrawIniResetSearchDirs before each call to
LDrawIniComputeRealDirs?

<SNIP>

static int FileIsFromP;
static int FileIsFromPARTS;
static FILE *OpenDatFile2(char *DatName, char *Extension)
{
   FILE          *fp;
   register int   i;

   for (i = 0; i < LDrawIni->nSearchDirs; i++)
   {
      strcpy(DatPath, LDrawIni->SearchDirs[i].Dir); /* Has trailing \ */
      strcat(DatPath, DatName);
      strcat(DatPath, Extension);
      FileIsFromP = (LDrawIni->SearchDirs[i].Flags & LDSDF_DEFPRIM) ? 1 : • 0;
      FileIsFromPARTS = (LDrawIni->SearchDirs[i].Flags & LDSDF_DEFPART) ? • 1 : 0;
      fp = fopeni(DatPath, "rb");
      if (fp)
         return fp;
   }
   return NULL;
}
FILE *OpenDatFile(char *DatName, int IsModel)
{
   static char *Extensions[] = { "", ".ldr", ".dat", ".mpd" };
   int i;
   FILE          *fp;

   if (IsModel)
   {
      /* Be sure to load model; can't be sure <MODELDIR> is in search dirs • */
      strcpy(DatPath, ModelDir); /* ModelDir may be "" */
      if (DatPath[0])
         strcat(DatPath, BACKSLASH_STRING);
      strcat(DatPath, DatName);
      FileIsFromP = 0;
      FileIsFromPARTS = 0;
      fp = fopeni(DatPath, "rb");
      if (fp)
         return fp;
   }
   for (i = 0; i < sizeof(Extensions)/sizeof(char *); i++)
   {
      fp = OpenDatFile2(DatName, Extensions[i]);
      if (fp)
         return fp;
   }
   return NULL;
}

Don't you ever need FileIsFrom* flags when processing the files themself? If
you use global variables you cannot tell, which flag belongs to which file?!

These library is ideal for me at least, and I like this suggestion. Well
done Lars!

Is there any interest out there on a c++ class? If yes, I'll write a well
documented one otherwice I do the quick and dirty way without comments and
documentation :-)

Michael


Subject: 
Re: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Thu, 18 Mar 2004 22:06:09 GMT
Viewed: 
3769 times
  
In lugnet.cad.dev, Michael Lachmann wrote:
Don mentioned that already, it would be good to enable <SKIP> from the
programm. Imagine an alternate set of files with <SKIP> flag before
official ones. When the user can enable/disable the SKIP detection,
the user can see the different view without to modify any ini file
- on some systems users might not be able to modify these files
(e.g. when running with a guest account).

OK, <SKIP> will be parsed into a bit-flag LDSDF_SKIP and LDrawIniComputeRealDirs
will have an extra parameter to include/exclude <SKIP> dirs:
KeepSkippedDirs, IncludeSkipDirs, DontSkipDirs, ExcludeSkipDirs, SkipSkipDirs
- please come up with a good name...

The last function is LDrawIniResetSearchDirs, only to be called from the
LDrawSetup program - or if you wish to override the search to be the
standard one.


Do we have to call LDrawIniResetSearchDirs before each call to
LDrawIniComputeRealDirs?

No. It is needed in LDrawSetup for a "Reset to default" button.
However, you may use it too if you wish to discard the search dirs
loaded by LDrawIniGet from the ini file and use the default search dirs in stead.


Don't you ever need FileIsFrom* flags when processing the files themself? If
you use global variables you cannot tell, which flag belongs to which file?!

Well, I call OpenDatFile and right after I use the FileIsFrom* flags.
However, L3P also calls OpenDatFile in other contexts (e.g. l3p -check)
where the default part type is irrelevant.
But I know it's bad design, I'll pass it as parameters in stead.

These library is ideal for me at least, and I like this suggestion. Well
done Lars!

Thanks, I'm glad you like it.

Is there any interest out there on a c++ class? If yes, I'll write a well
documented one otherwice I do the quick and dirty way without comments and
documentation :-)

:-) As mentioned earlier I need to stick to C code, but you are welcome.
/Lars


Subject: 
Re: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Fri, 19 Mar 2004 20:19:19 GMT
Viewed: 
3844 times
  
"Lars C. Hassing" <sp.lars@am.hassings.dk> schrieb im Newsbeitrag
news:HusLAn.8Cz@lugnet.com...
In lugnet.cad.dev, Michael Lachmann wrote: • <SNIP>
OK, <SKIP> will be parsed into a bit-flag LDSDF_SKIP and • LDrawIniComputeRealDirs
will have an extra parameter to include/exclude <SKIP> dirs:
KeepSkippedDirs, IncludeSkipDirs, DontSkipDirs, ExcludeSkipDirs, • SkipSkipDirs
- please come up with a good name...

I don't realy care but IncludeSkipDirs sounds reasonable.


The last function is LDrawIniResetSearchDirs, only to be called from • the
LDrawSetup program - or if you wish to override the search to be the
standard one.


Do we have to call LDrawIniResetSearchDirs before each call to
LDrawIniComputeRealDirs?

No. It is needed in LDrawSetup for a "Reset to default" button.
However, you may use it too if you wish to discard the search dirs
loaded by LDrawIniGet from the ini file and use the default search dirs in
stead.

That means LDrawIniComputeRealDirs will reset the paths to the original
loaded ones,
than take care of model path and eventually the IncludeSkipDirs flag, right?

Is there any interest out there on a c++ class? If yes, I'll write a • well
documented one otherwice I do the quick and dirty way without comments • and
documentation :-)

:-) As mentioned earlier I need to stick to C code, but you are welcome.
/Lars


Ok, so if you are ready I will add a wrapper class to you library ...

Michael


Subject: 
Re: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Sun, 21 Mar 2004 14:03:09 GMT
Viewed: 
4029 times
  
In lugnet.cad.dev, Michael Lachmann wrote:
"Lars C. Hassing" <sp.lars@am.hassings.dk> schrieb:
OK, <SKIP> will be parsed into a bit-flag LDSDF_SKIP and
LDrawIniComputeRealDirs will have an extra parameter to
include/exclude <SKIP> dirs: KeepSkippedDirs, IncludeSkipDirs,
DontSkipDirs, ExcludeSkipDirs, SkipSkipDirs - please come up with a
good name...

I don't realy care but IncludeSkipDirs sounds reasonable.

I like the LDSDF_SKIP bit-flag but I don't think we need to add a
parameter to to LDrawIniComputeRealDirs().  Here's why.  The parameter
would make it all or nothing for skipped dirs.  I'd rather toggle the
LDSDF_SKIP bit-flags of some of the directories myself before calling
LDrawIniComputeRealDirs(), because I envision the need for several
distinct groups of skip dirs.  Imagine some skip dirs are sorted into
groups by the "unknown" flags:

  <group unofficial>
  <group bfc>
  <group boxes>
  <group clones>

Maybe I should be really specific and call them skipgroups.  I don't
know yet.  Anyhow, I can easily imagine a scenario where I want to
temporarily enable the unofficial parts, but not the rest.

The only problem with my new approach is I have to remember which
directories I toggled the bit-flag in so I can undo it later.  Yeah, I
know the original information is still in the private data.  Perhaps
instead of a global parameter, you could add another bit-flag for each
directory called LDSF_INCLUDE_SKIP that I could toggle before calling
LDrawIniComputeRealDirs().  Then I could write a quick function to
clear all the LDSF_INCLUDE_SKIP flags, before I set the ones I want
(if any) and call LDrawIniComputeRealDirs().

Don


Subject: 
Re: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Tue, 23 Mar 2004 22:28:20 GMT
Viewed: 
3797 times
  
In lugnet.cad.dev, Michael Lachmann wrote:
Do we have to call LDrawIniResetSearchDirs before each call to
LDrawIniComputeRealDirs?

No. It is needed in LDrawSetup for a "Reset to default" button.
However, you may use it too if you wish to discard the search dirs
loaded by LDrawIniGet from the ini file and use the default search dirs in
stead.

That means LDrawIniComputeRealDirs will reset the paths to the original loaded ones,
than take care of model path and eventually the IncludeSkipDirs flag, right?

Right.
/Lars


Subject: 
Re: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Tue, 23 Mar 2004 22:40:37 GMT
Viewed: 
4010 times
  
In lugnet.cad.dev, Don Heyse wrote:
I like the LDSDF_SKIP bit-flag but I don't think we need to add a
parameter to to LDrawIniComputeRealDirs().

The idea was to make it simple for ordinary usage.
I guess most programs would call LDrawIniComputeRealDirs() with
IncludeSkipDirs=0 and simply search the dirs returned.

However, you can call LDrawIniComputeRealDirs with IncludeSkipDirs=1
and then postprocess the search dirs at your liking
building your own new array of search dirs.
I follow your idea but I think it goes beyond the simple scope.
/Lars


Subject: 
Re: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Wed, 24 Mar 2004 15:21:25 GMT
Viewed: 
4075 times
  
In lugnet.cad.dev, Lars C. Hassing wrote:
In lugnet.cad.dev, Don Heyse wrote:
I like the LDSDF_SKIP bit-flag but I don't think we need to add a
parameter to to LDrawIniComputeRealDirs().

The idea was to make it simple for ordinary usage.
I guess most programs would call LDrawIniComputeRealDirs() with
IncludeSkipDirs=0 and simply search the dirs returned.

However, you can call LDrawIniComputeRealDirs with IncludeSkipDirs=1
and then postprocess the search dirs at your liking
building your own new array of search dirs.
I follow your idea but I think it goes beyond the simple scope.

Hmmm, POSTprocess eh?  Yes, I think that'll work just fine.  Now why
didn't I think of it...

Thanks Lars,

Don


Subject: 
Dear LSC, was: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Mon, 9 Jul 2007 16:56:47 GMT
Viewed: 
7241 times
  
In lugnet.cad.dev, Lars C. Hassing wrote:
In lugnet.cad.dev, Michael Lachmann wrote:
Don mentioned that already, it would be good to enable <SKIP> from the
programm. Imagine an alternate set of files with <SKIP> flag before
official ones. When the user can enable/disable the SKIP detection,
the user can see the different view without to modify any ini file
- on some systems users might not be able to modify these files
(e.g. when running with a guest account).

OK, <SKIP> will be parsed into a bit-flag LDSDF_SKIP and LDrawIniComputeRealDirs
will have an extra parameter to include/exclude <SKIP> dirs:
KeepSkippedDirs, IncludeSkipDirs, DontSkipDirs, ExcludeSkipDirs, SkipSkipDirs
- please come up with a good name...

The last function is LDrawIniResetSearchDirs, only to be called from the
LDrawSetup program - or if you wish to override the search to be the
standard one.


Do we have to call LDrawIniResetSearchDirs before each call to
LDrawIniComputeRealDirs?

No. It is needed in LDrawSetup for a "Reset to default" button.
However, you may use it too if you wish to discard the search dirs
loaded by LDrawIniGet from the ini file and use the default search dirs in stead.


Don't you ever need FileIsFrom* flags when processing the files themself? If
you use global variables you cannot tell, which flag belongs to which file?!

Well, I call OpenDatFile and right after I use the FileIsFrom* flags.
However, L3P also calls OpenDatFile in other contexts (e.g. l3p -check)
where the default part type is irrelevant.
But I know it's bad design, I'll pass it as parameters in stead.

These library is ideal for me at least, and I like this suggestion. Well
done Lars!

Thanks, I'm glad you like it.

Is there any interest out there on a c++ class? If yes, I'll write a well
documented one otherwice I do the quick and dirty way without comments and
documentation :-)

:-) As mentioned earlier I need to stick to C code, but you are welcome.
/Lars

Dear LSC,

  I examined the LDraw website and was unable to find formalization for the
support of optional part paths.  I'm updating LPub and would like to include
support for this concept of alternate paths for LDraw parts.  The PRE and POST
concepts make sense to me.

  Parts authors would want PRE to point to directories where they have updated
or new parts.

  Mere mortal users would want POST to point to the directories where the
unofficial parts are stored.

  The above implementation seems Windows environment specific. Could we possibly
have a more platform independent method?  It would seem that this is best
specified outside an LDraw file because not all people will have their parts
directories organized the same way.

  One simple implementation would be to simply to specify the name of official
directories for pre and post.  This way we would not need a separate method and
data files for specifying and accessing this information.  The unofficial parts
bulk package would dump its files into post.

  Could we get a formal specification for this>

Keep up the good work and thanks,
Kevin


Subject: 
Re: Dear LSC, was: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Mon, 9 Jul 2007 17:19:59 GMT
Viewed: 
7354 times
  
----- Original Message -----
From: "Kevin L. Clague" <kevin_clague@yahoo.com>
To: <lugnet.cad.dev@lugnet.com>
Sent: Monday, July 09, 2007 5:56 PM
Subject: Dear LSC, was: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS -
additional search paths)


In lugnet.cad.dev, Lars C. Hassing wrote:
In lugnet.cad.dev, Michael Lachmann wrote:
Don mentioned that already, it would be good to enable <SKIP> from the
programm. Imagine an alternate set of files with <SKIP> flag before
official ones. When the user can enable/disable the SKIP detection,
the user can see the different view without to modify any ini file
- on some systems users might not be able to modify these files
(e.g. when running with a guest account).

OK, <SKIP> will be parsed into a bit-flag LDSDF_SKIP and
LDrawIniComputeRealDirs
will have an extra parameter to include/exclude <SKIP> dirs:
KeepSkippedDirs, IncludeSkipDirs, DontSkipDirs, ExcludeSkipDirs,
SkipSkipDirs
- please come up with a good name...

The last function is LDrawIniResetSearchDirs, only to be called from
the
LDrawSetup program - or if you wish to override the search to be the
standard one.


Do we have to call LDrawIniResetSearchDirs before each call to
LDrawIniComputeRealDirs?

No. It is needed in LDrawSetup for a "Reset to default" button.
However, you may use it too if you wish to discard the search dirs
loaded by LDrawIniGet from the ini file and use the default search dirs
in stead.


Don't you ever need FileIsFrom* flags when processing the files
themself? If
you use global variables you cannot tell, which flag belongs to which
file?!

Well, I call OpenDatFile and right after I use the FileIsFrom* flags.
However, L3P also calls OpenDatFile in other contexts (e.g. l3p -check)
where the default part type is irrelevant.
But I know it's bad design, I'll pass it as parameters in stead.

These library is ideal for me at least, and I like this suggestion. Well
done Lars!

Thanks, I'm glad you like it.

Is there any interest out there on a c++ class? If yes, I'll write a
well
documented one otherwice I do the quick and dirty way without comments
and
documentation :-)

:-) As mentioned earlier I need to stick to C code, but you are welcome.
/Lars

Dear LSC,

I examined the LDraw website and was unable to find formalization for the
support of optional part paths.  I'm updating LPub and would like to
include
support for this concept of alternate paths for LDraw parts.  The PRE and
POST
concepts make sense to me.

Parts authors would want PRE to point to directories where they have
updated
or new parts.

Mere mortal users would want POST to point to the directories where the
unofficial parts are stored.

The above implementation seems Windows environment specific. Could we
possibly
have a more platform independent method?  It would seem that this is best
specified outside an LDraw file because not all people will have their
parts
directories organized the same way.

One simple implementation would be to simply to specify the name of
official
directories for pre and post.  This way we would not need a separate
method and
data files for specifying and accessing this information.  The unofficial
parts
bulk package would dump its files into post.

Could we get a formal specification for this>

Keep up the good work and thanks,
Kevin


How do these differ from an official "unofficial" sub-directory? - see
http://news.lugnet.com/cad/dev/mac/?n=768

The LSC has already voted against having a formal "unofficial"
sub-directory, prefering to leave it to software authors, so we may take
some convincing.

From a programming point of view, so long as you read PRE and POST from some
system (environment) variables you should be platform independant as both
Windows and Unix support them.


Subject: 
Convention for directoried for unofficial parts?
Newsgroups: 
lugnet.cad.dev
Date: 
Mon, 9 Jul 2007 18:27:30 GMT
Viewed: 
7413 times
  
To all developers,

  The LSC does not want to specify how unofficial parts are handled.  Personally
if find the recommendation that we pull down individual unofficial parts into
the same directory as our LDraw file a hassle.

  Would the group prefer environment variables that provide paths for
directories, or known subdirectory names?

  I think that for the novice user, known subdirectory names would be simplest.
For advanced users environment variables provide the most control.

  I could see implementing both.  "unofficial" for parts that are not officially
released for the simple user and environment variables for part authors and
advanced users.  We could use LDRAWPREDIRS and LDRAWPOSTDIRS for the environment
variables.

  So, this convention can only work for a given user if all the tools they use
follow the convention.

  Unless someone comes up with an alternate plan, I will implement this in LPub.
I believe that I can compensate for L3P and the renderers by substituting parts
found in alternate paths with their full file system path name before handing
off the generated LDraw file to them.

  PLMKWYT

Kevin


Subject: 
Convention for directories for unofficial parts?
Newsgroups: 
lugnet.cad.dev
Date: 
Mon, 9 Jul 2007 18:29:15 GMT
Viewed: 
7361 times
  
To all developers,

  The LSC does not want to specify how unofficial parts are handled.  Personally
if find the recommendation that we pull down individual unofficial parts into
the same directory as our LDraw file a hassle.

  Would the group prefer environment variables that provide paths for
directories, or known subdirectory names?

  I think that for the novice user, known subdirectory names would be simplest.
For advanced users environment variables provide the most control.

  I could see implementing both.  "unofficial" subdirectory for parts that are
not officially released for the simple user and environment variables for part
authors and advanced users.  We could use LDRAWPREDIRS and LDRAWPOSTDIRS for the
environment variables.

  So, this convention can only work for a given user if all the tools they use
follow the convention.

  Unless someone comes up with an alternate plan, I will implement this in LPub.
I believe that I can compensate for L3P and the renderers by substituting parts
found in alternate paths with their full file system path name before handing
off the generated LDraw file to them.

  PLMKWYT

Kevin


Subject: 
Re: Convention for directoried for unofficial parts?
Newsgroups: 
lugnet.cad.dev
Date: 
Mon, 9 Jul 2007 18:37:41 GMT
Viewed: 
7506 times
  
Would the group prefer environment variables that provide paths for
directories, or known subdirectory names?

Get the best of both worlds and do both.  Check for the environment variable
and if it is blank
(or non-existant) default it to a "known" sub-directory.

W


Subject: 
Re: Dear LSC, was: LDrawIni API (was: LDRAWPREDIRS LDRAWPOSTDIRS - additional search paths)
Newsgroups: 
lugnet.cad.dev
Date: 
Mon, 9 Jul 2007 18:44:45 GMT
Viewed: 
7772 times
  
I examined the LDraw website and was unable to find formalization for the
support of optional part paths.

That's because the LSC voted against it.

Took me a while to find the discussion as well - and I knew it was out
there!

http://five.pairlist.net/pipermail/lsc/2007-March/thread.html

William


Subject: 
Re: Convention for directoried for unofficial parts?
Newsgroups: 
lugnet.cad.dev
Date: 
Mon, 9 Jul 2007 19:10:21 GMT
Viewed: 
7500 times
  
In lugnet.cad.dev, William Howard wrote:

Would the group prefer environment variables that provide paths for
directories, or known subdirectory names?

Get the best of both worlds and do both.  Check for the environment variable
and if it is blank
(or non-existant) default it to a "known" sub-directory.

That makes sense to me too.

Based on the coincidental informal convention already used by LDView and
Bricksmith, I suggest $LDRAWDIR/Unofficial as the default unofficial parts
directory. It is structured like the regular LDraw directory with parts,
parts/s, p, and p/48 subdirectories.

Using the full path to unofficial parts is a great tip for L3P! I like that
solution. Beats my previous approach of merging and unmerging the official and
unofficial hierarchies with a script.

Jim


Subject: 
Re: Convention for directoried for unofficial parts?
Newsgroups: 
lugnet.cad.dev
Date: 
Tue, 10 Jul 2007 02:30:54 GMT
Viewed: 
10135 times
  
In lugnet.cad.dev, Kevin L. Clague wrote:
To all developers,

  The LSC does not want to specify how unofficial parts are handled.  Personally
if find the recommendation that we pull down individual unofficial parts into
the same directory as our LDraw file a hassle.

I agree (which is why I voted yes on the other proposal, although it's not an
exact match for what you're asking for).  Having said that, Lars did offer the
INI parsing code, and since it's already in LDView (which is under GPL), anyone
who wants to can already access and use Lars's code.  While it's true that INI
files are a Windows invention, they do make an easily human-readable format for
settings files, and they are easy to parse.  Lars's code does all the parsing,
and it's written in C (not C++) that has been designed to be as portable as
possible.  I updated his code to provide support for a filename search callback
function to handle platform-specific case-sensitive file systems.  (And I have
an implementation of one such function in LDView's QT code.)

So if you want my opinion, I think we should all use Lars's code.  If you're not
writing in C, then the code could probably be rolled into a library quite easily
(although it does use structures, which have varied ease-of-use in non C-based
programming languages).


  Would the group prefer environment variables that provide paths for
directories, or known subdirectory names?

Lars's code supports using environment variables for everything, or the
ldraw.ini for everything (assuming it can find it), or a combination of the two.
I think what he has is sufficient for use on any OS.

Of course, the fact that I'm already using Lars's code in LDView may make me
biased.  Additionally, I haven't yet updated LDView's "extra dirs" UI to use
Lars's code, so you might (somewhat legitimately) claim that I'm being
hypocritical.

--Travis


Subject: 
Re: Convention for directoried for unofficial parts?
Newsgroups: 
lugnet.cad.dev
Date: 
Tue, 10 Jul 2007 17:29:36 GMT
Viewed: 
10582 times
  
In lugnet.cad.dev, Travis Cobbs wrote:
In lugnet.cad.dev, Kevin L. Clague wrote:
To all developers,

  The LSC does not want to specify how unofficial parts are handled.  Personally
if find the recommendation that we pull down individual unofficial parts into
the same directory as our LDraw file a hassle.

I agree (which is why I voted yes on the other proposal, although it's not an
exact match for what you're asking for).  Having said that, Lars did offer the
INI parsing code, and since it's already in LDView (which is under GPL), anyone
who wants to can already access and use Lars's code.  While it's true that INI
files are a Windows invention, they do make an easily human-readable format for
settings files, and they are easy to parse.  Lars's code does all the parsing,
and it's written in C (not C++) that has been designed to be as portable as
possible.  I updated his code to provide support for a filename search callback
function to handle platform-specific case-sensitive file systems.  (And I have
an implementation of one such function in LDView's QT code.)

I'm using Qt, and LPub is under GPL, so this sounds perfect.

I'm all for standardization, so this sounds great.


So if you want my opinion, I think we should all use Lars's code.  If you're not
writing in C, then the code could probably be rolled into a library quite easily
(although it does use structures, which have varied ease-of-use in non C-based
programming languages).


  Would the group prefer environment variables that provide paths for
directories, or known subdirectory names?

Lars's code supports using environment variables for everything, or the
ldraw.ini for everything (assuming it can find it), or a combination of the two.
I think what he has is sufficient for use on any OS.

Of course, the fact that I'm already using Lars's code in LDView may make me
biased.  Additionally, I haven't yet updated LDView's "extra dirs" UI to use
Lars's code, so you might (somewhat legitimately) claim that I'm being
hypocritical.

I'm not looking to judge or criticize anyone.  All of our programming
efforts are works in progress, so these self analysis' are all very
understandable in my book.


--Travis

Kevin


Subject: 
Re: Convention for directoried for unofficial parts?
Newsgroups: 
lugnet.cad.dev
Date: 
Tue, 10 Jul 2007 19:45:33 GMT
Viewed: 
10492 times
  
In lugnet.cad.dev, Kevin L. Clague wrote:
I'm using Qt, and LPub is under GPL, so this sounds perfect.

I'm all for standardization, so this sounds great.

The following files in LDView's source tree contain the LDrawIni stuff:

LDLoader/LDrawIni.c
LDLoader/LDrawIni.h
LDLoader/LDrawInP.h

There's a #include <TCFoundation/TCDefines.h> near the top of LDrawIni.c.  You
can delete that; the only reason it's there is to define
_CRT_SECURE_NO_DEPRECATE and _CRT_NONSTDC_NO_DEPRECATE to get rid of warnings in
Visual Studio 2005.

My file case callback function can be found in QT/ModelViewerWidget.cpp and is
named staticFileCaseCallback.  It uses another function in the same file named
staticFileCaseLevel.  Additionally, it uses replaceStringCharacter from
TCFoundation/mystring.{cpp,h}.  You'll probably want to either copy that one
function or reimplement it.  It just does a global search and replace in a
string looking for one character and replacing it with another (in this case,
replacing backslash with forward slash).

All of the above files can be downloaded from LDView's SourceForge CVS browse
here:

http://ldview.cvs.sourceforge.net/ldview/LDView/

Alternatively, you can do an anonymous cvs checkout of the LDView source tree
(instructions here: http://ldview.sourceforge.net/Downloads.html#SourceCode).

--Travis


©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR