// File: /workspace/github_cpp_makefile_star2_O3/rurban[P]dgnlib/dgnwrite.cpp
// Function: DGNCreateArcElem
DGNElemCore *
DGNCreateArcElem( DGNHandle hDGN, int nType, 
                  double dfOriginX, double dfOriginY, double dfOriginZ,
                  double dfPrimaryAxis, double dfSecondaryAxis, 
                  double dfStartAngle, double dfSweepAngle,
                  double dfRotation, int *panQuaternion )

{
    DGNElemArc *psArc;
    DGNElemCore *psCore;
    DGNInfo *psDGN = (DGNInfo *) hDGN;
    DGNPoint sMin, sMax, sOrigin;
    GInt32 nAngle;

    CPLAssert( nType == DGNT_ARC || nType == DGNT_ELLIPSE );

    DGNLoadTCB( hDGN );

/* -------------------------------------------------------------------- */
/*      Allocate element.                                               */
/* -------------------------------------------------------------------- */
    psArc = (DGNElemArc *) CPLCalloc( sizeof(DGNElemArc), 1 );
    psCore = &(psArc->core);

    DGNInitializeElemCore( hDGN, psCore );
    psCore->stype = DGNST_ARC;
    psCore->type = nType;

/* -------------------------------------------------------------------- */
/*      Set arc specific information in the structure.                  */
/* -------------------------------------------------------------------- */
    sOrigin.x = dfOriginX;
    sOrigin.y = dfOriginY;
    sOrigin.z = dfOriginZ;

    psArc->origin = sOrigin;
    psArc->primary_axis = dfPrimaryAxis;
    psArc->secondary_axis = dfSecondaryAxis;
    memset( psArc->quat, 0, sizeof(int) * 4 );
    psArc->startang = dfStartAngle;
    psArc->sweepang = dfSweepAngle;

    psArc->rotation = dfRotation;
    if( panQuaternion == NULL )
    {
        DGNRotationToQuaternion( dfRotation, psArc->quat );
    }
    else
    {
        memcpy( psArc->quat, panQuaternion, sizeof(long)*4 );
    }

/* -------------------------------------------------------------------- */
/*      Setup Raw data for the arc section.                             */
/* -------------------------------------------------------------------- */
    if( nType == DGNT_ARC )
    {
        double dfScaledAxis;

        if( psDGN->dimension == 3 )
            psCore->raw_bytes = 100;
        else
            psCore->raw_bytes = 80;
        psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1);

        /* start angle */
        nAngle = (int) (dfStartAngle * 360000.0);
        DGN_WRITE_INT32( nAngle, psCore->raw_data + 36 );

        /* sweep angle */
        if( dfSweepAngle < 0.0 )
        {
            nAngle = (int) (ABS(dfSweepAngle) * 360000.0);
            nAngle |= 0x80000000;
        }
        else if( dfSweepAngle > 364.9999 )
        {
            nAngle = 0;
        }
        else
        {
            nAngle = (int) (dfSweepAngle * 360000.0);
        }
        DGN_WRITE_INT32( nAngle, psCore->raw_data + 40 );

        /* axes */
        dfScaledAxis = dfPrimaryAxis / psDGN->scale;
        memcpy( psCore->raw_data + 44, &dfScaledAxis, 8 );
        IEEE2DGNDouble( psCore->raw_data + 44 );

        dfScaledAxis = dfSecondaryAxis / psDGN->scale;
        memcpy( psCore->raw_data + 52, &dfScaledAxis, 8 );
        IEEE2DGNDouble( psCore->raw_data + 52 );

        if( psDGN->dimension == 3 )
        {
            /* quaternion */
            DGN_WRITE_INT32( psArc->quat[0], psCore->raw_data + 60 );
            DGN_WRITE_INT32( psArc->quat[1], psCore->raw_data + 64 );
            DGN_WRITE_INT32( psArc->quat[2], psCore->raw_data + 68 );
            DGN_WRITE_INT32( psArc->quat[3], psCore->raw_data + 72 );
            
            /* origin */
            DGNInverseTransformPoint( psDGN, &sOrigin );
            memcpy( psCore->raw_data + 76, &(sOrigin.x), 8 );
            memcpy( psCore->raw_data + 84, &(sOrigin.y), 8 );
            memcpy( psCore->raw_data + 92, &(sOrigin.z), 8 );
            IEEE2DGNDouble( psCore->raw_data + 76 );
            IEEE2DGNDouble( psCore->raw_data + 84 );
            IEEE2DGNDouble( psCore->raw_data + 92 );
        }
        else
        {
            /* rotation */
            nAngle = (int) (dfRotation * 360000.0);
            DGN_WRITE_INT32( nAngle, psCore->raw_data + 60 );
            
            /* origin */
            DGNInverseTransformPoint( psDGN, &sOrigin );
            memcpy( psCore->raw_data + 64, &(sOrigin.x), 8 );
            memcpy( psCore->raw_data + 72, &(sOrigin.y), 8 );
            IEEE2DGNDouble( psCore->raw_data + 64 );
            IEEE2DGNDouble( psCore->raw_data + 72 );
        }
    }

/* -------------------------------------------------------------------- */
/*      Setup Raw data for the ellipse section.                         */
/* -------------------------------------------------------------------- */
    else
    {
        double dfScaledAxis;

        if( psDGN->dimension == 3 )
            psCore->raw_bytes = 92;
        else
            psCore->raw_bytes = 72;
        psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1);

        /* axes */
        dfScaledAxis = dfPrimaryAxis / psDGN->scale;
        memcpy( psCore->raw_data + 36, &dfScaledAxis, 8 );
        IEEE2DGNDouble( psCore->raw_data + 36 );

        dfScaledAxis = dfSecondaryAxis / psDGN->scale;
        memcpy( psCore->raw_data + 44, &dfScaledAxis, 8 );
        IEEE2DGNDouble( psCore->raw_data + 44 );

        if( psDGN->dimension == 3 )
        {
            /* quaternion */
            DGN_WRITE_INT32( psArc->quat[0], psCore->raw_data + 52 );
            DGN_WRITE_INT32( psArc->quat[1], psCore->raw_data + 56 );
            DGN_WRITE_INT32( psArc->quat[2], psCore->raw_data + 60 );
            DGN_WRITE_INT32( psArc->quat[3], psCore->raw_data + 64 );
            
            /* origin */
            DGNInverseTransformPoint( psDGN, &sOrigin );
            memcpy( psCore->raw_data + 68, &(sOrigin.x), 8 );
            memcpy( psCore->raw_data + 76, &(sOrigin.y), 8 );
            memcpy( psCore->raw_data + 84, &(sOrigin.z), 8 );
            IEEE2DGNDouble( psCore->raw_data + 68 );
            IEEE2DGNDouble( psCore->raw_data + 76 );
            IEEE2DGNDouble( psCore->raw_data + 84 );
        }
        else
        {
            /* rotation */
            nAngle = (int) (dfRotation * 360000.0);
            DGN_WRITE_INT32( nAngle, psCore->raw_data + 52 );
            
            /* origin */
            DGNInverseTransformPoint( psDGN, &sOrigin );
            memcpy( psCore->raw_data + 56, &(sOrigin.x), 8 );
            memcpy( psCore->raw_data + 64, &(sOrigin.y), 8 );
            IEEE2DGNDouble( psCore->raw_data + 56 );
            IEEE2DGNDouble( psCore->raw_data + 64 );
        }
        
        psArc->startang = 0.0;
        psArc->sweepang = 360.0;
    }
    
/* -------------------------------------------------------------------- */
/*      Set the core raw data, including the bounds.                    */
/* -------------------------------------------------------------------- */
    DGNUpdateElemCoreExtended( hDGN, psCore );

    sMin.x = dfOriginX - MAX(dfPrimaryAxis,dfSecondaryAxis);
    sMin.y = dfOriginY - MAX(dfPrimaryAxis,dfSecondaryAxis);
    sMin.z = dfOriginZ - MAX(dfPrimaryAxis,dfSecondaryAxis);
    sMax.x = dfOriginX + MAX(dfPrimaryAxis,dfSecondaryAxis);
    sMax.y = dfOriginY + MAX(dfPrimaryAxis,dfSecondaryAxis);
    sMax.z = dfOriginZ + MAX(dfPrimaryAxis,dfSecondaryAxis);

    DGNWriteBounds( psDGN, psCore, &sMin, &sMax );
    
    return psCore;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0xa8, %rsp
movq %rdx, %r15
movsd %xmm7, 0x8(%rsp)
movsd %xmm6, 0x18(%rsp)
movsd %xmm5, 0x10(%rsp)
movsd %xmm4, (%rsp)
movaps %xmm3, 0x40(%rsp)
movsd %xmm2, 0x20(%rsp)
movaps %xmm1, 0x50(%rsp)
movaps %xmm0, 0x60(%rsp)
movl %esi, %ebp
movq %rdi, %rbx
callq 0xae76
movl $0xa0, %edi
movl $0x1, %esi
callq 0x2d20
movq %rax, %r14
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movups %xmm0, 0x10(%rax)
movups %xmm0, 0x20(%rax)
movups %xmm0, 0x30(%rax)
movups %xmm0, 0x40(%rax)
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
movabsq $0x5ffffffff, %rax      # imm = 0x5FFFFFFFF
movq %rax, 0x8(%r14)
movl %ebp, 0x14(%r14)
movaps 0x60(%rsp), %xmm1
movsd %xmm1, 0x28(%rsp)
movaps 0x50(%rsp), %xmm1
movsd %xmm1, 0x30(%rsp)
movsd 0x20(%rsp), %xmm1
movsd %xmm1, 0x38(%rsp)
movups 0x28(%rsp), %xmm1
movups %xmm1, 0x50(%r14)
movq 0x38(%rsp), %rax
movq %rax, 0x60(%r14)
movaps 0x40(%rsp), %xmm1
movsd %xmm1, 0x68(%r14)
movsd (%rsp), %xmm1
movsd %xmm1, 0x70(%r14)
leaq 0x80(%r14), %rdi
movups %xmm0, 0x80(%r14)
movsd 0x8(%rsp), %xmm0
movsd 0x10(%rsp), %xmm1
movsd %xmm1, 0x90(%r14)
movsd 0x18(%rsp), %xmm1
movsd %xmm1, 0x98(%r14)
movsd %xmm0, 0x78(%r14)
testq %r15, %r15
je 0xc426
movups (%r15), %xmm0
movupd 0x10(%r15), %xmm1
movupd %xmm1, 0x10(%rdi)
movups %xmm0, (%rdi)
jmp 0xc42b
callq 0x84e8
movl 0x20018(%rbx), %eax
cmpl $0x10, %ebp
jne 0xc4be
cmpl $0x3, %eax
movl $0x64, %eax
movl $0x50, %edi
cmovel %eax, %edi
movl %edi, 0x40(%r14)
movl $0x1, %esi
callq 0x2d20
movq %rax, 0x48(%r14)
movsd 0x10(%rsp), %xmm0
mulsd 0x4246(%rip), %xmm0     # 0x106b0
cvttsd2si %xmm0, %ecx
movl %ecx, %edx
shrl $0x10, %edx
movb %dl, 0x24(%rax)
movl %ecx, %eax
shrl $0x18, %eax
movq 0x48(%r14), %rdx
movb %al, 0x25(%rdx)
movq 0x48(%r14), %rax
movb %cl, 0x26(%rax)
movq 0x48(%r14), %rax
movb %ch, 0x27(%rax)
xorpd %xmm0, %xmm0
movsd 0x18(%rsp), %xmm1
ucomisd %xmm1, %xmm0
movapd %xmm1, %xmm0
jbe 0xc634
mulsd 0x4508(%rip), %xmm0     # 0x109b8
cvttsd2si %xmm0, %eax
orl $0x80000000, %eax       # imm = 0x80000000
jmp 0xc64c
cmpl $0x3, %eax
movl $0x5c, %eax
movl $0x48, %edi
cmovel %eax, %edi
movl %edi, 0x40(%r14)
movl $0x1, %esi
callq 0x2d20
movq %rax, 0x48(%r14)
movapd 0x40(%rsp), %xmm0
divsd 0x20020(%rbx), %xmm0
movsd %xmm0, 0x24(%rax)
movq 0x48(%r14), %rdi
addq $0x24, %rdi
callq 0x7022
movsd (%rsp), %xmm0
divsd 0x20020(%rbx), %xmm0
movq 0x48(%r14), %rax
movsd %xmm0, 0x2c(%rax)
movq 0x48(%r14), %rdi
addq $0x2c, %rdi
callq 0x7022
cmpl $0x3, 0x20018(%rbx)
jne 0xc7d4
movl 0x80(%r14), %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x34(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x35(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x36(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x37(%rcx)
movl 0x84(%r14), %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x38(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x39(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x3a(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x3b(%rcx)
movl 0x88(%r14), %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x3c(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x3d(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x3e(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x3f(%rcx)
movl 0x8c(%r14), %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x40(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x41(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x42(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x43(%rcx)
leaq 0x28(%rsp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0xace4
movq 0x48(%r14), %rax
movq (%r15), %rcx
movq %rcx, 0x44(%rax)
movq 0x48(%r14), %rax
movq 0x8(%r15), %rcx
movq %rcx, 0x4c(%rax)
movq 0x48(%r14), %rax
movq 0x10(%r15), %rcx
movq %rcx, 0x54(%rax)
movq 0x48(%r14), %rdi
addq $0x44, %rdi
callq 0x7022
movl $0x54, %r15d
movl $0x4c, %edi
jmp 0xc83e
xorl %eax, %eax
ucomisd 0x4372(%rip), %xmm0     # 0x109b0
ja 0xc64c
mulsd 0x4068(%rip), %xmm0     # 0x106b0
cvttsd2si %xmm0, %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x28(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x29(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x2a(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x2b(%rcx)
movapd 0x40(%rsp), %xmm0
divsd 0x20020(%rbx), %xmm0
movq 0x48(%r14), %rax
movsd %xmm0, 0x2c(%rax)
movq 0x48(%r14), %rdi
addq $0x2c, %rdi
callq 0x7022
movsd (%rsp), %xmm0
divsd 0x20020(%rbx), %xmm0
movq 0x48(%r14), %rax
movsd %xmm0, 0x34(%rax)
movq 0x48(%r14), %rdi
addq $0x34, %rdi
callq 0x7022
cmpl $0x3, 0x20018(%rbx)
jne 0xc86a
movl 0x80(%r14), %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x3c(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x3d(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x3e(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x3f(%rcx)
movl 0x84(%r14), %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x40(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x41(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x42(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x43(%rcx)
movl 0x88(%r14), %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x44(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x45(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x46(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x47(%rcx)
movl 0x8c(%r14), %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x48(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x49(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x4a(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x4b(%rcx)
leaq 0x28(%rsp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0xace4
movq 0x48(%r14), %rax
movq (%r15), %rcx
movq %rcx, 0x4c(%rax)
movq 0x48(%r14), %rax
movq 0x8(%r15), %rcx
movq %rcx, 0x54(%rax)
movq 0x48(%r14), %rax
movq 0x10(%r15), %rcx
movq %rcx, 0x5c(%rax)
movq 0x48(%r14), %rdi
addq $0x4c, %rdi
callq 0x7022
movq 0x48(%r14), %rdi
addq $0x54, %rdi
callq 0x7022
movq 0x48(%r14), %rdi
addq $0x5c, %rdi
jmp 0xc8de
movsd 0x8(%rsp), %xmm0
mulsd 0x3ece(%rip), %xmm0     # 0x106b0
cvttsd2si %xmm0, %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x34(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x35(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x36(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x37(%rcx)
leaq 0x28(%rsp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0xace4
movq 0x48(%r14), %rax
movq (%r15), %rcx
movq %rcx, 0x38(%rax)
movq 0x48(%r14), %rax
movq 0x8(%r15), %rcx
movq %rcx, 0x40(%rax)
movl $0x40, %r15d
movl $0x38, %edi
addq 0x48(%r14), %rdi
callq 0x7022
addq 0x48(%r14), %r15
movq %r15, %rdi
callq 0x7022
xorpd %xmm0, %xmm0
movhpd 0x3e59(%rip), %xmm0     # xmm0 = xmm0[0],mem[0]
movupd %xmm0, 0x90(%r14)
jmp 0xc8e3
movsd 0x8(%rsp), %xmm0
mulsd 0x3e38(%rip), %xmm0     # 0x106b0
cvttsd2si %xmm0, %eax
movl %eax, %ecx
shrl $0x10, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x3c(%rdx)
movl %eax, %ecx
shrl $0x18, %ecx
movq 0x48(%r14), %rdx
movb %cl, 0x3d(%rdx)
movq 0x48(%r14), %rcx
movb %al, 0x3e(%rcx)
movq 0x48(%r14), %rcx
movb %ah, 0x3f(%rcx)
leaq 0x28(%rsp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0xace4
movq 0x48(%r14), %rax
movq (%r15), %rcx
movq %rcx, 0x40(%rax)
movq 0x48(%r14), %rax
movq 0x8(%r15), %rcx
movq %rcx, 0x48(%rax)
movq 0x48(%r14), %rdi
addq $0x40, %rdi
callq 0x7022
movq 0x48(%r14), %rdi
addq $0x48, %rdi
callq 0x7022
movq %r14, %rsi
callq 0xbf25
movapd 0x40(%rsp), %xmm2
maxsd (%rsp), %xmm2
movapd 0x60(%rsp), %xmm4
unpcklpd 0x50(%rsp), %xmm4       # xmm4 = xmm4[0],mem[0]
movapd %xmm2, %xmm0
unpcklpd %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0]
movapd %xmm4, %xmm1
subpd %xmm0, %xmm1
leaq 0x90(%rsp), %rdx
movapd %xmm1, (%rdx)
movsd 0x20(%rsp), %xmm3
movapd %xmm3, %xmm1
subsd %xmm2, %xmm1
movsd %xmm1, 0x10(%rdx)
addpd %xmm4, %xmm0
leaq 0x70(%rsp), %rcx
movapd %xmm0, (%rcx)
addsd %xmm3, %xmm2
movsd %xmm2, 0x10(%rcx)
movq %rbx, %rdi
movq %r14, %rsi
callq 0xc286
movq %r14, %rax
addq $0xa8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq