<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
    <title>Civilized Development</title>
    
    <link rel="alternate" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/" />
    <id>tag:typepad.com,2003:weblog-92290523942524683</id>
    <updated>2013-05-17T04:58:33-07:00</updated>
    <subtitle>Diving into Civil 3D programming the polite way.</subtitle>
    <generator uri="http://www.typepad.com/">TypePad</generator>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/CivilizedDevelopment" /><feedburner:info uri="civilizeddevelopment" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
        <title>Civil 3D Wish List Survey for 2013 Available</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CivilizedDevelopment/~3/qsutBVCcCig/civil-3d-wish-list-survey-for-2013-available.html" />
        <link rel="replies" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/2013/05/civil-3d-wish-list-survey-for-2013-available.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a0147e1be0df6970b0191023c7cba970c</id>
        <published>2013-05-17T04:58:33-07:00</published>
        <updated>2013-05-17T04:58:33-07:00</updated>
        <summary>Once again, ADN is hosting a survey to identify the Civil 3D API features important to you. We take very seriously your feedback, and if you review past survey results with the API functionality we have implemented, you’ll notice they match very well. Don’t let go this opportunity to be...</summary>
        <author>
            <name>Isaac R</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="General" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://civilizeddevelopment.typepad.com/civilized-development/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>Once again, ADN is hosting a survey to identify the Civil 3D API features important to you. We take very seriously your feedback, and if you review past survey results with the API functionality we have implemented, you’ll notice they match very well.</p>  <p>Don’t let go this opportunity to be heard. Take the survey and let us know which areas we need to work on to improve the API. You can take the survey <a href="https://www.surveymonkey.com/s/Civil3DAPIWishListSurveyY2013">here</a>.</p></div>
</content>



    <feedburner:origLink>http://civilizeddevelopment.typepad.com/civilized-development/2013/05/civil-3d-wish-list-survey-for-2013-available.html</feedburner:origLink></entry>
    <entry>
        <title>Subassembly Targets (Having Fun Yet?)</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CivilizedDevelopment/~3/jbFmpRxrkhk/subassembly-targets-having-fun-yet.html" />
        <link rel="replies" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/2013/05/subassembly-targets-having-fun-yet.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a0147e1be0df6970b01901bbdfa68970b</id>
        <published>2013-05-01T08:42:58-07:00</published>
        <updated>2013-05-01T08:42:58-07:00</updated>
        <summary>In my previous post, I demonstrated how to create a ‘Corridor’ from scratch. The sample builds a very basic ‘Corridor’, creates a ‘Baseline’ and a ‘Baseline Region’. For more complex corridors, there is a little more work to do; especially, if you want to leverage the full dynamism of the...</summary>
        <author>
            <name>Isaac R</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="C3D2014" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Corridors" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://civilizeddevelopment.typepad.com/civilized-development/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>In my previous <a href="http://civilizeddevelopment.typepad.com/civilized-development/2013/04/create-a-corridor-from-scratch.html">post</a>, I demonstrated how to create a ‘Corridor’ from scratch. The sample builds a very basic ‘Corridor’, creates a ‘Baseline’ and a ‘Baseline Region’. For more complex corridors, there is a little more work to do; especially, if you want to leverage the full dynamism of the ‘Corridor’ object. Any self-respecting ‘Corridor’ will require you set the subassembly targets in it. Given the e-mails, comments, and other communications I received lately, it doesn’t seem straight forward to work with the targets, and I have to admit that they are a little bit confusing. In this post, I will try to explain how to work with subassembly targets and how you should used them through the API.</p>  <p><strong>Targets Are Exposed by Subassemblies</strong></p>  <p>One of the steps of designing a subassembly is to specify the target types it supports. When the ‘Subassembly’ object gets applied, as part of an ‘Assembly’ object, to the ‘Corridor’, you are able to set the targets in it. As you saw in my previous <a href="http://civilizeddevelopment.typepad.com/civilized-development/2013/04/create-a-corridor-from-scratch.html">post</a>, the ‘Assembly’ used is specified in the ‘BaselineRegion’ when created, and it is applied across all the stations in the region. It doesn’t make sense, thereof, to set the targets in the ‘AppliedAssembly’ object directly. Instead, we set the targets in the ‘BaselineRegion’ object and the parameters are used by all the ‘AppliedAssembly’ and contained ‘AppliedSubassembly’ objects.</p>  <p>The ‘BaselineRegion.GetTargets()’ and ‘BaselineRegion.SetTargets()’ methods are provided by the API to access and modify targets. These methods are also exposed by the ‘Baseline’ and ‘Corridor’ objects. It is important to understand that targets on baselines and corridors aggregate the targets in their regions. This means that having a corridor with multiple baselines that in turn contain multiple regions, a call to ‘Corridor.GetTargets()’ will return targets for all regions in all baselines for the corridor. The methods in ‘Corridor’ and ‘Baseline’ are provided for convenience; although, I am still looking for a good situation when to use them.</p>  <p><strong>Work With Targets at the ‘BaselineRegion’ Level</strong></p>  <p>Again, the ‘GetTargets()’ and ‘SetTargets()’ methods in ‘Corridor’ and ‘Baseline’ are provided for convenience in case of a special situation that I still haven’t found (if you know of any, please let me know). You will always want to control the targets at the ‘BaselineRegion’ level, and as a matter of fact, it is the only way the code will behave as you expected. I modified the sample from my previous post to set some targets.</p>  <p><strong>C#</strong></p>  <pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> CreateCorridor(CivilDocument document)
{
    _document = document;
    createCorridorObject();
    createCorridorBaseline();
    createBaselineRegion();
    assignTargets();
    _corridor.Rebuild();
}</pre>

<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> assignTargets()
{
    <span class="rem">// These will return empty collections because the</span>
    <span class="rem">// Corridor object has not been built yet.</span>
    <span class="rem">//</span>
    <span class="rem">// SubassemblyTargetInfoCollection targets = </span>
    <span class="rem">//      _corridor.GetTargets();</span>
    <span class="rem">// SubassemblytargetInfoCollection targets = </span>
    <span class="rem">//      _baseline.GetTargets();</span>

    <span class="rem">// Getting the targets from the BaselineRegion </span>
    <span class="rem">// works because it access the information from</span>
    <span class="rem">// the specified Assembly object when creating the</span>
    <span class="rem">// BaselineRegion.</span>
    <span class="rem">//</span>
    SubassemblyTargetInfoCollection targets = 
        _region.GetTargets();
    <span class="kwrd">foreach</span> (SubassemblyTargetInfo target <span class="kwrd">in</span> targets)
    {
        assignTarget(target);
        
    }
    <span class="rem">// The collection is empty if retrieved from the</span>
    <span class="rem">// Corridor or Baseline object; therefore these</span>
    <span class="rem">// calls will do nothing.</span>
    <span class="rem">// </span>
    <span class="rem">// _corridor.SetTargets(targets);</span>
    <span class="rem">// _baseline.SetTargets(targets);</span>

    <span class="rem">// Regions allow you to specify the targets.</span>
    <span class="rem">//</span>
    _region.SetTargets(targets);
}</pre>
<style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style><style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p><strong>VB.NET</strong></p>

<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> CreateCorridor(document <span class="kwrd">As</span> CivilDocument)
    _document = document
    createCorridorObject()
    createCorridorBaseline()
    createBaselineRegion()
    assignTargets()
    _corridor.Rebuild()
<span class="kwrd">End</span> Sub</pre>

<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> assignTargets()
    <span class="rem">' These will return empty collections because the</span>
    <span class="rem">' Corridor object has not been built yet.</span>
    <span class="rem">'</span>
    <span class="rem">' SubassemblyTargetInfoCollection targets = </span>
    <span class="rem">'      _corridor.GetTargets();</span>
    <span class="rem">' SubassemblytargetInfoCollection targets = </span>
    <span class="rem">'      _baseline.GetTargets();</span>

    <span class="rem">' Getting the targets from the BaselineRegion </span>
    <span class="rem">' works because it access the information from</span>
    <span class="rem">' the specified Assembly object when creating the</span>
    <span class="rem">' BaselineRegion.</span>
    <span class="rem">'</span>
    <span class="kwrd">Dim</span> targets <span class="kwrd">As</span> SubassemblyTargetInfoCollection =
        _region.GetTargets()
    <span class="kwrd">For</span> <span class="kwrd">Each</span> target <span class="kwrd">As</span> SubassemblyTargetInfo <span class="kwrd">In</span> targets

        assignTarget(target)
    <span class="kwrd">Next</span>
    <span class="rem">' The collection is empty if retrieved from the</span>
    <span class="rem">' Corridor or Baseline object; therefore these</span>
    <span class="rem">' calls will do nothing.</span>
    <span class="rem">' </span>
    <span class="rem">' _corridor.SetTargets(targets);</span>
    <span class="rem">' _baseline.SetTargets(targets);</span>

    <span class="rem">' Regions allow you to specify the targets.</span>
    <span class="rem">'</span>
    _region.SetTargets(targets)
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style><style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>The implementation of ‘CreateCorridor()’ hasn’t changed a lot. It just adds a new call to ‘assignTargets()’. Notice that this call is done before we “rebuild” the ‘Corridor’ object. The ‘assignTargets()’ method first calls ‘GetTargets()’ on the ‘BaselineRegion’ object. This returns a ‘SubassemblyTargetInfoCollection’ object containing information about all the supported targets, which is stored as a ‘SubassemblyTargetInfo’ object. For each one of them, we assign the corresponding target (‘assignTarget()’).</p>

<p>If we tried to do the same operation at the ‘BaselineRegion’ or ‘Corridor’ object level, it wouldn’t work. Targets for the ‘BaselineRegion’ and the ‘Corridor’ objects are not defined until the ‘Corridor’ object is built. Since we are setting targets before we actually build the corridor, calling ‘GetTargets()’ on ‘BaselineRegion’ or ‘Corridor’ will return an empty collection (‘SubassemblyTargetInfoCollection’).</p>

<p><strong>‘TargetIds’ is a Disconnected Collection</strong></p>

<p>I have been planning a post to explain the concept of a ‘connected’ vs. ‘disconnected’ collection for the longest time. What stops me is that it will reveal a major inconsistency through out the API. One of these days, I’ll come clean and talk about this topic, and I will point out how we violate this rule in the API. In the meantime, you need to understand that the ‘TargetIds’ property of ‘SubassemblyTargetInfo’ is of type ‘ObjectIdCollection’ and therefore, it is a disconnected collection. Let’s take a look at some code, and then I’ll explain how this affects you.</p>

<p><strong>C#</strong></p>

<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> assignSurfaceTarget(
    SubassemblyTargetInfo target)
{
    <span class="rem">// The 'Add()' method of 'ObjectIdCollection'</span>
    <span class="rem">// knows nothing about subassembly targets; therefore</span>
    <span class="rem">// this call doesn't work.</span>
    <span class="rem">//</span>
    <span class="rem">// target.TargetIds.Add(surfaceId);</span>

    target.TargetIds = _targetSurfaces;

    <span class="rem">// Alternatively, you can get the collection,</span>
    <span class="rem">// manipulate it, and then set it again.</span>
    <span class="rem">//</span>
    <span class="rem">// ObjectIdCollection ids = target.TargetIds;</span>
    <span class="rem">// ... do whatever manipulations (add/remove targets)</span>
    <span class="rem">// target.TargetIds = ids;</span>
    <span class="rem">//</span>
    <span class="rem">// This will work, but trust me, my way (starting</span>
    <span class="rem">// clean) it is easier most of the time.</span>
}

<span class="rem">// The following 2 methods are implemented under the</span>
<span class="rem">// assumption that the subassembly name contains a</span>
<span class="rem">// substring "Right" or "Left" depending on its side.</span>
<span class="rem">// This is a big assumption that works on this</span>
<span class="rem">// particular example, but you will have to get more</span>
<span class="rem">// creative.</span>
<span class="rem">//</span>
<span class="kwrd">private</span> <span class="kwrd">void</span> assignElevationTarget(
    SubassemblyTargetInfo target)
{
    <span class="kwrd">if</span> (isRightSide(target.SubassemblyName))
    {
        target.TargetIds = _targetRightElevation;
    }
    <span class="kwrd">else</span>
    {
        target.TargetIds = _targetLeftElevation;
    }
}

<span class="kwrd">private</span> <span class="kwrd">void</span> assignOffsetTarget(
    SubassemblyTargetInfo target)
{
    <span class="kwrd">if</span> (isRightSide(target.SubassemblyName))
    {
        target.TargetIds = _targetRightOffset;
    }
    <span class="kwrd">else</span>
    {
        target.TargetIds = _targetLeftOffset;
    }
}</pre>
<style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p><strong>VB.NET</strong></p>

<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> assignTarget(target <span class="kwrd">As</span> SubassemblyTargetInfo)
    <span class="kwrd">Select</span> <span class="kwrd">Case</span> target.TargetType
        <span class="kwrd">Case</span> SubassemblyLogicalNameType.Surface
            assignSurfaceTarget(target)
            <span class="kwrd">Exit</span> <span class="kwrd">Select</span>

        <span class="kwrd">Case</span> SubassemblyLogicalNameType.Elevation
            assignElevationTarget(target)
            <span class="kwrd">Exit</span> <span class="kwrd">Select</span>

        <span class="kwrd">Case</span> SubassemblyLogicalNameType.Offset
            assignOffsetTarget(target)
            <span class="kwrd">Exit</span> <span class="kwrd">Select</span>
    <span class="kwrd">End</span> <span class="kwrd">Select</span>
<span class="kwrd">End</span> <span class="kwrd">Sub</span>

<span class="kwrd">Private</span> <span class="kwrd">Sub</span> assignSurfaceTarget(
        target <span class="kwrd">As</span> SubassemblyTargetInfo)
    <span class="rem">' The 'Add()' method of 'ObjectIdCollection'</span>
    <span class="rem">' knows nothing about subassembly targets; therefore</span>
    <span class="rem">' this call doesn't work.</span>
    <span class="rem">'</span>
    <span class="rem">' target.TargetIds.Add(surfaceId);</span>

    target.TargetIds = _targetSurfaces

    <span class="rem">' Alternatively, you can get the collection,</span>
    <span class="rem">' manipulate it, and then set it again.</span>
    <span class="rem">'</span>
    <span class="rem">' ObjectIdCollection ids = target.TargetIds;</span>
    <span class="rem">' ... do whatever manipulations (add/remove targets)</span>
    <span class="rem">' target.TargetIds = ids;</span>
    <span class="rem">'</span>
    <span class="rem">' This will work, but trust me, my way (starting</span>
    <span class="rem">' clean) it is easier most of the time.</span>
<span class="kwrd">End</span> <span class="kwrd">Sub</span>

<span class="rem">' The following 2 methods are implemented under the</span>
<span class="rem">' assumption that the subassembly name contains a</span>
<span class="rem">' substring "Right" or "Left" depending on its side.</span>
<span class="rem">' This is a big assumption that works on this</span>
<span class="rem">' particular example, but you will have to get more</span>
<span class="rem">' creative.</span>
<span class="rem">'</span>
<span class="kwrd">Private</span> <span class="kwrd">Sub</span> assignElevationTarget(
        target <span class="kwrd">As</span> SubassemblyTargetInfo)
    <span class="kwrd">If</span> isRightSide(target.SubassemblyName) <span class="kwrd">Then</span>
        target.TargetIds = _targetRightElevation
    <span class="kwrd">Else</span>
        target.TargetIds = _targetLeftElevation
    <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End</span> <span class="kwrd">Sub</span>

<span class="kwrd">Private</span> <span class="kwrd">Sub</span> assignOffsetTarget(
        target <span class="kwrd">As</span> SubassemblyTargetInfo)
    <span class="kwrd">If</span> isRightSide(target.SubassemblyName) <span class="kwrd">Then</span>
        target.TargetIds = _targetRightOffset
    <span class="kwrd">Else</span>
        target.TargetIds = _targetLeftOffset
    <span class="kwrd">End</span> <span class="kwrd">If</span>
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>The ‘SubassemblyTargetInfo.TargetIds’ property sets/gets an ‘ObjectIdCollection’ containing the object ids of the targeted objects. ‘ObjectIdCollection’ knows nothing about subassembly targets and there is no hook exposed in the class to do any work when an object is added or removed from the collection. The ‘ObjectIdCollection’ is what we call in the API team a “disconnected” collection. Because of this, you cannot write this type of code ‘target.TargetIds.Add(newId)’. This will add the object id to a temporary collection that will get discarded right after the call. </p>

<p>You can also get the collection, add/remove items from it, and then set it again in the property. I find this way a lot more difficult to use because you need to know exactly what the collection already contains to remove items that you don’t need, and then add the new items to it. Generally, it is easier to start with a new ‘ObjectIdCollection’ that contains exactly what you want and set it, and that’s exactly what I do in the example.</p>

<p>In a future post, I will talk about “connected” and “disconnected” collections and what you need to understand when working with the API. This will reveal several inconsistencies throughout the API, but it is important for you to understand those inconsistencies. For now, I hope I explained well enough how to work with subassembly targets and the best practices that you should use. If not, drop me a comment or an e-mail with any further questions you might have.</p>

<p>As always, you can download the full source code for the sample from the <a href="https://bitbucket.org/IsaacRodriguez/civilizeddevelopment">Civilized Development</a> repository at BitBucket, which also contains an updated “CorridorFromScratch.dwg” to work with the new version of the sample.</p></div>
</content>



    <feedburner:origLink>http://civilizeddevelopment.typepad.com/civilized-development/2013/05/subassembly-targets-having-fun-yet.html</feedburner:origLink></entry>
    <entry>
        <title>Create a Corridor From Scratch</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CivilizedDevelopment/~3/WOkf1GI9iqs/create-a-corridor-from-scratch.html" />
        <link rel="replies" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/2013/04/create-a-corridor-from-scratch.html" thr:count="1" thr:updated="2013-04-29T14:51:07-07:00" />
        <id>tag:typepad.com,2003:post-6a0147e1be0df6970b017eea653164970d</id>
        <published>2013-04-19T08:36:15-07:00</published>
        <updated>2013-04-19T12:31:01-07:00</updated>
        <summary>The Civil 3D API provides the necessary functionality to create a Corridor in the same way we will do through the application UI. The corridor object is on of the most complex objects provided by Civil 3D, and it is necessary to understand its structure to be able to create...</summary>
        <author>
            <name>Isaac R</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="C3D2014" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Corridors" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://civilizeddevelopment.typepad.com/civilized-development/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>The Civil 3D API provides the necessary functionality to create a Corridor in the same way we will do through the application UI. The corridor object is on of the most complex objects provided by Civil 3D, and it is necessary to understand its structure to be able to create one programmatically. In this post, we will go through the process of creating a corridor based on an existing drawing. The full source for the example is available at the <a href="https://bitbucket.org/IsaacRodriguez/civilizeddevelopment">Civilized Development</a> repository at <a href="http://bitbucket.org">BitBucket</a>. The repository contains a test drawing (CorridorFromScratch.dwg) that can be used to test the provided code.</p>  <p>As I mentioned before, the Corridor object is one of the most complex objects in Civil 3D. Creating one programmatically requires some work, and we want to maintain our code as clean as possible. I decided to use a separate class (CorridorCreator) from the command to do the work. The class provides an interface where we can set the parameters for the creation of the Corridor and a ‘CreateCorridor()’ method that creates the Corridor object. The code in our command class remains fairly simple to follow:</p>  <p><strong>C#</strong></p>  <pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> executeCreateCorridorFromScratch()
{
  <span class="kwrd">using</span> (Transaction tr = startTransaction())
  {
    CorridorCreator creator = <span class="kwrd">new</span> CorridorCreator()
    {
      CorridorName = promptForString(
        <span class="str">"\nEnter corridor name: "</span>),
      BaselineName = promptForString(
        <span class="str">"\nEnter baseline name: "</span>),
      RegionName = promptForString(
        <span class="str">"\nEnter region name: "</span>),
      AlignmentId = _desiredAlignmentId,
      AssemblyId = _desiredAssemblyId
    };
    creator.CreateCorridor(_civildoc);

    tr.Commit();
  }
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p><strong>VB.NET</strong></p>

<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> executeCreateCorridorFromScratch()
    Using tr <span class="kwrd">As</span> Transaction = startTransaction()
        <span class="kwrd">Dim</span> creator <span class="kwrd">As</span> <span class="kwrd">New</span> CorridorCreator() <span class="kwrd">With</span> { _
            .CorridorName = promptForString(
                vbLf &amp; <span class="str">"Enter corridor name: "</span>), _
            .BaselineName = promptForString(
                vbLf &amp; <span class="str">"Enter baseline name: "</span>), _
            .RegionName = promptForString(
                vbLf &amp; <span class="str">"Enter region name: "</span>), _
            .AlignmentId = _desiredAlignmentId, _
            .AssemblyId = _desiredAssemblyId _
        }
        creator.CreateCorridor(_civildoc)

        tr.Commit()
    <span class="kwrd">End</span> Using
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>CorridorCreator exposes properties to set the parameters of the Corridor object, which we set from user input. Once we have the parameters initialized, we call ‘CreateCorridor()’ to create the Corridor object based on the input. Notice that we inject the CivilDocument object in our call to ‘CreateCorridor()’. This allow us to create the corridor in any open drawing. But there is a catch; all the creation parameters must belong to the same drawing or the process will fail.</p>

<p>The implementation of the ‘CreateCorridor()’ methods shows us the necessary steps to build the Corridor object. We will then dive into the implementation of these steps.</p>

<p><strong>C#</strong></p>

<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> CreateCorridor(CivilDocument document)
{
    _document = document;
    createCorridorObject();
    createCorridorBaseline();
    createBaselineRegion();
    _corridor.Rebuild();
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p><strong>VB.NET</strong></p>

<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Sub</span> CreateCorridor(document <span class="kwrd">As</span> CivilDocument)
    _document = document
    createCorridorObject()
    createCorridorBaseline()
    createBaselineRegion()
    _corridor.Rebuild()
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>The first step is to create a new Corridor in the ‘CivilDocument’. The ‘CivilDocument’ class provides a ‘CorridorCollection’ property, encapsulated by the private property ‘_corridors’ in the example, which allows us to create a new Corridor object by name.</p>

<p><strong>C#</strong></p>

<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> createCorridorObject()
{
    ObjectId id = _corridors.Add(CorridorName);
    _corridor = id.GetObject(OpenMode.ForWrite)
        <span class="kwrd">as</span> Corridor;
}

<span class="kwrd">private</span> CorridorCollection _corridors
{
    get { <span class="kwrd">return</span> _document.CorridorCollection; }
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p><strong>VB.NET</strong></p>

<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> createCorridorObject()
    <span class="kwrd">Dim</span> id <span class="kwrd">As</span> ObjectId = _corridors.Add(CorridorName)
    _corridor = <span class="kwrd">TryCast</span>(id.GetObject(OpenMode.ForWrite), 
        Corridor)
<span class="kwrd">End</span> <span class="kwrd">Sub</span>

<span class="kwrd">Private</span> <span class="kwrd">ReadOnly</span> <span class="kwrd">Property</span> _corridors() _
        <span class="kwrd">As</span> CorridorCollection
    <span class="kwrd">Get</span>
        <span class="kwrd">Return</span> _document.CorridorCollection
    <span class="kwrd">End</span> <span class="kwrd">Get</span>
<span class="kwrd">End</span> Property</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>Once we create the new Corridor object and we open it for write, we need to add a ‘Baseline’ to it. The Corridor object contains a ‘Baselines’ property that provides an ‘Add()’ method to add a new ‘Baseline’. This method requires a baseline name, an alignment id, and a profile id. </p>

<p><strong>C#</strong></p>

<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> createCorridorBaseline()
{
    _baseline = _corridor.Baselines.Add(BaselineName, 
        AlignmentId, ProfileId);
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p><strong>VB.NET</strong></p>

<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> createCorridorBaseline()
    _baseline = _corridor.Baselines.Add(BaselineName,
        AlignmentId, ProfileId)
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>With the ‘Baseline’ created, we need to add a ‘Region’ to it. The ‘Baseline’ class provides a ‘BaselineRegions’ property that returns a ‘BaselineRegionCollection’, which exposes an ‘Add()’ method to do this. The ‘Add()’ method requires a region name and an assembly id.</p>

<p><strong>C#</strong></p>

<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> createBaselineRegion()
{
    _baseline.BaselineRegions.Add(RegionName, AssemblyId);
}</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p><strong>VB.NET</strong></p>

<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> createBaselineRegion()
    _baseline.BaselineRegions.Add(RegionName, AssemblyId)
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>

<p>Creating the regions completes the components of the Corridor. If we committed the Transaction at this point, the Corridor will be created; however, you will see in prospector that the object needs to be rebuilt. Fortunately, the API provides a ‘Rebuild()’ method in the Corridor object that allows us to do that, and we can execute it before the Transaction is committed.</p>

<p>As you can see, the new version of the API provides all the facilities to build a Corridor object from scratch. There are more complex and involved operations that we can perform when creating our Corridors programmatically, and we will look at them in future posts. For now, feel free to download the full source from the <a href="https://bitbucket.org/IsaacRodriguez/civilizeddevelopment">Civilized Development</a> repository and play with it to familiarize your-self with the new API.</p></div>
</content>



    <feedburner:origLink>http://civilizeddevelopment.typepad.com/civilized-development/2013/04/create-a-corridor-from-scratch.html</feedburner:origLink></entry>
    <entry>
        <title>Download Civilized Development Source for 2014</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CivilizedDevelopment/~3/jQnonurrU1U/download-civilized-development-source-for-2014.html" />
        <link rel="replies" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/2013/04/download-civilized-development-source-for-2014.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a0147e1be0df6970b017d42e1ed80970c</id>
        <published>2013-04-17T11:22:23-07:00</published>
        <updated>2013-04-17T11:22:23-07:00</updated>
        <summary>This is a quick post to inform you that the Civilized Development source has been ported to the Civil 3D 2014 release. No additional samples have been added; we will do that in upcoming posts, but you should be able to build and run the samples against the new version...</summary>
        <author>
            <name>Isaac R</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="C3D2014" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="General" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://civilizeddevelopment.typepad.com/civilized-development/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>This is a quick post to inform you that the Civilized Development source has been ported to the Civil 3D 2014 release. No additional samples have been added; we will do that in upcoming posts, but you should be able to build and run the samples against the new version of Civil 3D. You can download the source from the <a href="https://bitbucket.org/IsaacRodriguez/civilizeddevelopment">Civilized Development Repository</a>.</p></div>
</content>



    <feedburner:origLink>http://civilizeddevelopment.typepad.com/civilized-development/2013/04/download-civilized-development-source-for-2014.html</feedburner:origLink></entry>
    <entry>
        <title>Whats New in the Civil 3D 2014 API</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CivilizedDevelopment/~3/DuP_mD9k2xs/whats-new-in-the-civil-3d-2014-api.html" />
        <link rel="replies" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/2013/04/whats-new-in-the-civil-3d-2014-api.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a0147e1be0df6970b017eea230aee970d</id>
        <published>2013-04-10T08:52:07-07:00</published>
        <updated>2013-04-10T08:52:07-07:00</updated>
        <summary>Let me tell you, the API team has been very busy during the 2014 project cycle. There’s still more work to do, but this past year has been great, and we have been able to provide a great set of new functionality in the API that I am sure is...</summary>
        <author>
            <name>Isaac R</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="C3D2014" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Corridors" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="SectionView" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://civilizeddevelopment.typepad.com/civilized-development/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>Let me tell you, the API team has been very busy during the 2014 project cycle. There’s still more work to do, but this past year has been great, and we have been able to provide a great set of new functionality in the API that I am sure is going to please many of you.</p>  <p>Are you using COM because Corridors wasn’t fully available in .NET? Well, no more. The 2014 release provides a full-blown API to work with Corridors. We provided access to the Corridor object, as well as all its components. You can now, programmatically, manipulate Baseline, Regions, Assemblies, and Subassemblies, as well as their components. This functionality allows you to build a Corridor from scratch using the API.</p>  <p>The 2014 API also provides full support for Sample Lines, Sections, and Section Views. These features were highly requested by you, and now, they are available in our latest release. You can find a complete list of new functionality at the <a href="http://wikihelp.autodesk.com/AutoCAD_Civil_3D/enu/2014/Help/API_Developer's_Guide/0001-About_th1/0005-New_Feat5">on-line documentation site</a>.</p>  <p>But the release is not only about new features. We also want to provide a high quality API, and that means solving issues with previous versions and fixing defects. The new release is full of fixes and improvements to existing APIs, many of them, reported by you through this blog or direct communication. We’ve received many requests for functionality that have also been addressed in this release. Overall, this is the most solid release of the API, and we are very happy with its quality.</p>  <p>I want to congratulate the team for a solid release and thank them for their efforts. It was a busy year and there is more to come, but we always strive to provide a high-quality API and tools that allow our partners to build all sorts of applications.</p></div>
</content>



    <feedburner:origLink>http://civilizeddevelopment.typepad.com/civilized-development/2013/04/whats-new-in-the-civil-3d-2014-api.html</feedburner:origLink></entry>
 
</feed><!-- ph=1 -->
