• Bl0rq (unregistered)

    Kinda off topic but i really dont like the extra click from my rss aggregator (www.blorq.com) to get to the comments.

  • (cs) in reply to Abscissa
    Abscissa:
    I can understand them wanting to port it to C++: They want to avoid having to deal with maintaining and updating a program written in an antiquated language. Plus that would require retraining the development staff in said antiquated language (Anyone not like it being called "antiquated"? Good language or not, fortran has been pretty much cast aside - deal with it). So that part of it was a *good* management decision.

    Ooooh ... I hope you never ever have to work at a financial institution. You'd have to learn COBOL ... they don't want to break code as any screw-up would translate into millions in loss.

    So, they take the painful decision... they make their developers learn the "antique" language.

    (I'd rather program in FORTRAN than COBOL ... but then, I'd go for C at the least.)

  • (cs) in reply to Abscissa

    The REAL problem here is that the developers doing the port were too unskilled to translate the code properly. If you know how to write reliable C++ code, and you properly translate any speed/reliability details from the original, then there's no reason the C++ version should be slower or less reliable. So the real WTF is hiring crappy programmers and then assuming they knew what they're doing.

    You're assuming that someone spent the time/money teaching their C++ programmers how to program in FORTRAN. Maybe a manager thought "they don't have to really know FORTRAN - just enough to translate it". And there you have a WTF, and likely a large part of the reason for the instability. Converting from Fortran to C is trivial (it can be automated), but converting it to C++ (real C++, not just FORTRAN as C compiled as C++) would be non-trivial I believe.

    Not to mention all the changes they made to make it prettier which I can guarantee would interfere with the program if done by people who didn't understand it...

  • (cs)

    I once worked for a service bureau. We convinced a customer of a different service bureau to switch to us instead, so I had to take a Fortran program and make it run on the IBM 370. It was easy. There was only one problem. It was an accounting package that used floating-point for money and the other computer had 36-bit words. The 370 has 32-bit words. We had to convince the customer that $123,321.06 plus $123,321.06 really equalled $246,642.13.

  • m0s3s (unregistered) in reply to Dustin

    Yeah. I've seen people use C++ to make incredibly poor-performing apps. Especially when they're new to OO and decide that the first thing they need is a giant class hierarchy for everything.

  • (cs) in reply to jrwr
    jrwr:
    They should of just kept it as FORTRAN and shipped it.... maybe he still will as OSS

    Captch: Knowhuntimean ( ??!! )

    Why is everyone's kneejerk reaction to release it as OSS? What does the prof get for releases it as OSS instead of releasing it not OSS?

  • TheDoom (unregistered) in reply to chrismcb

    Yanks eh?

    And why did the other guy have trouble going from .net 1.0 to .net 2.0 ?? RTFM dude.

  • Woody (unregistered) in reply to Really Old Dude
    Why, you young whippersnappers don't know how easy you have it. Back in The Day, we used to debug with Oscilloscopes and jumper wires! Web? Hah! High level langauges? Hah! Debuggers? Don't even get me started...

    Back in the day? Hell, I do that now. Writing embedded code is.... fun and interesting on some days. Like when you find out that one of your system libraries is trying to poke IO lines to locate one piece of hardware, and you're trying to use that IO line for a rather different purpose.

    Although writing java to be executed by an 8051 processor running at 30MHz, where it's a fully interpreted JVM (no HotSpot compile-to-native-bytes here...)... That's pretty much a WTF in and of itself.

    http://www.maxim-ic.com/products/microcontrollers/tini/

    captcha: perfection (!!)

  • sdether (unregistered) in reply to AssimilatedByBorg
    AssimilatedByBorg:
    And, oh yeah, we were changing: - the OS - the DB platform from an open-source to commercial DB - the language of the application - the web server

    Doomed to failure? Nah...... what makes you think that?

    This wouldn't have been a certain large webmail ASP?

  • (cs)
    Having effectively created the GoBots of the CAD Software world
    Nice one. Am I really the first Transformers fan (the good stuff, not the Saban crapola) to get this reference?
  • (cs) in reply to sdether
    sdether:
    AssimilatedByBorg:
    And, oh yeah, we were changing: - the OS - the DB platform from an open-source to commercial DB - the language of the application - the web server

    Doomed to failure? Nah...... what makes you think that?

    This wouldn't have been a certain large webmail ASP?

    lol... nope, not hotmail (or any kind of webmail), and I never worked for MS.

    Version 2.0 never saw the light of day. The company imploded when it ran out of money.

  • Woody (unregistered) in reply to VGR

    GoBots != Transformers (those were Autobots). The GoBots were a different show entirely.

    (I watched both as a kid)

  • (cs) in reply to Jim Steichen
    Jim Steichen:
    Things like tool-tips, help buttons, friendly menus, and grammatically correct messages would need to be added in to make the program commercially viable. When did all this extra crap become an acceptable substitute for proper training and knowledge about how to draft schematics, mechanical drawings, etc? Marketing seems to want to ensure that any IDIOT can use a given program (perhaps rightly so), but someone needs to bash some common sense into such people.

    All that extra "crap" isn't there for a substitute of proper training and knowledge about the line of work. All of that extra "crap" is there to make the program easy to use, and so you don't need to take a class on how to use the program. If the program is well design, an expert in the field should find it fairly easy to use.

  • hexatron (unregistered)

    Couldn't you just subtract one from the array pointer so that newArray[1] == oldArray[0], allowing you to loop from 1 to 4?

    My father had a story: A man went to a tailor to get a suit made. When he tried it on, the fit was miserable. "One leg is shorter than the other!" "So stand a little tilted--it'll look fine!" "The shoulders aren't even either!" "So bend one shoulder down--you'll look great!"

    The man hobbled out of the shop as the tailor had directed.

    On the street, another man started talking to him: "Where did you get that wonderful suit?" "At the shop over there. But I don't think it's so wonderful." "Whaddya mean? That tailor must be a genius to fit such a nice suit on a cripple like you!"

    So sure. Subtract one from all the pointers. Why does the program keep crashing in 'delete'?

  • (cs) in reply to AssimilatedByBorg
    AssimilatedByBorg:
    ...They wanted the release out in 2.5 months with a boatload of new features.

    And, oh yeah, we were changing:

    • the OS
    • the DB platform from an open-source to commercial DB
    • the language of the application
    • the web server

    Doomed to failure? Nah...... what makes you think that?

    I bet the new version was easy to get customers to fork out money. Many folks would like to have to buy a new OS, new DB and a new web server just to run the update.

  • (cs) in reply to AssimilatedByBorg
    AssimilatedByBorg:
    ...They wanted the release out in 2.5 months with a boatload of new features.

    And, oh yeah, we were changing:

    • the OS
    • the DB platform from an open-source to commercial DB
    • the language of the application
    • the web server

    Doomed to failure? Nah...... what makes you think that?

    I bet the new version was easy to get customers to fork out money. Many folks would like to have to buy a new OS, new DB and a new web server just to run the update.

  • Meng Mao (unregistered) in reply to Woody

    That's a bit dense of you -- GoBots were clearly a shitty ripoff of Transformers, which is why the author made the reference in the first place.

    Woody:
    Although writing java to be executed by an 8051 processor running at 30MHz, where it's a fully interpreted JVM (no HotSpot compile-to-native-bytes here...)... That's pretty much a WTF in and of itself.
    I took an 8051-based class at MIT, and there were rumors that some kid had implemented a stripped down JVM for the 2-week final project a couple years back. I'm sure he would have tried to make it fully featured if he'd had enough ROM.
  • Woody (unregistered) in reply to Meng Mao
    That's a bit dense of you -- GoBots were clearly a shitty ripoff of Transformers, which is why the author made the reference in the first place.

    good point. I clearly missed that that might have been a joke.

    I took an 8051-based class at MIT, and there were rumors that some kid had implemented a stripped down JVM for the 2-week final project a couple years back. I'm sure he would have tried to make it fully featured if he'd had enough ROM.

    Hmmm. It wouldn't surprise me to find out that was the source... It appears to take about 400K to pull it off (this is an 8051 core with 24-bit addressing capabilities). It works, it's just slow. VERRRRY slow. But writing java can be far less painful than C/C++. But there's a significant trading of ease of use vs. performance. I get about 100-1000x the performance when I drop into assembly for optimizing routines (array-based math stuff and hardware IO operations pretty much need to be done in assembly or they're laughably slow).

  • (cs)

    Oh my god! I think I used to get constant junk mail from the makers of this application (if it was indeed a CAD program for the Mac). I'm not an architect, and have no use for CAD, but I used to get color glossy flyers for this application (ArchiCAD, I think it was?). And it sold for like $57. Isn't AutoCAD something like $10,000 per seat? That was enough to make me realize that this program had to suck hard.

  • (cs) in reply to Cody
    Cody:
    nobody:
    Why do I think many of the stability problems were due to the difference between FORTRAN arrays (1-based) and C++ arrays (0-based)?

    One time, I had to work with C++ code ported from FORTRAN, and got an array out of bounds error because of this (loop over 1 to 4 instead of 0 to 3). Unfortunately, the obvious fix wasn't acceptable, becuase the results couldn't change. No matter that the results might have had random errors

    Couldn't you just subtract one from the array pointer so that newArray[1] == oldArray[0], allowing you to loop from 1 to 4?
    This is a perfect case for using Hungarian notation for variable naming. Put a "ci" in front of an index and it means that it is a "c++ index" and has had 1 subtracted from it, hence it should only be used as an array subscript. Loops would go from 1 to n just like the FORTRAN code and only "ci" variables go in the array subscripts.

  • luipugs (unregistered) in reply to Bl0rq

    Nobody has noticed this?

    "They were blown away by The Processor's application..."

    Shouldn't it be "The Professor's"?

  • (cs) in reply to chrismcb
    chrismcb:
    jrwr:
    They should of just kept it as FORTRAN and shipped it.... maybe he still will as OSS...
    Why is everyone's kneejerk reaction to release it as OSS? What does the prof get for releases it as OSS instead of releasing it not OSS?
    Actually, it is what he doesn't get that is important: he doesn't get slapped with a lawsuit from the original company that he made the deal with, he doesn't get the headache of hiring a tech team to upgrade the program and he doesn't get hounded by irate customers when a bug pops up.
  • (cs) in reply to luipugs
    luipugs:
    Nobody has noticed this?

    "They were blown away by The Processor's application..."

    Shouldn't it be "The Professor's"?

    I saw this too, but passed it off as a `bad pun that I didn't get'.

  • N Morrison (unregistered) in reply to Jim Steichen
    Jim Steichen:
    Things like tool-tips, help buttons, friendly menus, and grammatically correct messages would need to be added in to make the program commercially viable. When did all this extra crap become an acceptable substitute for proper training and knowledge about how to draft schematics, mechanical drawings, etc? Marketing seems to want to ensure that any IDIOT can use a given program (perhaps rightly so), but someone needs to bash some common sense into such people.
    What do you expect when CD/DVD software training programs consist of someone reading to the student while a few random lines flash on the screen. Programmers who can't read - that's a large market niche - NOT!
  • Troy McClure (unregistered) in reply to dcardani
    dcardani:
    Oh my god! I think I used to get constant junk mail from the makers of this application (if it was indeed a CAD program for the Mac). I'm not an architect, and have no use for CAD, but I used to get color glossy flyers for this application (ArchiCAD, I think it was?). And it sold for like $57. Isn't AutoCAD something like $10,000 per seat? That was enough to make me realize that this program had to suck hard.

    ArchiCAD came with the restriction that you had to stand hence the $57 price. AutoCAD is more because it allows you to sit while using it.

  • anon (unregistered)

    The lesson here isn't about the code, the programmers or the Company - it's about the unhired lawyer.

    If you are entering in a business deal, whether it's selling software or buying a house, the $500 (or maybe even more) you spend on a lawyer will be worth it. If you "can't afford" the lawyer, you can't afford the deal.

  • C Nazi (unregistered) in reply to Cody
    Cody:
    Couldn't you just subtract one from the array pointer so that newArray[1] == oldArray[0], allowing you to loop from 1 to 4?

    Welcome to the land of UNDEFINED BEHAVIOUR.

  • Marc (unregistered)

    Oh, apart from Indy Jones, the warehouse remembers me of the X-Files. Some things better be kept away from the public :D

  • Nataku (unregistered) in reply to The cow says....
    The cow says....:
    quamaretto:
    Yes, managers everywhere really are stupid enough to do a C++ to Fortran conversion without any consideration.

    It's not really a rare thing for a project manager to be blind to consequences in order to switch to the tools they prefer.

    Sure...

    It's the project manager who decided that it had to be ported to the language de jour because software always always always has to be written in the coolest available language. Developers never decide that it is better to "upgrade" the system rather than sullying their minds with some supposedly antiquated language like FORTRAN (or COBOL or C or whatever they think only dinosaurs would use).

    Yeah, it had to be management making that call.

    Indeed. I have developers all over my workplace right now calling for everything under the sun to be rewritten in Ruby. When asked why, one of them said that programming languages only last about 10 years. I find it amusing that nearly every major application that he uses has been written in a language more than 10 years old.

  • Bill (unregistered) in reply to Dustin
    Dustin:
    So they convert from Fortran to C++... That made it unstable and that's not surprising, but slower?

    Anybody else here done this sort of conversion with that outcome?

    Yes. And yes.

  • Eternal Density (unregistered) in reply to Kooky Koder
    Kooky Koder:
    There are two kinds: The fat rat and the hungry rat. The fat rat is happy with things the way they are, the hungry rat wants to change everything to "make it better". At the very least, he wants more food. The fat rat notices that things are NOT getting better, and asks you to stop trying to change things. The Hungry rat notices that things are NOT getting better, and asks you to change more things faster. Progress. Got to love it.

    What you really meant was:

    Rat is two. The two is fat. The two is hungry. Fat rat put foot. Foot stay put. Put in what? Put in concrete. Hungry rat produce. Produce everything want. Want what? Least better. Better is more food. Fat rat notice. The notice not better. No better no concrete. Fat angry. Fat rat rattle with you. You stop. Hungry notice stop. Stop is not better. The Hungry rat ask. Ask who? Ask you produce. You produce faster things. Someting progress on you. The something disgusting. No quack!

    Captcha = creative. Well kinda.

  • Mike (unregistered) in reply to newfweiler
    newfweiler:
    There was only one problem. It was an accounting package that used floating-point for money and the other computer had 36-bit words. The 370 has 32-bit words. We had to convince the customer that $123,321.06 plus $123,321.06 really equalled $246,642.13.

    The first time, when I saw a financial application using floats for its calculations, I thought it was just a stupid mistake. But now that I read "The Daily WTF" regularly I fell this might be much more common.

    Where I learned programming I was tought to never ever use floats for financal calculations and to go with integers instead.

  • Tassos Bassoukos (unregistered) in reply to tharfagreinir

    Ah, reminds me of http://www.warehouse23.com/basement/box/

  • Winter (unregistered) in reply to Jim Steichen
    Jim Steichen:
    Things like tool-tips, help buttons, friendly menus, and grammatically correct messages would need to be added in to make the program commercially viable. When did all this extra crap become an acceptable substitute for proper training and knowledge about how to draft schematics, mechanical drawings, etc? Marketing seems to want to ensure that any IDIOT can use a given program (perhaps rightly so), but someone needs to bash some common sense into such people.

    Job security through obfuscation?

  • The Old Guy (unregistered) in reply to Really Old Dude

    you kids are so lucky!

    these days you have those fancy OSCILLOSCOPES. back in my days, we had to sense the electricity with our fingers. thats one major reason the industry switched from 4000 volt to 210...

  • Gareth Martin (unregistered) in reply to hexatron
    hexatron:
    >Couldn't you just subtract one from the array pointer so that newArray[1] == oldArray[0], allowing you to loop from 1 to 4?

    So sure. Subtract one from all the pointers. Why does the program keep crashing in 'delete'?

    This is assuming he's using new and delete (or malloc and free etc), and not static arrays.

    But anyway, to avoid the "delete" problem just add one again before you use delete, or store the altered pointer separately. All languages with a 1-based array either internally keep a pointer to one element before the start of the array, and offset from that, or they subtract 1 from the index you ask for on every array access, so just emulate one of these. Alternatively you could just make the arrays 1 larger and ignore the 0 element, which will also work flawlessly. Or for yet another solution, just redefine the array versions of new and delete to return and expect a pointer to the element before the start of the array. Would save a lot of hunting down all the arrays to alter them (of course only works on dynamically allocated arrays).

  • J Random Hacker (unregistered) in reply to hexatron

    @hexatron

    "My father had a story: A man went to a tailor to get a suit made..."

    Famous old joke. I believe it was originally told about "demob suits", the civilian clothes issued to British soldiers after WW2.

  • Mike James (unregistered)

    I have once been nearly in the professors situation.

    I evolved a 50k LOC C/Yacc/Lex program over a period of about 6 years. It could do various tricks involving partitioning designs across FPGAs, translating hardware description languages and printed circuit board netlists.

    Some of the tricks were pretty unique and could only be found in tools that cost in the $100k region. The particular integration of features was unique or bizarre.

    It was looked at by an in-house software team to see if it could be integrated into the design flow, and they recoiled in horror at the code.

    I showed it running to a CAD company and they offered me 3 months overseas with them integrating it into their product. I felt it would take more like a year, as I had forgotten how some of it worked :-), and so I declined.

    The last surviving copy is now kept securely in captivity in my pocket on a flash card in my Zaurus 5500 PDA , where I rebuild it from time to time as a stress test of the native compiler tools.

  • (cs) in reply to Jim Steichen
    Jim Steichen:
    Things like tool-tips, help buttons, friendly menus, and grammatically correct messages would need to be added in to make the program commercially viable. When did all this extra crap become an acceptable substitute for proper training and knowledge about how to draft schematics, mechanical drawings, etc? Marketing seems to want to ensure that any IDIOT can use a given program (perhaps rightly so), but someone needs to bash some common sense into such people.

    I'm thinking of Blender here. Blender 1.x had a bit cryptic UI: The first time I sat in front of it I was pretty much like "WTF?", and after I did some exercises from the Book, I was like "okay, this is actually a good program."

    In contrast to >2.3x series, which actually has things like menus, tooltips, and the bajillion keyboard shortcuts are actually explained within the program itself somehow. Even if I now know a little bit about the application from 1.x days, it's still a refreshing change that helps me understand the application further.

    If the application is good at the core, that's good, that's important. People seem to think that "every idiot can use it" is somehow bad, while they ignore a simple fact: If idiots can find the program easy enough, what about the actually competent people - wouldn't they think a little bit easier UI would benefit them too?

  • James Schend (unregistered) in reply to Eternal Density
    Eternal Density:
    Kooky Koder:
    There are two kinds: The fat rat and the hungry rat. The fat rat is happy with things the way they are, the hungry rat wants to change everything to "make it better". At the very least, he wants more food. The fat rat notices that things are NOT getting better, and asks you to stop trying to change things. The Hungry rat notices that things are NOT getting better, and asks you to change more things faster. Progress. Got to love it.

    What you really meant was:

    Rat is two. The two is fat. The two is hungry. Fat rat put foot. Foot stay put. Put in what? Put in concrete. Hungry rat produce. Produce everything want. Want what? Least better. Better is more food. Fat rat notice. The notice not better. No better no concrete. Fat angry. Fat rat rattle with you. You stop. Hungry notice stop. Stop is not better. The Hungry rat ask. Ask who? Ask you produce. You produce faster things. Someting progress on you. The something disgusting. No quack!

    Captcha = creative. Well kinda.

    It's just like the story of the grasshopper and the octopus...

  • Heinz Gorgon Mittelmacher (unregistered) in reply to Mike
    Mike:
    newfweiler:
    There was only one problem. It was an accounting package that used floating-point for money and the other computer had 36-bit words. The 370 has 32-bit words. We had to convince the customer that $123,321.06 plus $123,321.06 really equalled $246,642.13.
    Where I learned programming I was tought to never ever use floats for financal calculations and to go with integers instead.
    You were taught right. And your are right: it's all too common. And as far as I know, there are no easy ways to solve the rounding issues once you have a 750000-line business app written in C that consistently uses floats for currency.
  • (cs) in reply to quamaretto
    quamaretto:
    Yes, managers everywhere really are stupid enough to do a C++ to Fortran conversion without any consideration.

    It was FORTRAN, and they turned it into C++.

    That, and everything else about this story, is amusingly backwards compared to the regular inherited-FORTRAN-beast stories that get posted here.

    I can't remember any post about a program that started out good and was hacked into oblivion... was there?

  • Corporate Cog (unregistered) in reply to quamaretto

    Upgrading a project in rev? Sorry, that's not the same mistake...

  • PGB (unregistered) in reply to hexatron
    hexatron:

    My father had a story: A man went to a tailor to get a suit made. When he tried it on, the fit was miserable. "One leg is shorter than the other!" "So stand a little tilted--it'll look fine!" "The shoulders aren't even either!" "So bend one shoulder down--you'll look great!"

    The man hobbled out of the shop as the tailor had directed.

    On the street, another man started talking to him: "Where did you get that wonderful suit?" "At the shop over there. But I don't think it's so wonderful." "Whaddya mean? That tailor must be a genius to fit such a nice suit on a cripple like you!"

    My grandfather told the joke this way: A man went to a tailor to get a suit made. When he tried it on, the fit was miserable. "One leg is shorter than the other!" "So stand a little tilted--it'll look fine!" "The shoulders aren't even either!" "So bend one shoulder down--you'll look great!"

    The man hobbled out of the shop as the tailor had directed.

    Two women on the street saw the man hobbling along. One said to the other: "Look at that poor crippled man." "Oh my yes. But his suit fits great."

  • (cs)

    Should have got me in - from the start. I'd have done a good job.

    Too many idiots about with C++ on their CVs who are clueless as to how to write C++ properly.

    Any decent C++ programmer knows that the big key to C++ is RAII. And that inheritance is used to implement polymorphism.

    vector is a fundamental template class in C++, yet so many times it's not being used, and raw arrays are being used instead.

  • Dante (unregistered) in reply to Abscissa
    Abscissa:
    The REAL problem here is that the developers doing the port were too unskilled to translate the code properly. If you know how to write reliable C++ code, and you properly translate any speed/reliability details from the original, then there's no reason the C++ version should be slower or less reliable. So the real WTF is hiring crappy programmers and then assuming they knew what they're doing.

    It's from a company that advocates language changes like that as "small changes". All their good developers either stopped trying or left.

  • Dante (unregistered) in reply to WWWWolf
    WWWWolf:
    If the application is good at the core, that's good, that's important. People seem to think that "every idiot can use it" is somehow bad, while they ignore a simple fact: If idiots can find the program easy enough, what about the actually competent people - wouldn't they think a little bit easier UI would benefit them too?

    That precludes the idea that people who know how to use it aren't going to be elitist about the fact that they know how to use it. "Back in my day, we used CLI versions of CAD! We had to map it out in our heads and then use xyz coordinates to tell the program where the point was! It didn't even display it, but WE LIKED IT!"

  • Was Anders (unregistered) in reply to Heinz Gorgon Mittelmacher
    Heinz Gorgon Mittelmacher:
    Mike:
    Where I learned programming I was tought to never ever use floats for financal calculations and to go with integers instead.
    You were taught right. And your are right: it's all too common.

    You were both taught wrong. If you're writing a financial app where accuracy is the key quality parameter, by all means use floating-point!

    It's only if you're writing an accounting application, where predictability and reproducability takes precedence over accuracy, that you have to use something fixed-point.

  • Michael Wojcik (unregistered) in reply to Jeff Bell
    Jeff Bell:

    That's not surprising that it's slower. Even C is slower than Fortran if there are lots of array operations. That trick of treating arrays as a special kind of pointer was cheap on a PDP-11, but hinders what the compiler can do.

    In particular, pointer aliasing in C (and in C-like C++) is a big problem for optimizing code that does a lot of operations through indirection in the inner loop. That's why C99 introduced the "restrict" sc-specifier, which indicates a pointer type that the programmer guarantees will not be aliased.

    Unfortunately, C99 has not proven popular, and even those implementations that accept the "restrict" keyword rarely do anything with it. I don't recall whether C++ has incorporated "restrict" into the latest standard, but I imagine the situation's similar there. In any case, it wouldn't have been available when this particular misbegotten conversion was happening.

    Fortran explicitly disallows aliasing, so its pointer operations are more amenable to optimization.

    -- Michael Wojcik

    (The swell new TDW implementation appears to have dropped my session silently - I just noticed that it now thinks I'm an anonymous user. God, how I hate "web forums".)

  • (cs) in reply to nobody
    nobody:
    Why do I think many of the stability problems were due to the difference between FORTRAN arrays (1-based) and C++ arrays (0-based)?

    Also, multi-dimensional Fortran arrays are in column-major order, while C and C++ arrays are in row-major order. That could cause problems if any of the code tried to convert from orthogonal to linear addressing, for example.

    -- Michael Wojcik

Leave a comment on “It's CAD-tastic!”

Log In or post as a guest

Replying to comment #:

« Return to Article