THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 02/11/2007 at 13:17, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 10.1
Platform: Mac OSX ;
Language(s) : C.O.F.F.E.E ;
---------
Hello,
I've been using C4D for years, but I'm new to C.O.F.F.E.E. and scripting in general, so pardon my simple questions.
I"m roughing together a number of file parsers and have run into a limitation, found a workaround, and then discovered limits for that. I simply need a function analogous to readlines() in Python. That will allow me to step through an imported string, one line at a time to isolate information from lines that start with the word "ATOM". Unable to find such a function in the SDK, I tried to hunt for a specific string using.
var phrase = stradd(tostring(0x000A),"ATOM ");
var posMove0 = strstr(str,phrase,pos);
...
var posMove= strstr(str,phrase,(posAdvance + posMove0));
This yeilded random results, usually pulling any word ATOM from the middle of lines etc., telling me that 0x000A and 0x000D did not work as proper carriage returns. To work around this, I grabbed a copy of the 80th character and pasted it into my search string.
var phrase = stradd(strmid(myString,80,1), "ATOM ");
This works great on a properly formatted PDB file which is supposed to have a carriage return at position 80 and should thus work for unix or mac unicoded returns...however, I quickly discovered that many files available in the Protein DataBank are not correctly formatted, the first line often has less than 80 characters and my parser fails.
Is there a readlines() function in COFFEE that I missed? If not, is there a better way to incorporate a carriage return into my search string?
Also, since I'm new to this, I imagine my clumsy code could be made more efficient, so I'd love to hear any suggestions and will paste it below. Could I fill an array first, or is it faster to just fill one line of the polygon object points list at a time as I'm doing, etc. I'll paste the much more elegant python script below that for comparison of what I'd like to achieve directly in C4D.
Thank you,
Graham
main(doc,op)
{
// Lets the user select a file
var filename = GeGetStartupPath();
filename->FileSelect("Please select a file.", FALSE);
// println ("filename = ", filename->GetFullString());
// Opens the same file and reads it
var file2 = new(BaseFile);
file2->Open(filename, GE_READ, FILE_DIALOG);
var myString = file2->ReadString(file2->GetLength());
var PointCloud = doc->FindObject("PointCloud");
var op = PointCloud;
op->SetScale(vector(1,1,-1));
var cnt = op->GetPointCount(); // Get actual point count.
var MaxPoints = 10000;
var str = myString;
var pos = 0;
// Roundabout way to get end of line or linefeed character to find first atom
// in the string created in "phrase2" just below.
var phrase = stradd(strmid(myString,80,1), "ATOM ");
var posMove0 = strstr(str,phrase,pos);;
for (cnt=0;cnt<MaxPoints;cnt++)
{
if (!instanceof(op,PointObject)) return FALSE; // Not a point object.
var vc = new(VariableChanged); if (!vc) return FALSE; // Allocate class.
var cnt = op->GetPointCount(); // Get actual point count.
vc->Init(cnt,cnt+1); // Resize point count from cnt to cnt+1.
// Just for adding a point at the end of
// the point list one doesn't need a map.
var pos= cnt;
var posAdvance = ((pos*79));
var posMove= strstr(str,phrase,(posAdvance + posMove0));
posMove = posMove + 1;
if (posMove == 0) break;
var len = 8;
var x = strmid(str,(posMove + 30), len);
var y = strmid(str,(posMove + 38), len);
var z = strmid(str,(posMove + 46), len);
{
//****** z must be (-) because C4D uses left-handed coordinate system******
var ok = op->MultiMessage(MSG_POINTS_CHANGED,vc);
var p = vector (evaluate(x), evaluate(y), (evaluate(z)));
op->SetPoint(cnt, p); // Set data p for new point
}
}
}
IN PYTHON
#!/usr/bin/env python
import glob, os
filelist = glob.glob("*.pdb")
for f in filelist:
ctr = 1
name = os.path.splitext(os.path.basename(f))[0]
outputfilename = name+ '.txt'
fptr = open(outputfilename, 'w')
ostr = "Point X Y Z\n"
fptr.write(ostr)
ptr = open(f)
lines = ptr.readlines()
for l in lines:
if l.find("ATOM")==0 or l.find("HETA")==0:
xcoord = float(l[30:38])
ycoord = float(l[38:46])
zcoord = float(l[46:54])
ostr = "%5d %.3f %.3f %.3f\n" %(ctr, xcoord, ycoord, zcoord)
fptr.write(ostr)
ctr += 1
fptr.close()
print "wrote ", outputfilename
Thanks
Graham