// File: /workspace/github_cpp_makefile_star2_O3/rurban[P]dgnlib/dgnwrite.cpp
// Function: DGNCreateMultiPointElem
DGNElemCore *DGNCreateMultiPointElem( DGNHandle hDGN, int nType, 
                                      int nPointCount, DGNPoint *pasVertices )

{
    DGNElemMultiPoint *psMP;
    DGNElemCore *psCore;
    DGNInfo *psDGN = (DGNInfo *) hDGN;
    int i;
    DGNPoint sMin, sMax;

    CPLAssert( nType == DGNT_LINE 
               || nType == DGNT_LINE_STRING
               || nType == DGNT_SHAPE
               || nType == DGNT_CURVE
               || nType == DGNT_BSPLINE_POLE );

    DGNLoadTCB( hDGN );

/* -------------------------------------------------------------------- */
/*      Is this too many vertices to write to a single element?         */
/* -------------------------------------------------------------------- */
    if( nPointCount > 101 )
    {
        CPLError( CE_Failure, CPLE_ElementTooBig, 
                  "Attempt to create %s element with %d points failed.\n"
                  "Element would be too large.",
                  DGNTypeToName( nType ), nPointCount );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Allocate element.                                               */
/* -------------------------------------------------------------------- */
    psMP = (DGNElemMultiPoint *) 
        CPLCalloc( sizeof(DGNElemMultiPoint)
                   + sizeof(DGNPoint) * (nPointCount-2), 1 );
    psCore = &(psMP->core);

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

/* -------------------------------------------------------------------- */
/*      Set multipoint specific information in the structure.           */
/* -------------------------------------------------------------------- */
    psMP->num_vertices = nPointCount;
    memcpy( psMP->vertices + 0, pasVertices, sizeof(DGNPoint) * nPointCount );

/* -------------------------------------------------------------------- */
/*      Setup Raw data for the multipoint section.                      */
/* -------------------------------------------------------------------- */
    if( nType == DGNT_LINE )
    {
        CPLAssert( nPointCount == 2 );

        psCore->raw_bytes = 36 + psDGN->dimension* 4 * nPointCount;

        psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1);

        DGNInverseTransformPointToInt( psDGN, pasVertices + 0, 
                                       psCore->raw_data + 36 );
        DGNInverseTransformPointToInt( psDGN, pasVertices + 1, 
                                       psCore->raw_data + 36
                                       + psDGN->dimension * 4 );
    }
    else
    {
        CPLAssert( nPointCount >= 2 );

        psCore->raw_bytes = 38 + psDGN->dimension * 4 * nPointCount;
        psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1);

        psCore->raw_data[36] = (unsigned char) (nPointCount % 256);
        psCore->raw_data[37] = (unsigned char) (nPointCount/256);

        for( i = 0; i < nPointCount; i++ )
            DGNInverseTransformPointToInt( psDGN, pasVertices + i, 
                                           psCore->raw_data + 38 
                                           + psDGN->dimension * i * 4 );
    }
    
/* -------------------------------------------------------------------- */
/*      Set the core raw data, including the bounds.                    */
/* -------------------------------------------------------------------- */
    DGNUpdateElemCoreExtended( hDGN, psCore );

    sMin = sMax = pasVertices[0];
    for( i = 1; i < nPointCount; i++ )
    {
        sMin.x = MIN(pasVertices[i].x,sMin.x);
        sMin.y = MIN(pasVertices[i].y,sMin.y);
        sMin.z = MIN(pasVertices[i].z,sMin.z);
        sMax.x = MAX(pasVertices[i].x,sMax.x);
        sMax.y = MAX(pasVertices[i].y,sMax.y);
        sMax.z = MAX(pasVertices[i].z,sMax.z);
    }

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

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rcx, %r15
movl %edx, %r12d
movl %esi, %ebp
movq %rdi, %r14
callq 0xae76
cmpl $0x66, %r12d
jl 0xc074
movl %ebp, %edi
callq 0x8333
leaq 0x4b5a(%rip), %rdx      # 0x10bb0
xorl %ebx, %ebx
movl $0x3, %edi
movl $0x1, %esi
movq %rax, %rcx
movl %r12d, %r8d
xorl %eax, %eax
callq 0x460c
jmp 0xc274
leal -0x2(%r12), %eax
cltq
leaq (%rax,%rax,2), %rax
leaq 0x88(,%rax,8), %rdi
movl $0x1, %esi
callq 0x2d20
movq %rax, %rbx
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 $0x2ffffffff, %rax      # imm = 0x2FFFFFFFF
movq %rax, 0x8(%rbx)
movl %ebp, 0x14(%rbx)
movl %r12d, 0x50(%rbx)
leaq 0x58(%rbx), %rdi
movslq %r12d, %rax
shlq $0x3, %rax
leaq (%rax,%rax,2), %rdx
movq %r15, %rsi
callq 0x2230
movl 0x20018(%r14), %eax
imull %r12d, %eax
shll $0x2, %eax
cmpl $0x3, %ebp
movq %r12, 0x8(%rsp)
jne 0xc13b
addl $0x24, %eax
movl %eax, 0x40(%rbx)
movslq %eax, %rdi
movl $0x1, %esi
callq 0x2d20
movq %rax, 0x48(%rbx)
leaq 0x24(%rax), %rdx
movq %r14, %rdi
movq %r15, %rsi
callq 0xadbc
leaq 0x18(%r15), %rsi
movq 0x48(%rbx), %rax
movslq 0x20018(%r14), %rcx
leaq (%rax,%rcx,4), %rdx
addq $0x24, %rdx
movq %r14, %rdi
callq 0xadbc
jmp 0xc1ae
addl $0x26, %eax
movl %eax, 0x40(%rbx)
movslq %eax, %rdi
movl $0x1, %esi
callq 0x2d20
movq %rax, 0x48(%rbx)
movb %r12b, 0x24(%rax)
leal 0xff(%r12), %eax
testl %r12d, %r12d
cmovnsl %r12d, %eax
movq 0x48(%rbx), %rcx
movb %ah, 0x25(%rcx)
jle 0xc1ae
movl 0x8(%rsp), %ebp
shlq $0x2, %rbp
xorl %r12d, %r12d
movq %r15, %r13
movq 0x48(%rbx), %rax
movl 0x20018(%r14), %ecx
imull %r12d, %ecx
movslq %ecx, %rcx
leaq (%rax,%rcx), %rdx
addq $0x26, %rdx
movq %r14, %rdi
movq %r13, %rsi
callq 0xadbc
addq $0x4, %r12
addq $0x18, %r13
cmpq %r12, %rbp
jne 0xc17c
movq %rbx, %rsi
callq 0xbf25
movq 0x10(%r15), %rax
movq %rax, 0x20(%rsp)
movups (%r15), %xmm0
movaps %xmm0, 0x10(%rsp)
movups (%r15), %xmm0
movaps %xmm0, 0x30(%rsp)
movq 0x10(%r15), %rax
movq %rax, 0x40(%rsp)
movsd 0x30(%rsp), %xmm1
movsd 0x10(%rsp), %xmm0
movq 0x8(%rsp), %rax
cmpl $0x2, %eax
jl 0xc257
movupd 0x38(%rsp), %xmm2
movupd 0x18(%rsp), %xmm3
movl %eax, %eax
leaq (%rax,%rax,2), %rax
leaq -0x18(,%rax,8), %rax
xorl %ecx, %ecx
movapd %xmm3, %xmm4
movapd %xmm2, %xmm5
movapd %xmm0, %xmm6
movapd %xmm1, %xmm2
movsd 0x18(%r15,%rcx), %xmm0
movapd %xmm0, %xmm1
minsd %xmm2, %xmm1
movupd 0x20(%r15,%rcx), %xmm3
movapd %xmm3, %xmm2
minpd %xmm5, %xmm2
maxsd %xmm6, %xmm0
maxpd %xmm4, %xmm3
addq $0x18, %rcx
cmpq %rcx, %rax
jne 0xc20c
movupd %xmm2, 0x38(%rsp)
movupd %xmm3, 0x18(%rsp)
leaq 0x30(%rsp), %rdx
movsd %xmm1, (%rdx)
leaq 0x10(%rsp), %rcx
movsd %xmm0, (%rcx)
movq %r14, %rdi
movq %rbx, %rsi
callq 0xc286
movq %rbx, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq